青年IT男

个人从事金融行业,就职过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就职于某银行负责统一支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、响应式编程、人工智能等领域。同时也热衷于技术分享创立公众号和博客站点对知识体系进行分享。微信公众号:青年IT男。

Java Comparator

Java Comparator

Java java.util.Comparator功能接口对对象集合强制进行排序。要对集合进行排序,我们将Comparator实例传递给Stream.sorted,Collections.sort,List.sort和Arrays.sort方法。比较器还可以控制SortedSet的顺序和SortedMap数据结构的键的顺序。

比较器的功能方法是compare(T o1,T o2),它返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。比较器强加的顺序应与equals方法一致。只有当c.compare(e1,e2)== 0与我们集合中每个e1和e2的e1.equals(e2)具有相同的布尔值时,它才是一致的,其中c是Comparator的实例。

比较器功能方法: compare(T o1,T o2)

compare是比较器功能接口的功能方法。

int compare(T o1, T o2)

compare比较它的两个参数的顺序。当第一个参数小于,等于或大于第二个参数时,它返回负数,零或正数。

使用Lambda Expression定义比较

我们使用lambda表达式定义比较函数方法如下。

Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge();
Comparator<Student> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());

example

package com.concretepage;

import java.util.Comparator;
import java.util.List;

public class CompareDemo {
    public static void main(String[] args) {
        List<Student> list = Student.getStudentList();
        System.out.println("--- Sort Students by age ---");
        Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge();
        list.sort(ageComp);
        list.forEach(s -> System.out.println(s));
        System.out.println("--- Sort Students by name ---");
        Comparator<Student> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());
        list.sort(nameComp);
        list.forEach(s -> System.out.println(s));
    }
}

compare 功能方法需要返回-ve,零或+ ve值。s1.getAge() – s2.getAge()将返回-ve或零或+ ve值。和String.compareTo按字典顺序比较两个字符串。它返回-ve,零或+ ve值。

package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class Student implements Comparable<Student> {
  private String name;
  private int age;
  public Student(String name, int age) {
  this.name = name;
  this.age = age;
  }
  public String getName() {
  return name;
  }
  public int getAge() {
  return age;
  }
  @Override
  public int compareTo(Student s) {
  return name.compareTo(s.getName());
  }
  @Override  
  public String toString(){
  return name + "-" + age; 
  }
  public static List<Student> getStudentList(){
    Student s1 = new Student("Ram", 18);
    Student s2 = new Student("Shyam",22);
    Student s3 = new Student("Mohan",19);
    List<Student> list = Arrays.asList(s1,s2,s3);
    return list;
  }  
}

输出:

--- Sort Students by age ---
Ram-18
Mohan-19
Shyam-22
--- Sort Students by name ---
Mohan-19
Ram-18
Shyam-22 

定义比较实现Comparator

package com.concretepage;
import java.io.Serializable;
import java.util.Comparator;
import java.util.List;

class AgeComparator implements Comparator<Student>, Serializable {
  private static final long serialVersionUID = 1L;
  @Override
  public int compare(Student s1, Student s2) {
     return s1.getAge() - s2.getAge();
  }
}
class NameComparator implements Comparator<Student>, Serializable {
  private static final long serialVersionUID = 1L;
  @Override
  public int compare(Student s1, Student s2) {
     return s1.getName().compareTo(s2.getName());
  }
}
public class CompareDemoImplement {
  public static void main(String[] args) {
  List<Student> list = Student.getStudentList();

  System.out.println("--- Sort Students by age ---");

  AgeComparator ageComparator = new AgeComparator();
  list.sort(ageComparator);
  list.forEach(s -> System.out.println(s));

  System.out.println("--- Sort Students by name ---");

  NameComparator nameComparator = new NameComparator();
  list.sort(nameComparator);
  list.forEach(s -> System.out.println(s));
  }
}

输出:

--- Sort Students by age ---
Ram-18
Mohan-19
Shyam-22
--- Sort Students by name ---
Mohan-19
Ram-18
Shyam-22 

最好在实现Comparator接口时实现Serializable,因为它们可以用作可序列化数据结构(如TreeSet和TreeMap)中的排序方法。

使用Comparator

可以将Comparator与Stream.sorted,Collections.sort,List.sort和Arrays.sort方法一起使用。

Comparator与Stream.sorted的比较器

Stream.sorted返回一个由该流的元素组成的流,根据提供的比较器进行排序。

package com.concretepage;

import java.util.Comparator;
import java.util.List;

public class CompareDemoStreamSorted {
    public static void main(String[] args) {
        List<Student> list = Student.getStudentList();
        System.out.println("--- Sort Students by age ---");
        Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge();
        list.stream().sorted(ageComp).forEach(s -> System.out.println(s));
        System.out.println("--- Sort Students by name ---");
        Comparator<Student> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());
        list.stream().sorted(nameComp).forEach(s -> System.out.println(s));
    }
}

从本页上面的比较示例中使用Student class。

Comparator with Collections.sort

Collections.sort根据给定的Comparator实例对指定的列表进行排序。

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class CompareDemoCollectionsSort {
  public static void main(String[] args) {
  List<Student> list = Student.getStudentList();

  System.out.println("--- Sort Students by age ---");

  Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge();
  Collections.sort(list, ageComp);
  list.forEach(s -> System.out.println(s));

  System.out.println("--- Sort Students by name ---");

  Comparator<Student> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());  
  Collections.sort(list, nameComp);
  list.forEach(s -> System.out.println(s));  
  }
}

Comparator with List.sort

List.sort根据给定的Comparator实例对此列表进行排序。

package com.concretepage;

import java.util.Comparator;
import java.util.List;

public class CompareDemoListSort {
    public static void main(String[] args) {
        List<Student> list = Student.getStudentList();
        System.out.println("--- Sort Students by age ---");
        Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge();
        list.sort(ageComp);
        list.forEach(s -> System.out.println(s));
        System.out.println("--- Sort Students by name ---");
        Comparator<Student> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());
        list.sort(nameComp);
        list.forEach(s -> System.out.println(s));
    }
}

Comparator with Arrays.sort

Arrays.sort根据指定比较器引发的顺序对指定的对象数组进行排序。

package com.concretepage;

import java.util.Arrays;
import java.util.Comparator;

public class CompareDemoArraysSort {
    public static void main(String[] args) {
        Student st1 = new Student("Ram", 18);
        Student st2 = new Student("Shyam", 22);
        Student st3 = new Student("Mohan", 19);
        Student[] array = {st1, st2, st3};
        System.out.println("--- Sort Students by age ---");
        Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge();
        Arrays.sort(array, ageComp);
        for (Student s : array) {
            System.out.println(s);
        }
        System.out.println("--- Sort Students by name ---");
        Comparator<Student> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());
        Arrays.sort(array, nameComp);
        for (Student s : array) {
            System.out.println(s);
        }
    }
}

Comparator Methods

在Java 8中,Comparator接口引入了一些静态和默认方法。在这里,我们将通过示例讨论这些方法。我们可以将Comparator与Stream.sorted,List.sort,Collections.sort和Arrays.sort一起使用来对集合和映射进行排序。

reversed是Java Comparator功能接口的默认方法。reverse返回一个Comparator,强制执行此Comparator的反向排序。它已被宣布如下。

default Comparator<T> reversed()

要使用反向方法,需要实例化我们的Comparator并调用此方法。reverse将返回Comparator的新实例,该实例将强制执行此比较器的反向排序。

Comparator<Student> nameComparator = (s1, s2) -> s1.getName().compareTo(s2.getName());
Collections.sort(list, nameComparator.reversed());
package com.concretepage;
import java.util.Comparator;
import java.util.List;
import com.concretepage.Student;
public class ComparatorReversedDemo {
  public static void main(String[] args) {
  List<Student> list = Student.getStudentList();
  Comparator<Student> ageComparator = (s1, s2) -> s1.getAge() - s2.getAge();  
  list.stream().sorted(ageComparator.reversed()).forEach(s -> System.out.print(s.getAge() + " "));
  System.out.println("-----------");
  Comparator<Student> nameComparator = (s1, s2) -> s1.getName().compareTo(s2.getName());  
  list.stream().sorted(nameComparator.reversed()).forEach(s -> System.out.print(s.getName() + " "));
  System.out.println("-----------");  
  list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).forEach(s -> System.out.print(s.getAge() + " "));
  System.out.println("-----------");
  list.stream().sorted(Comparator.comparing(Student::getName).reversed()).forEach(s -> System.out.print(s.getName() + " "));  
  }
}

输出:

22 19 18 
-----------
Shyam Ram Mohan 
-----------
22 19 18 
-----------
Shyam Ram Mohan

reverseOrder是一个静态方法,它返回Comparator以对象集合的反向自然顺序强加排序。对于自然排序,类需要实现Comparable并定义compareTo方法。根据compareTo以自然顺序对对象集合进行排序。Comparator.reverseOrder反转自然顺序。它在内部调用Collections.reverseOrder()并返回Comparator实例。

public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
     return Collections.reverseOrder();
}
package com.concretepage;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparatorReverseOrderDemo {
  public static void main(String[] args) {
  List<Integer> numList = Arrays.asList(12, 10, 15, 8, 11);
  Collections.sort(numList, Comparator.reverseOrder());
  numList.forEach(n -> System.out.print(n + " "));
  System.out.println("-----------");

  List<String> strList = Arrays.asList("Varanasi", "Allahabad", "Kanpur", "Noida");
  Collections.sort(strList, Comparator.reverseOrder());
  strList.forEach(s -> System.out.print(s + " "));
  System.out.println("-----------");  

  List<Student> stdList = Student.getStudentList();
  Collections.sort(stdList, Comparator.reverseOrder());
  stdList.forEach(s -> System.out.print(s.getName() + " "));  
  }
}

输出:

15 12 11 10 8 
-----------
Varanasi Noida Kanpur Allahabad 
-----------
Shyam Ram Mohan

naturalOrder是Comparator功能接口的静态方法。Comparator.naturalOrder方法返回一个比较器,该比较器按自然顺序比较Comparable对象。对于自然排序,类需要实现Comparable并定义compareTo方法。根据自然顺序中的compareTo方法对对象集合进行排序。诸如Integer,String和Date之类的Java类实现Comparable接口并覆盖其compareTo方法,它们按字典顺序排序。

static <T extends Comparable<? super T>> Comparator<T> naturalOrder()
package com.concretepage;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class ComparatorNaturalOrderDemo {
  public static void main(String[] args) {
  List<Integer> numList = Arrays.asList(12, 10, 15, 8, 11);
  numList.sort(Comparator.naturalOrder());
  numList.forEach(n -> System.out.print(n + " "));
  System.out.println("-----------");

  List<String> strList = Arrays.asList("Varanasi", "Allahabad", "Kanpur", "Noida");
  strList.sort(Comparator.naturalOrder());
  strList.forEach(s -> System.out.print(s + " "));
  System.out.println("-----------");  

  List<Student> stdList = Student.getStudentList();
  stdList.sort(Comparator.naturalOrder());
  stdList.forEach(s -> System.out.print(s.getName() + " "));
  }
}

输出:

8 10 11 12 15 
-----------
Allahabad Kanpur Noida Varanasi 
-----------
Mohan Ram Shyam

nullsFirst是Comparator功能接口的静态方法。Comparator.nullsFirst方法返回一个空值友好的比较器,该比较器将null视为小于非null。

static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator)
  1. null元素被认为小于非null。
  2. 当两个元素都为空时,它们被认为是相等的。
  3. 当两个元素都为非null时,指定的Comparator将确定顺序。
  4. 如果指定的比较器为空,则返回的比较器将所有非空元素视为相等。
package com.concretepage;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class NullsFirstDemo {
  public static void main(String[] args) {
  Student s1 = new Student("Ram", 18);
  Student s2 = new Student("Shyam", 22);
  Student s3 = new Student("Mohan", 17);

  System.out.println("-------Case1: One null----------");

  List<Student> list = Arrays.asList(s1, s2, null, s3);
  Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student::getName)));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case2: More than one null---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student::getName)));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case3: Reverse specified Comparator to nullsFirst---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student::getName).reversed()));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case4: Reverse Comparator returned by nullsFirst---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student::getName)).reversed());
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case5: Specify natural order Comparator to nullsFirst---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsFirst(Comparator.naturalOrder()));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case6: Specify null to nullsFirst---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsFirst(null));
  list.forEach(s -> System.out.println(s));
  }
}

输出:

-------Case1: One null----------
null
Mohan-17
Ram-18
Shyam-22
--------Case2: More than one null---------
null
null
Mohan-17
Ram-18
Shyam-22
--------Case3: Reverse specified Comparator to nullsFirst---------
null
null
Shyam-22
Ram-18
Mohan-17
--------Case4: Reverse Comparator returned by nullsFirst---------
Shyam-22
Ram-18
Mohan-17
null
null
--------Case5: Specify natural order Comparator to nullsFirst---------
null
null
Mohan-17
Ram-18
Shyam-22
--------Case6: Specify null to nullsFirst---------
null
null
Ram-18
Shyam-22
Mohan-17

nullsLast是Comparator功能接口的静态方法。Comparator.nullsLast方法返回一个空值友好的比较器,该比较器将null视为大于非null。

static <T> Comparator<T> nullsLast(Comparator<? super T> comparator)
  1. null元素被认为大于非null。
  2. 当两个元素都为空时,它们被认为是相等的。
  3. 当两个元素都为非null时,指定的Comparator将确定顺序。
  4. 如果指定的比较器为空,则返回的比较器将所有非空元素视为相等。
package com.concretepage;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class NullsLastDemo {
  public static void main(String[] args) {
  Student s1 = new Student("Ram", 18);
  Student s2 = new Student("Shyam", 22);
  Student s3 = new Student("Mohan", 17);

  System.out.println("-------Case1: One null----------");

  List<Student> list = Arrays.asList(s1, s2, null, s3);
  Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student::getName)));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case2: More than one null---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student::getName)));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case3: Reverse specified Comparator to nullsLast---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student::getName).reversed()));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case4: Reverse Comparator returned by nullsLast---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student::getName)).reversed());
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case5: Specify natural order Comparator to nullsLast---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsLast(Comparator.naturalOrder()));
  list.forEach(s -> System.out.println(s));

  System.out.println("--------Case6: Specify null to nullsLast---------");

  list = Arrays.asList(s1, null, s2, null, s3);
  Collections.sort(list, Comparator.nullsLast(null));
  list.forEach(s -> System.out.println(s));
  }
}

输出:

-------Case1: One null----------
Mohan-17
Ram-18
Shyam-22
null
--------Case2: More than one null---------
Mohan-17
Ram-18
Shyam-22
null
null
--------Case3: Reverse specified Comparator to nullsLast---------
Shyam-22
Ram-18
Mohan-17
null
null
--------Case4: Reverse Comparator returned by nullsLast---------
null
null
Shyam-22
Ram-18
Mohan-17
--------Case5: Specify natural order Comparator to nullsLast---------
Mohan-17
Ram-18
Shyam-22
null
null
--------Case6: Specify null to nullsLast---------
Ram-18
Shyam-22
Mohan-17
null
null 

比较是比较器功能接口的静态方法。Comparator.comparing接受一个Function,它从给定类型中提取Comparable排序键,并返回一个Comparator,该Comparator按该排序键进行比较。Comparator.comparing有两种形式。

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

需要传递一个Function,它将从类型T中提取Comparable排序键,并返回一个Comparator,它按该排序键进行比较。

Comparator<Student> nameComparator = Comparator.comparing(Student::getName);
static <T,U> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator)

需要传递一个函数和一个比较器。该方法将从类型T中提取排序键,并返回使用指定的Comparator通过该排序键进行比较的Comparator

Comparator<Student> nameComparator = Comparator.comparing(Student::getName, (s1, s2) -> s2.compareTo(s1));

对于int,long和double数据类型排序键,Comparator分别具有comparisonInt,comparisonLong和comparisonDouble方法。

package com.concretepage;
public class School implements Comparable<School> {
  private int code;
  private String sname;
  public School(int code, String sname) {
  this.code = code;
  this.sname = sname;
  }
  public int getCode() {
        return code;
  }
  public String getSname() {
        return sname;
  }
  @Override
  public int compareTo(School s) {
  return s.sname.compareTo(sname);
  }
}

创建另一个类,我们将在其中创建School类的class属性。

package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class Student {
  private String name;
  private int age;
  private long homeDistance;  
  private double weight;
  private School school;
  public Student(String name, int age, long homeDistance, double weight, School school) {
  this.name = name;
  this.age = age;
  this.homeDistance = homeDistance;
  this.weight = weight;
  this.school = school;
  }
  public String getName() {
        return name;
  }
  public int getAge() {
        return age;
  }
  public long getHomeDistance() {
        return homeDistance;
  }
  public double getWeight() {
        return weight;
  }
  public School getSchool() {
        return school;
  }
  public static List<Student> getStudentList() {
  Student s1 = new Student("Ram", 18, 3455, 60.75, new School(101, "PQ College"));
  Student s2 = new Student("Shyam", 22, 3252, 65.80, new School(103, "RS College"));
  Student s3 = new Student("Mohan", 19, 1459, 65.20, new School(102, "AB College"));
  Student s4 = new Student("Mahesh", 20, 4450, 70.25, new School(104, "CD College"));
  List<Student> list = Arrays.asList(s1, s2, s3, s4);
  return list;
  }
}

Comparator.comparing方法

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparingDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    Comparator<Student> schoolComparator1 = Comparator.comparing(Student::getSchool);
    Collections.sort(list, schoolComparator1);
    list.forEach(s->System.out.print(s.getName() + "-" + s.getSchool().getSname() + " | "));
    System.out.println("-------------------");    

    Comparator<Student> schoolComparator2 = 
      Comparator.comparing(Student::getSchool, (sch1, sch2) -> sch1.getCode() - sch2.getCode());
    Collections.sort(list, schoolComparator2);
    list.forEach(s->System.out.print(s.getName() + "-" + s.getSchool().getCode() + " | "));
    System.out.println("-------------------");    

    Comparator<Student> nameComparator1 = Comparator.comparing(Student::getName); 
    Collections.sort(list, nameComparator1);
    list.forEach(s->System.out.print(s.getName() + " "));
    System.out.println("-------------------");

    Comparator<Student> nameComparator2 = Comparator.comparing(Student::getName, (s1, s2) -> s2.compareTo(s1));     
    Collections.sort(list, nameComparator2);
    list.forEach(s->System.out.print(s.getName() + " "));    
  }
}

输出:

Shyam-RS College | Ram-PQ College | Mahesh-CD College | Mohan-AB College | 
-------------------
Ram-101 | Mohan-102 | Shyam-103 | Mahesh-104 | 
-------------------
Mahesh Mohan Ram Shyam 
-------------------
Shyam Ram Mohan Mahesh

找到comparisonInt方法的声明。

static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor)

它接受一个从类型T中提取int排序键的函数,并返回一个通过该排序键进行比较的Comparator。找到这个例子。使用Student class进行比较

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparingIntDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    Collections.sort(list, Comparator.comparingInt(Student::getAge));
    list.forEach(s->System.out.print(s.getAge() + " "));    
  }
}

输出:

18 19 20 22

comparisonLong方法的声明。

static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor)

它接受一个从类型T中提取长排序键的函数,并返回一个通过该排序键进行比较的Comparator。找到这个例子。使用Student class进行比较

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparingLongDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    Collections.sort(list, Comparator.comparingLong(Student::getHomeDistance));
    list.forEach(s->System.out.print(s.getHomeDistance() + " "));           
  }
}

输出:

1459 3252 3455 4450

找到comparisonDouble方法的声明。

static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor)

它接受一个从类型T中提取双重排序键的函数,并返回一个按该排序键进行比较的Comparator。

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparingDoubleDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    Collections.sort(list, Comparator.comparingDouble(Student::getWeight));
    list.forEach(s->System.out.print(s.getWeight() + " "));           
  }
}

输出:

60.75 65.2 65.8 70.25 

thenComparing是Comparator功能接口的默认方法。Comparator.thenComparing返回一个词典顺序比较器,该比较器由Comparator实例调用,以使用排序键组对项目进行排序。当该比较器比较两个相等的元素时,则比较方法确定顺序。我们可以多次使用Comparator.thenComparing。当我们想要通过排序键组确定元素的顺序时,它很有用。对于int,long和double数据类型排序键,Comparator分别具有ComparingInt,thenComparingLong和thenComparingDouble默认方法。

然后比较有以下形式。

default Comparator<T> thenComparing(Comparator<? super T> other)

返回一个带有另一个比较器的字典顺序比较器。

Comparator<Student> compByStdName = Comparator.comparing(Student::getName);
Comparator<Student> schoolComparator1 = Comparator.comparing(Student::getAge) //sort by student age
  .thenComparing(compByStdName); //then sort by student name

首先,比较者将按学生年龄对学生的收集进行排序,如果对于某些学生,年龄相等,则按其姓名排序。

default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T,? extends U> keyExtractor)

返回一个字典顺序比较器,其中包含一个提取Comparable排序键的函数。

Comparator<Student> schoolComparator2 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
  .thenComparing(Student::getAge) //then sort by student age
  .thenComparing(Student::getName); //then sort by student name

首先,学生的收藏将按其各自的学校按其自然顺序排序,如果一些学生根据他们的学校顺序是相等的,那么这些学生将按他们各自的年龄排序,如果年龄也等于那么他们将按他们的排序 名称。

default <U> Comparator<T> thenComparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator)

返回一个字典顺序比较器,其中包含一个函数,用于提取要与给定比较器进行比较的键。

Comparator<Student> schoolComparator3 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
  .thenComparing(Student::getSchool, (school1, school2) -> school1.getSname().compareTo(school2.getSname())) //then sort by school name 
  .thenComparing(Student::getAge) //then sort by student age
  .thenComparing(Student::getName); //then sort by student name

首先,学生的收藏将按其各自的学校按其自然顺序排序(即通过我们的演示中的学校城市),然后如果学生在同一学校城市,他们将按照他们各自的学校名称排序,如果学生与 相同的学校名称,他们将按年龄排序,如果学生年龄相同,他们将按姓名分类。

package com.concretepage;
public class School implements Comparable<School> {
  private String sname;
  private String city;  
  public School(String sname, String city) {
  this.sname = sname;
  this.city = city;
  }
  public String getSname() {
        return sname;
  }
  public String getCity() {
        return city;
  }
  @Override
  public int compareTo(School s) {
  return s.getCity().compareTo(city);
  }
}
package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class Student {
  private String name;
  private int age;
  private long homeDistance;
  private double weight;
  private School school;

  public Student(String name, int age, long homeDistance, double weight, School school) {
  this.name = name;
  this.age = age;
  this.homeDistance = homeDistance;
  this.weight = weight;
  this.school = school;
  }
  public String getName() {
  return name;
  }
  public int getAge() {
  return age;
  }
  public long getHomeDistance() {
  return homeDistance;
  }
  public double getWeight() {
  return weight;
  }
  public School getSchool() {
  return school;
  }
  public static List<Student> getStudentList() {
  Student s1 = new Student("Ram", 18, 3455, 60.75, new School("AB College", "Noida"));
  Student s2 = new Student("Shyam", 22, 3252, 65.80, new School("RS College", "Gurugram"));
  Student s3 = new Student("Mohan", 18, 1459, 65.20, new School("AB College", "Noida"));
  Student s4 = new Student("Mahesh", 22, 4450, 70.25, new School("RS College", "Gurugram"));
  List<Student> list = Arrays.asList(s1, s2, s3, s4);
  return list;
  }
}
package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    System.out.println("--------Example-1---------"); 

    Comparator<Student> compByStdName = Comparator.comparing(Student::getName);
    Comparator<Student> schoolComparator1 = Comparator.comparing(Student::getAge) //sort by student age
      .thenComparing(compByStdName); //then sort by student name   

    Collections.sort(list, schoolComparator1);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()));

    System.out.println("--------Example-2---------");   

    Comparator<Student> schoolComparator2 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
      .thenComparing(Student::getAge) //then sort by student age
      .thenComparing(Student::getName); //then sort by student name   

    Collections.sort(list, schoolComparator2);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()+ "-" + s.getSchool().getCity()));

    System.out.println("--------Example-3---------");    

    Comparator<Student> schoolComparator3 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
      .thenComparing(Student::getSchool, (school1, school2) -> school1.getSname().compareTo(school2.getSname())) //then sort by school name 
      .thenComparing(Student::getAge) //then sort by student age
      .thenComparing(Student::getName); //then sort by student name 

    Collections.sort(list, schoolComparator3);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()+ "-" + s.getSchool().getSname() + "-" + s.getSchool().getCity()));
  }
}

输出:

--------Example-1---------
Mohan-18
Ram-18
Mahesh-22
Shyam-22
--------Example-2---------
Mohan-18-Noida
Ram-18-Noida
Mahesh-22-Gurugram
Shyam-22-Gurugram
--------Example-3---------
Mohan-18-AB College-Noida
Ram-18-AB College-Noida
Mahesh-22-RS College-Gurugram
Shyam-22-RS College-Gurugram

thenComparingInt方法声明

default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor)

返回一个字典顺序比较器,其中包含一个提取int排序键的函数。

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingIntDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    Comparator<Student> comparator = Comparator.comparing(Student::getName, (s1, s2) -> s1.charAt(0) - s2.charAt(0))
      .thenComparingInt(Student::getAge);

    Collections.sort(list, comparator);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()));    
  }
}

输出:

Mohan-18Mahesh-22Ram-18Shyam-22

thenComparingLong方法声明

default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor)

返回一个字典顺序比较器,其中包含一个提取长排序键的函数。

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingLongDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    Comparator<Student> comparator = Comparator.comparing(Student::getName, (s1, s2) -> s1.charAt(0) - s2.charAt(0))
      .thenComparingLong(Student::getHomeDistance);

    Collections.sort(list, comparator);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getHomeDistance()));  
  }
}

输出:

Mohan-1459Mahesh-4450Ram-3455Shyam-3252

thenComparingDouble方法声明

default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor)

它返回一个字典顺序比较器,其中包含一个提取双排序键的函数。

package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingDoubleDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();

    Comparator<Student> comparator = Comparator.comparing(Student::getName, (s1, s2) -> s1.charAt(0) - s2.charAt(0))
      .thenComparingDouble(Student::getWeight);

    Collections.sort(list, comparator);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getWeight()));         
  }
}

输出:

Mohan-65.2Mahesh-70.25Ram-60.75Shyam-65.8 

Comparator with SortedSet

Java Comparator可用于控制SortedSet数据结构的顺序。SortedSet的实现类是TreeSet和ConcurrentSkipListSet。我们可以将Comparator实例传递给TreeSet和ConcurrentSkipListSet类的构造函数来控制它的顺序。SortedSet提供了comparator()方法,该方法返回用于对此集合中的元素进行排序的比较器。如果SortedSet使用其元素的自然排序,则comparator()方法返回null。

Comparator with TreeSet

TreeSet根据元素的自然顺序对元素进行排序,或者通过在创建时设置的比较器对元素进行排序,具体取决于使用的构造函数。

TreeSet(Comparator<? super E> comparator)

它构造一个新的空树集,根据指定的比较器进行排序。当我们不传递比较器时,TreeSet根据其自然顺序对元素进行排序。对于自然排序,类需要实现Comparable接口并覆盖compareTo方法。

为了获得TreeSet对象使用的比较器,SortedSet提供了comparator()方法。

package com.concretepage;

import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo {
    public static void main(String[] args) {
        Student s1 = new Student("Shyam", 18);
        Student s2 = new Student("Mohan", 20);
        Student s3 = new Student("Ram", 22);
        System.out.println("---TreeSet Order With Comparator---");
        Comparator<Student> ageComparator = Comparator.comparing(Student::getAge);
        TreeSet<Student> myTreeSet = new TreeSet<>(ageComparator);
        myTreeSet.addAll(Arrays.asList(s1, s2, s3));
        myTreeSet.forEach(s -> System.out.println(s));    //System.out.println("Comparator: "+ myTreeSet.comparator());    System.out.println("---TreeSet Natural Order (With Comparable)---");    myTreeSet = new TreeSet<>();  myTreeSet.addAll(Arrays.asList(s1, s2, s3));  myTreeSet.forEach(s -> System.out.println(s));  }}
    }
}

输出:

---TreeSet Order With Comparator---
Shyam-18
Mohan-20
Ram-22
---TreeSet Natural Order (With Comparable)---
Mohan-20
Ram-22
Shyam-18

Comparator with ConcurrentSkipListSet

ConcurrentSkipListSet根据元素的自然顺序对元素进行排序,或者根据设置的创建时间提供的比较器对元素进行排序,具体取决于使用的构造函数。

ConcurrentSkipListSet(Comparator<? super E> comparator)

构造一个新的空集,根据指定的比较器对其元素进行排序。当我们不传递比较器时,ConcurrentSkipListSet根据其自然顺序对元素进行排序。对于自然排序,类需要实现Comparable接口并覆盖compareTo方法。

为了获得ConcurrentSkipListSet对象使用的比较器,SortedSet提供了comparator()方法。

package com.concretepage;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.ConcurrentSkipListSet;
public class ConcurrentSkipListSetDemo {
  public static void main(String[] args) {
  Student s1 = new Student("Shyam", 18);
  Student s2 = new Student("Mohan", 20);
  Student s3 = new Student("Ram", 22);

  System.out.println("---ConcurrentSkipListSet Order With Comparator---");

  Comparator<Student> ageComparator = Comparator.comparing(Student::getAge);
  ConcurrentSkipListSet<Student> myConcurrentSkipList = new ConcurrentSkipListSet<>(ageComparator);
  myConcurrentSkipList.addAll(Arrays.asList(s1, s2, s3));
  myConcurrentSkipList.forEach(s -> System.out.println(s));  
  //System.out.println("Comparator: "+ myConcurrentSkipList.comparator());

  System.out.println("---ConcurrentSkipListSet Natural Order (With Comparable)---");

  myConcurrentSkipList = new ConcurrentSkipListSet<>();
  myConcurrentSkipList.addAll(Arrays.asList(s1, s2, s3));
  myConcurrentSkipList.forEach(s -> System.out.println(s));
  }
}

输出:

---ConcurrentSkipListSet Order With Comparator---
Shyam-18
Mohan-20
Ram-22
---ConcurrentSkipListSet Natural Order (With Comparable)---
Mohan-20
Ram-22
Shyam-18

Comparator with SortedMap

Java Comparator可用于控制SortedMap数据结构的键的顺序。SortedMap的实现类是TreeMap和ConcurrentSkipListMap。我们可以将Comparator实例传递给TreeMap和ConcurrentSkipListMap类的构造函数来控制其键的顺序。SortedMap提供了comparator()方法,该方法返回用于对此映射中的键进行排序的比较器。如果SortedMap使用关键元素的自然排序,则comparator()方法返回null。

Comparator with TreeMap

TreeMap根据其键的自然顺序进行排序,或者通过在映射创建时提供的比较器进行排序,具体取决于使用的构造函数。

TreeMap(Comparator<? super K> comparator)

它构造一个新的空树图,根据给定的比较器排序。当我们不通过比较器时,TreeMap将键排序为其自然顺序。对于自然排序,元素类需要实现Comparable接口并覆盖compareTo方法。

为了获得我们的TreeMap对象使用的比较器,SortedMap提供了comparator()方法。

package com.concretepage;

import java.util.Comparator;
import java.util.TreeMap;

public class TreeMapDemo {
    public static void main(String[] args) {
        Student s1 = new Student("Shyam", 18);
        Student s2 = new Student("Mohan", 20);
        Student s3 = new Student("Ram", 22);
        System.out.println("---TreeMap Order With Comparator---");
        Comparator<Student> ageComparator = Comparator.comparing(Student::getAge);
        TreeMap<Student, String> myTreeMap = new TreeMap<>(ageComparator);
        myTreeMap.put(s1, "Varanasi");
        myTreeMap.put(s2, "Mathura");
        myTreeMap.put(s3, "Kashi");
        myTreeMap.forEach((k, v) -> System.out.println(k + " - " + v));    //System.out.println("Comparator: "+ myTreeMap.comparator());    System.out.println("---TreeMap Natural Order (With Comparable)---");    myTreeMap = new TreeMap<>();  myTreeMap.put(s1, "Varanasi");  myTreeMap.put(s2, "Mathura");  myTreeMap.put(s3, "Kashi");    myTreeMap.forEach((k, v) -> System.out.println(k + " - " + v));    }}
    }
}

输出:

---TreeMap Order With Comparator---
Shyam-18 - Varanasi
Mohan-20 - Mathura
Ram-22 - Kashi
---TreeMap Natural Order (With Comparable)---
Mohan-20 - Mathura
Ram-22 - Kashi
Shyam-18 - Varanasi

Comparator with ConcurrentSkipListMap

ConcurrentSkipListMap根据其键的自然顺序或在映射创建时提供的比较器进行排序,具体取决于使用的构造函数

ConcurrentSkipListMap(Comparator<? super K> comparator)

它构造一个新的空映射,根据给定的比较器排序。当我们不传递比较器时,ConcurrentSkipListMap将键排序为其自然顺序。对于自然排序,元素类需要实现Comparable接口并覆盖compareTo方法。

为了获得ConcurrentSkipListMap对象使用的比较器,SortedMap提供了comparator()方法。

package com.concretepage;
import java.util.Comparator;
import java.util.concurrent.ConcurrentSkipListMap;
public class ConcurrentSkipListMapDemo {
public static void main(String[] args) {
  Student s1 = new Student("Shyam", 18);
  Student s2 = new Student("Mohan", 20);
  Student s3 = new Student("Ram", 22);

  System.out.println("---ConcurrentSkipListMap Order With Comparator---");

  Comparator<Student> ageComparator = Comparator.comparing(Student::getAge);
  ConcurrentSkipListMap<Student, String> myConcurrentSkipListMap = new ConcurrentSkipListMap<>(ageComparator);
  myConcurrentSkipListMap.put(s1, "Varanasi");
  myConcurrentSkipListMap.put(s2, "Mathura");
  myConcurrentSkipListMap.put(s3, "Kashi");  
  myConcurrentSkipListMap.forEach((k, v) -> System.out.println(k + " - " + v));  
//System.out.println("Comparator: "+ myConcurrentSkipListMap.comparator());

  System.out.println("---ConcurrentSkipListMap Natural Order (With Comparable)---");

  myConcurrentSkipListMap = new ConcurrentSkipListMap<>();
  myConcurrentSkipListMap.put(s1, "Varanasi");
  myConcurrentSkipListMap.put(s2, "Mathura");
  myConcurrentSkipListMap.put(s3, "Kashi");  
  myConcurrentSkipListMap.forEach((k, v) -> System.out.println(k + " - " + v));  
  }
}

输出:

---ConcurrentSkipListMap Order With Comparator---
Shyam-18 - Varanasi
Mohan-20 - Mathura
Ram-22 - Kashi
---ConcurrentSkipListMap Natural Order (With Comparable)---
Mohan-20 - Mathura
Ram-22 - Kashi
Shyam-18 - Varanasi

收藏地址:程序员DD

0
青年IT男

个人从事金融行业,就职过易极付、思建科技等重庆一流技术团队,目前就职于某网约车平台负责整个支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、响应式编程、人工智能等领域。

评论已关闭。

This site is protected by wp-copyrightpro.com