Comparator.comparing比较排序
使用外部比较器Comparator进行排序
当我们需要对集合的元素进行排序的时候,可以使用java.util.Comparator 创建一个比较器来进行排序。Comparator接口同样也是一个函数式接口,我们可以把使用lambda表达式。如下示例,
package com.common;
import java.util.*;
import java.util.stream.Collectors;
public class ComparatorTest {
    public static void main(String[] args) {
        Employee e1 = new Employee("John", 25, 3000, 9922001);
        Employee e2 = new Employee("Ace", 22, 2000, 5924001);
        Employee e3 = new Employee("Keith", 35, 4000, 3924401);
        List<Employee> employees = new ArrayList<>();
        employees.add(e1);
        employees.add(e2);
        employees.add(e3);
        /**
         *     @SuppressWarnings({"unchecked", "rawtypes"})
         *     default void sort(Comparator<? super E> c) {
         *         Object[] a = this.toArray();
         *         Arrays.sort(a, (Comparator) c);
         *         ListIterator<E> i = this.listIterator();
         *         for (Object e : a) {
         *             i.next();
         *             i.set((E) e);
         *         }
         *     }
         *
         *     sort 对象接收一个 Comparator 函数式接口,可以传入一个lambda表达式
         */
        employees.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
        Collections.sort(employees, (o1, o2) -> o1.getName().compareTo(o2.getName()));
        employees.forEach(System.out::println);
    }
}
/**
 * [Employee(name=John, age=25, salary=3000.0, mobile=9922001),
 * Employee(name=Ace, age=22, salary=2000.0, mobile=5924001),
 * Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
 */
class Employee {
    String name;
    int age;
    double salary;
    long mobile;
    // constructors, getters & setters
    public Employee(String name, int age, double salary, long mobile) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.mobile = mobile;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public long getMobile() {
        return mobile;
    }
    public void setMobile(long mobile) {
        this.mobile = mobile;
    }
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Employee{");
        sb.append("name='").append(name).append('\'');
        sb.append(", age=").append(age);
        sb.append(", salary=").append(salary);
        sb.append(", mobile=").append(mobile);
        sb.append('}');
        return sb.toString();
    }
}使用 Comparator.comparing 进行排序
comparing 方法一
查看 Comparator 类内部实现,还有一个 comparing 方法,实现如下,
    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }
其返回值是 (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); 一个lambda表达式,也就是一个Compator 。所以上面那个例子也可以改造成 如下,
package com.common;
import java.util.*;
public class ComparatorTest {
    public static void main(String[] args) {
        Employee e1 = new Employee("John", 25, 3000, 9922001);
        Employee e2 = new Employee("Ace", 22, 2000, 5924001);
        Employee e3 = new Employee("Keith", 35, 4000, 3924401);
        List<Employee> employees = new ArrayList<>();
        employees.add(e1);
        employees.add(e2);
        employees.add(e3);
        /**
         *     @SuppressWarnings({"unchecked", "rawtypes"})
         *     default void sort(Comparator<? super E> c) {
         *         Object[] a = this.toArray();
         *         Arrays.sort(a, (Comparator) c);
         *         ListIterator<E> i = this.listIterator();
         *         for (Object e : a) {
         *             i.next();
         *             i.set((E) e);
         *         }
         *     }
         *
         *     sort 对象接收一个 Comparator 函数式接口,可以传入一个lambda表达式
         */
        employees.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
        Collections.sort(employees, (o1, o2) -> o1.getName().compareTo(o2.getName()));
        employees.forEach(System.out::println);
        /**
         * Comparator.comparing 方法的使用
         *
         * comparing 方法接收一个 Function 函数式接口 ,通过一个 lambda 表达式传入
         *
         */
        employees.sort(Comparator.comparing(e -> e.getName()));
        /**
         * 该方法引用 Employee::getName 可以代替 lambda表达式
         */
        employees.sort(Comparator.comparing(Employee::getName));
    }
}
/**
 * [Employee(name=John, age=25, salary=3000.0, mobile=9922001),
 * Employee(name=Ace, age=22, salary=2000.0, mobile=5924001),
 * Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
 */
class Employee {
    String name;
    int age;
    double salary;
    long mobile;
    // constructors, getters & setters
    public Employee(String name, int age, double salary, long mobile) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.mobile = mobile;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public long getMobile() {
        return mobile;
    }
    public void setMobile(long mobile) {
        this.mobile = mobile;
    }
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Employee{");
        sb.append("name='").append(name).append('\'');
        sb.append(", age=").append(age);
        sb.append(", salary=").append(salary);
        sb.append(", mobile=").append(mobile);
        sb.append('}');
        return sb.toString();
    }
}comparing 方法二
    public static <T, U> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    {
        Objects.requireNonNull(keyExtractor);
        Objects.requireNonNull(keyComparator);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                              keyExtractor.apply(c2));
    }和comparing 方法一不同的是 该方法多了一个参数 keyComparator ,keyComparator 是创建一个自定义的比较器。
Collections.sort(employees, Comparator.comparing(
                Employee::getName, (s1, s2) -> {
                    return s2.compareTo(s1);
                }));
使用 Comparator.reversed 进行排序
返回相反的排序规则,
/**
 *  相反的排序规则
 */
