【Java 8 新特性】Java Comparator |
您所在的位置:网站首页 › compare在java中的用法 › 【Java 8 新特性】Java Comparator |
Java Comparator | 比较器
比较器功能方法:compare(T o1, T o2)1. 使用 Lambda 表达式定义 compare2. 自定义 compare 实现比较器
比较器的使用Stream.sortedCollections.sortList.sortArrays.sort
比较器的方法1. reversed2. reverseOrder3. naturalOrder4. nullsFirst5. nullsLast6. comparing7. comparingInt8. comparingLong9. comparingDouble10. thenComparing11. thenComparingInt12. thenComparingLong13. thenComparingDouble
在 SortedSet 中使用比较器1. 在TreeSet中使用比较器2. 在 ConcurrentSkipListSet 中使用比较器
在 SortedMap 使用比较器1. 在 TreeMap 中使用比较器2. 在 ConcurrentSkipListMap 中使用比较器
参考文献
Java java.util.Comparator功能接口对对象的集合进行总排序。 为了对一个集合进行排序,我们将比较器(Comparator)实例传递给Stream.sorted、Collections.sort、List.sort和Arrays.sort方法。 比较器(Comparator)还可以控制SortedSet的顺序和SortedMap数据结构的键顺序。 比较器(Comparator)的功能方法是compare(T o1, T o2),当第一个参数小于、等于或大于第二个参数时,返回一个负整数、零或一个正整数。 比较器(Comparator)施加的排序应与equals方法一致。 只有当c.compare(e1, e2)==0对于集合中的每个e1和e2具有与e1.equals(e2)相同的布尔值时,才称为一致,其中c是比较器(Comparator)的实例。 现在让我们详细讨论比较器(Comparator)示例。 比较器功能方法:compare(T o1, T o2)compare是比较器功能接口的功能方法。从Java源代码中找到它的声明。 int compare(T o1, T o2)compare比较其两个参数的顺序。 当第一个参数小于、等于或大于第二个参数时,它返回负值、零值或正值。 找到定义比较方法的例子。 1. 使用 Lambda 表达式定义 compare我们使用lambda表达式定义compare功能方法如下。 Comparator ageComp = (s1, s2) -> s1.getAge() - s2.getAge(); Comparator nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());示例 CompareDemo.java import java.util.Comparator; import java.util.List; public class CompareDemo { public static void main(String[] args) { List list = Student.getStudentList(); System.out.println("--- Sort Students by age ---"); Comparator 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 nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName()); list.sort(nameComp); list.forEach(s -> System.out.println(s)); } }compare功能方法需要返回-ve、0、+ve的值。 s1.getAge()-s2.getAge()将返回-ve、0、+ve的值。 而String.compareTo对两个字符串进行按字母顺序的比较,它返回-ve、0、+ve的值。 List.sort根据给定的比较器(Comparator)实例对这个列表进行排序。 现在找到一个在Student类中使用的示例。 Student.java import java.util.Arrays; import java.util.List; public class Student implements Comparable { 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 getStudentList(){ Student s1 = new Student("Ram", 18); Student s2 = new Student("Shyam",22); Student s3 = new Student("Mohan",19); List 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 2. 自定义 compare 实现比较器CompareDemoImplement.java import java.io.Serializable; import java.util.Comparator; import java.util.List; class AgeComparator implements Comparator, Serializable { private static final long serialVersionUID = 1L; @Override public int compare(Student s1, Student s2) { return s1.getAge() - s2.getAge(); } } class NameComparator implements Comparator, 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 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在实现比较器接口的同时实现Serializable是一个很好的做法,因为它们可能被用作可序列化数据结构(如TreeSet和TreeMap)的排序方法。 比较器的使用我们可以用Stream.sorted、Collections.sort、List.sort和Arrays.sort方法来使用我们的比较器。 Stream.sortedStream.sorted返回一个由这个流的元素组成的流,根据提供的比较器进行排序。 CompareDemoStreamSorted.java import java.util.Comparator; import java.util.List; public class CompareDemoStreamSorted { public static void main(String[] args) { List list = Student.getStudentList(); System.out.println("--- Sort Students by age ---"); Comparator 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 nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName()); list.stream().sorted(nameComp).forEach(s -> System.out.println(s)); } }使用的Student类为上面compare例子中的学生类。 Collections.sortCollections.sort根据给定的比较器实例对指定的列表进行排序。 CompareDemoCollectionsSort.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class CompareDemoCollectionsSort { public static void main(String[] args) { List list = Student.getStudentList(); System.out.println("--- Sort Students by age ---"); Comparator 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 nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName()); Collections.sort(list, nameComp); list.forEach(s -> System.out.println(s)); } }使用的Student类为上面compare例子中的学生类。 List.sortList.sort根据给定的比较器实例对这个列表进行排序。 CompareDemoListSort.java import java.util.Comparator; import java.util.List; public class CompareDemoListSort { public static void main(String[] args) { List list = Student.getStudentList(); System.out.println("--- Sort Students by age ---"); Comparator 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 nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName()); list.sort(nameComp); list.forEach(s -> System.out.println(s)); } }使用的Student类为上面compare例子中的学生类。 Arrays.sortArrays.sort根据指定比较器产生的顺序对指定的对象数组进行排序。 CompareDemoArraysSort.java 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 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 nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName()); Arrays.sort(array, nameComp); for (Student s : array) { System.out.println(s); } } }使用的Student类为上面compare例子中的学生类。 比较器的方法在Java 8中,比较器接口引入了一些静态和默认的方法。 在这里,我们将结合实例讨论这些方法。 我们可以将比较器与Stream.sorted、List.sort、Collections.sort和Arrays.sort一起使用来对集合和Map进行排序。 1. reversedreversed是Java比较器功能接口的默认方法。reversed返回一个比较器,该比较器强制执行反向排序。 声明如下。 default Comparator reversed()要使用reversed方法,我们需要实例化我们的比较器并调用该方法。 reversed将返回新的比较器实例,该实例将强加该比较器的反向排序。 Comparator nameComparator = (s1, s2) -> s1.getName().compareTo(s2.getName()); Collections.sort(list, nameComparator.reversed());示例,其中使用的Student类为上面compare例子中的学生类。 ComparatorReversedDemo.java import java.util.Comparator; import java.util.List; import com.concretepage.Student; public class ComparatorReversedDemo { public static void main(String[] args) { List list = Student.getStudentList(); Comparator ageComparator = (s1, s2) -> s1.getAge() - s2.getAge(); list.stream().sorted(ageComparator.reversed()).forEach(s -> System.out.print(s.getAge() + " ")); System.out.println("\n-----------"); Comparator nameComparator = (s1, s2) -> s1.getName().compareTo(s2.getName()); list.stream().sorted(nameComparator.reversed()).forEach(s -> System.out.print(s.getName() + " ")); System.out.println("\n-----------"); list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).forEach(s -> System.out.print(s.getAge() + " ")); System.out.println("\n-----------"); 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 2. reverseOrderreverseOrder是一个静态方法,返回比较器,对对象集合进行反向自然排序。 对于自然排序,一个类需要实现比较器并定义compareTo方法。 一个对象集合根据自然排序中的compareTo进行排序。 Comparator.reverseOrder反转了自然排序。 它在内部调用Collections.reverseOrder()并返回比较器实例。 查找Comparator.reverseOrder的Java源代码。 public static Comparator reverseOrder() { return Collections.reverseOrder(); }示例,其中使用的Student类为上面compare例子中的学生类。 ComparatorReverseOrderDemo.java 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 numList = Arrays.asList(12, 10, 15, 8, 11); Collections.sort(numList, Comparator.reverseOrder()); numList.forEach(n -> System.out.print(n + " ")); System.out.println("\n-----------"); List strList = Arrays.asList("Varanasi", "Allahabad", "Kanpur", "Noida"); Collections.sort(strList, Comparator.reverseOrder()); strList.forEach(s -> System.out.print(s + " ")); System.out.println("\n-----------"); List 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 3. naturalOrdernaturalOrder是比较器功能接口的静态方法。 Comparator.naturalOrder方法返回一个比较器,该比较器以自然顺序比较可比较的对象。 对于自然排序,一个类需要实现Comparable并定义compareTo方法。 一个对象的集合按照自然排序的compareTo方法进行排序。 像Integer、String和Date这样的Java类实现了Comparable接口,并覆盖了其compareTo方法,它们以词汇表(lexicographic-order)排序。 从Java源代码中找到naturalOrder方法声明。 static Comparator naturalOrder()找到使用List.sort方法的Comparator.naturalOrder的例子。 import java.util.Arrays; import java.util.Comparator; import java.util.List; public class ComparatorNaturalOrderDemo { public static void main(String[] args) { List numList = Arrays.asList(12, 10, 15, 8, 11); numList.sort(Comparator.naturalOrder()); numList.forEach(n -> System.out.print(n + " ")); System.out.println("\n-----------"); List strList = Arrays.asList("Varanasi", "Allahabad", "Kanpur", "Noida"); strList.sort(Comparator.naturalOrder()); strList.forEach(s -> System.out.print(s + " ")); System.out.println("\n-----------"); List 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 4. nullsFirstnullsFirst是比较器功能接口的静态方法。 Comparator.nullsFirst方法返回一个对null友好的比较器,它认为null小于非null。 从Java源代码中找到它的声明。 static Comparator nullsFirst(Comparator comparator)找到由nullsFirst方法返回的比较器工作原理。 空元素被认为是小于非空元素的。当两个元素都是空的时候,那么它们就被认为是相等的。当两个元素都是非空的时候,指定的比较器决定了顺序。如果指定的比较器是空的,那么返回的比较器认为所有非空的元素是相等的。示例 NullsFirstDemo.java 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 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 5. nullsLastnullsLast是比较器功能接口的静态方法。 Comparator.nullsLast方法返回一个对null友好的比较器,认为null大于非null。 从Java源代码中找到它的声明。 static Comparator nullsLast(Comparator comparator)找到由nullsLast方法返回的比较器工作原理。 空元素被认为是大于非空元素的。当两个元素都是空的时候,那么它们就被认为是相等的。当两个元素都是非空的时候,指定的比较器决定了顺序。如果指定的比较器是空的,那么返回的比较器认为所有非空的元素是相等的。示例 NullsLastDemo.java 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 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 6. comparingcomparing是比较器功能接口的静态方法。 Comparator.comparing接受一个函数,该函数从给定的类型中提取一个可比较的排序键,并返回一个通过该排序键进行比较的比较器。 Comparator.comparing有两种形式。 1. static Comparator comparing(Function keyExtractor)我们需要传递一个函数,它将从一个类型T中提取一个可比较的排序键,并返回一个通过该排序键进行比较的比较器。 查找示例代码。 Comparator nameComparator = Comparator.comparing(Student::getName);2. static Comparator comparing(Function keyExtractor, Comparator keyComparator)我们需要传递一个函数和一个比较器。 该方法将从一个类型T中提取一个排序键,并返回一个比较器,使用指定的比较器对该排序键进行比较。 查找示例代码。 Comparator nameComparator = Comparator.comparing(Student::getName, (s1, s2) -> s2.compareTo(s1));对于int、long和double数据类型的排序键,比较器分别有comparingInt、comparingLong和comparingDouble方法。 这里我们将提供Comparator.comparing方法的例子。 找到一个将实现Comparable接口的类,并定义compareTo方法。 School.java public class School implements Comparable { 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类型的类属性。 Student.java 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 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 list = Arrays.asList(s1, s2, s3, s4); return list; } }现在找到Comparator.comparing方法的例子。 ComparingDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ComparingDemo { public static void main(String[] args) { List list = Student.getStudentList(); Comparator schoolComparator1 = Comparator.comparing(Student::getSchool); Collections.sort(list, schoolComparator1); list.forEach(s->System.out.print(s.getName() + "-" + s.getSchool().getSname() + " | ")); System.out.println("\n-------------------"); Comparator 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("\n-------------------"); Comparator nameComparator1 = Comparator.comparing(Student::getName); Collections.sort(list, nameComparator1); list.forEach(s->System.out.print(s.getName() + " ")); System.out.println("\n-------------------"); Comparator 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 7. comparingIntcomparingInt方法的声明。 static Comparator comparingInt(ToIntFunction keyExtractor)它接受一个从类型T中提取一个int排序键的函数,并返回一个通过该排序键进行比较的比较器。 ComparingIntDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ComparingIntDemo { public static void main(String[] args) { List list = Student.getStudentList(); Collections.sort(list, Comparator.comparingInt(Student::getAge)); list.forEach(s->System.out.print(s.getAge() + " ")); } }输出 18 19 20 22 8. comparingLongcomparingLong方法的声明。 static Comparator comparingLong(ToLongFunction keyExtractor)它接受一个从类型T中提取long排序键的函数,并返回一个通过该排序键进行比较的比较器。 ComparingLongDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ComparingLongDemo { public static void main(String[] args) { List list = Student.getStudentList(); Collections.sort(list, Comparator.comparingLong(Student::getHomeDistance)); list.forEach(s->System.out.print(s.getHomeDistance() + " ")); } }输出 1459 3252 3455 4450 9. comparingDoublecomparingDouble方法的声明。 static Comparator comparingDouble(ToDoubleFunction keyExtractor)它接受一个从类型T中提取double排序键的函数,并返回一个通过该排序键进行比较的比较器。 ComparingDoubleDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ComparingDoubleDemo { public static void main(String[] args) { List 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 10. thenComparingthenComparing是比较器功能接口的默认方法。 Comparator.thenComparing返回一个词表顺序(lexicographic-order)的比较器,该比较器被一个比较器实例调用,使用一组排序键对项目进行排序。 当这个比较器比较两个元素相等时,thenComparing方法决定了顺序。 我们可以多次使用Comparator.thenComparing。 当我们想通过排序键组来确定元素的顺序时,要用到它。 对于int、long和double数据类型的排序键,比较器分别有thenComparingInt、thenComparingLong和thenComparingDouble默认方法。 thenComparing有以下形式。 1. default Comparator thenComparing(Comparator other)它返回一个词表顺序(lexicographic-order)比较器和另一个比较器。查找代码段。 Comparator compByStdName = Comparator.comparing(Student::getName); Comparator schoolComparator1 = Comparator.comparing(Student::getAge) //sort by student age .thenComparing(compByStdName); //then sort by student name首先,比较器将按照学生年龄对学生集合进行排序,如果某些学生的年龄相同,那么将按照他们的名字进行排序。 2. default Comparator thenComparing(Function keyExtractor)它返回一个词表顺序(lexicographic-order)比较器,其中包含一个提取可比较排序键的函数。 Comparator 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首先,学生的集合将按照他们各自的学校的自然顺序进行排序,如果一些学生根据他们的学校排序是相同的,那么这些学生将按照他们各自的年龄进行排序,如果年龄也是相同的,那么他们将按照他们的名字进行排序。 3. default Comparator thenComparing(Function keyExtractor, Comparator keyComparator)它返回一个词表顺序(lexicographic-order)的比较器,该比较器带有一个函数,可以提取一个键与给定的比较器进行比较。 Comparator 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首先,学生的集合将按他们各自的学校的自然顺序进行排序(即在我们的演示中按学校所在城市),然后如果学生在同一学校所在城市,他们将按各自的学校名称进行排序,如果学生在同一学校名称,他们将按年龄进行排序,如果学生在同一年龄,他们将按名字进行排序。 完整的例子 School.java public class School implements Comparable { 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); } }Student.java 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 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 list = Arrays.asList(s1, s2, s3, s4); return list; } }ThenComparingDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ThenComparingDemo { public static void main(String[] args) { List list = Student.getStudentList(); System.out.println("--------Example-1---------"); Comparator compByStdName = Comparator.comparing(Student::getName); Comparator 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 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 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 11. thenComparingIntthenComparingInt方法声明。 default Comparator thenComparingInt(ToIntFunction keyExtractor)它返回一个词表顺序(lexicographic-order)比较器,其中包含一个提取int排序键的函数。找到例子。 ThenComparingIntDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ThenComparingIntDemo { public static void main(String[] args) { List list = Student.getStudentList(); Comparator 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-18 Mahesh-22 Ram-18 Shyam-22 12. thenComparingLongthenComparingLong方法声明。 default Comparator thenComparingLong(ToLongFunction keyExtractor)它返回一个词表顺序(lexicographic-order)比较器,其中包含一个提取long排序键的函数。找到例子。 ThenComparingLongDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ThenComparingLongDemo { public static void main(String[] args) { List list = Student.getStudentList(); Comparator 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-1459 Mahesh-4450 Ram-3455 Shyam-3252 13. thenComparingDoublethenComparingDouble方法声明。 default Comparator thenComparingDouble(ToDoubleFunction keyExtractor)它返回一个词表顺序(lexicographic-order)比较器,其中包含一个提取double排序键的函数。找到例子。 ThenComparingDoubleDemo.java import java.util.Collections; import java.util.Comparator; import java.util.List; public class ThenComparingDoubleDemo { public static void main(String[] args) { List list = Student.getStudentList(); Comparator 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.2 Mahesh-70.25 Ram-60.75 Shyam-65.8 在 SortedSet 中使用比较器Java Comparator可用于控制SortedSet数据结构的顺序。 SortedSet的实现类是TreeSet和ConcurrentSkipListSet。 我们可以将比较器实例传递给TreeSet和ConcurrentSkipListSet类的构造函数以控制其顺序。 SortedSet提供了comparator()方法,用于返回用于对这个集合中的元素进行排序的比较器。 如果SortedSet对其元素使用自然排序,那么comparator()方法返回null。 在这一页,我们将提供一些例子,说明如何在TreeSet和ConcurrentSkipListSet类中使用比较器。 1. 在TreeSet中使用比较器TreeSet根据元素的自然排序,或者通过在集合创建时提供的比较器对元素进行排序,这取决于使用哪个构造函数。 我们可以通过使用以下构造函数传递比较器来实例化TreeSet类。 TreeSet(Comparator comparator)它构建了一个新的、空的树集,根据指定的比较器进行排序。 当我们不传递比较器时,TreeSet会根据它的自然排序对元素进行排序。 对于自然排序,一个类需要实现Comparable接口并覆盖compareTo方法。 为了获得我们的TreeSet对象所使用的比较器,SortedSet提供了 comparator() 方法。 现在找到使用比较器与TreeSet类来控制其元素顺序的例子。使用本页面上面compare例子中的Student类。 TreeSetDemo.java 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 ageComparator = Comparator.comparing(Student::getAge); TreeSet 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 2. 在 ConcurrentSkipListSet 中使用比较器ConcurrentSkipListSet根据元素的自然排序或在集合创建时提供的比较器来排序,这取决于使用哪种构造函数。 我们可以通过使用下面的构造函数传递比较器来实例化ConcurrentSkipListSet类。 ConcurrentSkipListSet(Comparator comparator)它构造了一个新的、空的集合,根据指定的比较器对其元素进行排序。 当我们不传递比较器时,ConcurrentSkipListSet会根据其自然排序对元素进行排序。 对于自然排序,一个类需要实现Comparable接口并覆盖compareTo方法。 为了获得我们的ConcurrentSkipListSet对象所使用的比较器,SortedSet提供了comparator()方法。 现在找到使用比较器与ConcurrentSkipListSet类来控制其元素顺序的例子。 ConcurrentSkipListSetDemo.java 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 ageComparator = Comparator.comparing(Student::getAge); ConcurrentSkipListSet 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 在 SortedMap 使用比较器Java比较器可用于控制SortedMap数据结构的键的顺序。 SortedMap的实现类是TreeMap和ConcurrentSkipListMap。 我们可以将比较器实例传递给TreeMap和ConcurrentSkipListMap类的构造函数以控制其键的顺序。 SortedMap提供了comparator()方法,用于返回用于对该Map中的键进行排序的比较器。 如果SortedMap使用key元素的自然排序,那么comparator()方法返回null。 在这一页,我们将提供一些例子,说明如何在TreeMap和ConcurrentSkipListMap类中使用比较器。 1. 在 TreeMap 中使用比较器TreeMap根据其键的自然排序或在Map创建时提供的比较器进行排序,这取决于使用哪个构造函数。 我们可以通过使用以下构造函数传递比较器来实例化TreeMap类。 TreeMap(Comparator comparator)它构造一个新的、空的TreeMap,根据给定的比较器进行排序。 当我们不传递比较器时,TreeMap会按其自然顺序对键进行排序。 对于自然排序,元素类需要实现Comparable接口并重写compareTo方法。 为了获得我们的TreeMap对象所使用的比较器,SortedMap提供了comparator()方法。 现在找到使用比较器与TreeMap类来控制其键的顺序的例子。使用本页面上面compare例子中的Student类。 TreeMapDemo.java 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 ageComparator = Comparator.comparing(Student::getAge); TreeMap 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 2. 在 ConcurrentSkipListMap 中使用比较器ConcurrentSkipListMap根据其键的自然排序,或者根据Map创建时提供的比较器进行排序,这取决于使用哪个构造函数。 我们可以通过使用下面的构造函数传递比较器来实例化ConcurrentSkipListMap类。 ConcurrentSkipListMap(Comparator comparator)它构造一个新的、空的Map,根据给定的比较器排序。 当我们不传递比较器时,ConcurrentSkipListMap会根据其自然排序对键进行排序。 对于自然排序,元素类需要实现Comparable接口并重写compareTo方法。 为了获得我们的ConcurrentSkipListMap对象所使用的比较器,SortedMap提供了comparator()方法。 现在找到使用比较器与ConcurrentSkipListMap类来控制其键的顺序的例子。 ConcurrentSkipListMapDemo.java 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 ageComparator = Comparator.comparing(Student::getAge); ConcurrentSkipListMap 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 参考文献【1】Interface Comparator 【2】Interface SortedSet 【3】Interface SortedMap 【4】Java Comparator |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |