Java 8 Lambda 表达式比较器使用

引言

在这个例子中,我们将向您展示如何使用 java8 lambda 表达式编写一个 Comparator 来对 List 进行排序。

  1. 经典的比较器示例:
    Comparator<Developer> byName = new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o1.getName().compareTo(o2.getName());
        }
    };
  1. 使用 lambda:
    Comparator<Developer> byName = 
        (Developer o1, Developer o2)->o1.getName().compareTo(o2.getName());

1.没有 Lambda 的排序

先新建一个 Developer 类,然后比较 Developer 对象的年龄,通常我们使用 Collections.sort 并传递匿名 Comparator 类,如下所示:

package com.jimzhang.lambda;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 〈一句话功能简述〉<br> 〈排序〉
 *
 * @author zhangjinmiao
 * @create 2019/8/4 10:19
 */
public class TestSorting {

  public static void main(String[] args) {
    List<Developer> listDevs = getDevelopers();

    System.out.println("Before Sort");
    for (Developer developer : listDevs) {
      System.out.println(developer.toString());
    }

    //sort by age
    Collections.sort(listDevs, new Comparator<Developer>() {
      @Override
      public int compare(Developer o1, Developer o2) {
        return o1.getAge() - o2.getAge();
      }
    });

    System.out.println("After Sort");
    for (Developer developer : listDevs) {
      System.out.println(developer);
    }

  }

  public static List<Developer> getDevelopers() {
    List<Developer> developers = new ArrayList<>();
    developers.add(new Developer("lisi", new BigDecimal("8000"),23));
    developers.add(new Developer("wangwu", new BigDecimal("9000"),24));
    developers.add(new Developer("maliu", new BigDecimal("10000"),25));
    developers.add(new Developer("zhangsan", new BigDecimal("7000"),22));
    return developers;
  }
}

当排序要求改变时,您只需传入另一个新的匿名 Comparator 类:

  //sort by age
    Collections.sort(listDevs, new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o1.getAge() - o2.getAge();
        }
    });
    
    //sort by name  
    Collections.sort(listDevs, new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o1.getName().compareTo(o2.getName());
        }
    });
                
    //sort by salary
    Collections.sort(listDevs, new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o1.getSalary().compareTo(o2.getSalary());
        }
    });     

这是可行的,但是,您是否觉得仅仅因为想要更改一行代码就创建一个类有点奇怪?

2.使用 Lambda 排序

在 Java 8 中,List 接口直接支持排序方法,不再需要使用 Collections.sort。

  //List.sort() since Java 8
    listDevs.sort(new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o2.getAge() - o1.getAge();
        }
    }); 

3.更多例子

1. 按年龄排序

  //sort by age
    Collections.sort(listDevs, new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o1.getAge() - o2.getAge();
        }
    });
    
    //lambda
    listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());
    
    //lambda, valid, parameter type is optional
    listDevs.sort((o1, o2)->o1.getAge()-o2.getAge());

2. 按名字排序

    //sort by name
    Collections.sort(listDevs, new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o1.getName().compareTo(o2.getName());
        }
    });
        
    //lambda
    listDevs.sort((Developer o1, Developer o2)->o1.getName().compareTo(o2.getName()));      
    
    //lambda
    listDevs.sort((o1, o2)->o1.getName().compareTo(o2.getName()));      

3. 按薪水排序

    //sort by salary
    Collections.sort(listDevs, new Comparator<Developer>() {
        @Override
        public int compare(Developer o1, Developer o2) {
            return o1.getSalary().compareTo(o2.getSalary());
        }
    });             

    //lambda
    listDevs.sort((Developer o1, Developer o2)->o1.getSalary().compareTo(o2.getSalary()));
    
    //lambda
    listDevs.sort((o1, o2)->o1.getSalary().compareTo(o2.getSalary()));

4. 反向排序

  1. 薪水正序排序
Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
    listDevs.sort(salaryComparator);

输出:

Developer{name='zhangsan', salary=7000, age=22}
Developer{name='lisi', salary=8000, age=23}
Developer{name='wangwu', salary=9000, age=24}
Developer{name='maliu', salary=10000, age=25}

2.反向排序

Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
    listDevs.sort(salaryComparator.reversed());

输出:

Developer{name='maliu', salary=10000, age=25}
Developer{name='wangwu', salary=9000, age=24}
Developer{name='lisi', salary=8000, age=23}
Developer{name='zhangsan', salary=7000, age=22}

源码见:java-8-demo

系列文章详见:Java 8 教程

欢迎关注
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 行为参数化 为了应对多变的需求,难道我们就要因为客户每提出一个需求,我们就要写一个方法去实现吗? 显然这样做很冗余...
    uzip柚子皮阅读 889评论 0 1
  • 前段时间一直在看lambda表达式,但是总感觉吃不透,在深入了解lambda表达式的时候,需要很多基础的知识栈。这...
    西瓜真好吃丶阅读 2,750评论 0 7
  • Lambda表达式 利用行为参数化这个概念,就可以编写更为灵活且可重复使用的代码。但同时,使用匿名类来表示不同的行...
    谢随安阅读 933评论 2 0
  • 本文内容大部分来自《Java 8实战》一书 前言 在上一篇文章中,我们了解了利用行为参数化来传递代码有助于应对不断...
    我没有三颗心脏阅读 5,135评论 0 3
  • 你是不是有这样的苦恼? 家里无论怎么收拾都收拾不完,今天整理干净了,明天又乱了,一旦哪天不想收拾,第二天就会加倍凌...
    迷夏的小岛阅读 386评论 1 7