Collections.sort(employees, Comparator.comparing(Employee::getName).reversed());
employees.forEach(System.out::println);
输出,
Employee{name='Keith', age=35, salary=4000.0, mobile=3924401}
Employee{name='John', age=25, salary=3000.0, mobile=9922001}
Employee{name='Ace', age=22, salary=2000.0, mobile=5924001}使用 Comparator.nullsFirst进行排序
当集合中存在null元素时,可以使用针对null友好的比较器,null元素排在集合的最前面
employees.add(null);  //插入一个null元素
Collections.sort(employees, Comparator.nullsFirst(Comparator.comparing(Employee::getName)));
employees.forEach(System.out::println);
Collections.sort(employees, Comparator.nullsLast(Comparator.comparing(Employee::getName)));
employees.forEach(System.out::println);
使用 Comparator.thenComparing排序
首先使用 name 排序,紧接着在使用ege 排序,来看下使用效果
Collections.sort(employees, Comparator.comparing(Employee::getAge).thenComparing(Employee::getName));
employees.forEach(System.out::println);
转载:https://my.oschina.net/xinxingegeya/blog/2046405
Comparator.comparing比较排序的更多相关文章
- Comparator.comparing排序使用示例
		Comparator.comparing排序使用示例 目录 Comparator.comparing排序使用示例 背景 实体类 示例一 示例二 背景 以前常用的排序方式是通过实现Comparator接 ... 
- [转] Java中Comparator进行对象排序
		[From] https://blog.51cto.com/thinklili/2063244 Java在8后引入了lambda表达式和流,使得排序方法有了变化 class User { int id ... 
- Java基础 TreeSet()来实现数组的【定制排序】 : Comparable接口(自然排序) 或者 Comparator接口 (定制排序)
		笔记: //排序真麻烦!没有C++里的好用又方便!ORZ!ORZ!数组排序还还自己写个TreeSet()和( Comparable接口(自然排序) 或者 Comparator接口 (定制排序))imp ... 
- java运用Comparator为对象排序
		要排序的类需要实现Comparator接口,重写compare方法: user类及实现接口的内部类: package test; import java.util.Comparator; public ... 
- Comparator接口实现排序
		对任意类型集合对象进行整体排序,排序时将此接口的实现传递给Collections.sort方法或者Arrays.sort方法排序.实现int compare(T o1, T o2);方法,返回正数,零 ... 
- TreeSet和Comparator 对TreeSet排序
		使用TreeSet和Comparator,编写TreeSetTestInner类,要求对TreeSet中的元素"HashSet"."ArrayList".&qu ... 
- TreeSet实现Comparator接口的排序算法的分析
		为了方便,用lambda表达式代替comparator接口 例子如下: public static void main(String[] args) { TreeSet<Integer> ... 
- Java中List排序的3种方法
		在某些特殊的场景下,我们需要在 Java 程序中对 List 集合进行排序操作.比如从第三方接口中获取所有用户的列表,但列表默认是以用户编号从小到大进行排序的,而我们的系统需要按照用户的年龄从大到小进 ... 
- Java8:使用Lambda表达式增强版Comparator排序
		学习路上的自我记录-------路好长,就问你慌不慌,大声港,不慌.----jstarseven. 实体类: package com.server.model; /** * Created by js ... 
随机推荐
- AndroidStudio修改主题外观和字体大小
			修改主题外观 File --> Settings --> Appearance & Behavior --> Appearance 右边 Theme 修改编辑器的字体大小 F ... 
- Code:NLog
			ylbtech-Code:NLog 1. NLog介绍使用返回顶部 1. NLog是什么 NLog是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码.NLog ... 
- Sharepoint中WebPart開發時註意的問題
			1. 怎麼樣在WebPart中使用Sharepoint控件? 要在webpart中使用sharepoint控件必須先引用Microsoft.SharePoint.WebControls命名空間,如你現 ... 
- ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 01. 创建项目 +项目结构和配置简介
			新建项目:Tutotial.Web 解决方案名称可以把web去掉 视频里面把git这个选项勾选了.我就不勾选了 dotnet CLI创建项目 首先必须安装好了.net Core的SDK dotnet ... 
- 一文教您如何通过 Docker 快速搭建各种测试环境(Mysql, Redis, Elasticsearch, MongoDB) | 建议收藏
			欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ... 
- Beta版本发布!
			该作业所属课程:https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2 作业地址:https://edu.cnblogs.com/c ... 
- 1391:局域网(net)
			[题目描述] 某个局域网内有n(n≤100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象.因为连接计 ... 
- 继续(3n+1)猜想 (25)
			#include <algorithm> #include <iostream> using namespace std; int main(){ ] = { }; ], nu ... 
- Hdu 5459 Jesus Is Here (2015 ACM/ICPC Asia Regional Shenyang Online) 递推
			题目链接: Hdu 5459 Jesus Is Here 题目描述: s1 = 'c', s2 = 'ff', s3 = s1 + s2; 问sn里面所有的字符c的距离是多少? 解题思路: 直觉告诉我 ... 
- 字符串处理 Codeforces Round #305 (Div. 2) A. Mike and Fax
			题目传送门 /* 字符串处理:回文串是串联的,一个一个判断 */ #include <cstdio> #include <cstring> #include <iostr ... 
