Comparator详解
1.compare是比较器功能接口的功能方法。当第一个参数小于、等于或大于第二个参数时,它返回负值、零值或正值。
package com.example.test;
import java.util.Arrays;
import java.util.List;
public class Student3 implements Comparable<Student3> {
private String name;
private int age;
private long homeDistance;
private double weight;
private School school;
public Student3(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;
}
@Override
public int compareTo(Student3 s) {
return name.compareTo(s.getName());
}
@Override
public String toString(){
return name + "-" + age;
}
public static List<Student3> getStudentList(){
Student3 s1 = new Student3("Ram", 18,3455, 60.75, new School("AB College", "Noida"));
Student3 s2 = new Student3("Shyam",22, 3252, 65.80, new School("RS College", "Gurugram"));
Student3 s3 = new Student3("Mohan",19, 1459, 65.20, new School("AB College", "Noida"));
List<Student3> list = Arrays.asList(s1,s2,s3);
return list;
}
}
package com.example.test;
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);
}
}
DEMO参数:
Comparator<Student3> ageComp = (s1, s2) -> s1.getAge() - s2.getAge();
Comparator<Student3> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());
Student3 s1 = new Student3("Ram", 18);
Student3 s2 = new Student3("Shyam",22);
Student3 s3 = new Student3("Mohan",19);
2.Stream.sorted返回一个由这个流的元素组成的流,根据提供的比较器进行排序。
list.stream().sorted(ageComp).forEach(System.out::println);
list.stream().sorted(nameComp).forEach(System.out::println);
3.Collections.sort根据给定的比较器实例对指定的列表进行排序。
Collections.sort(list, ageComp);
list.forEach(System.out::println);
Collections.sort(list, nameComp);
list.forEach(System.out::println);
4.list.sort返回一个由这个流的元素组成的流,根据提供的比较器进行排序。
list.sort(ageComp);
list.forEach(System.out::println);
list.sort(nameComp);
list.forEach(System.out::println);
4.Arrays.sort根据指定比较器产生的顺序对指定的对象数组进行排序。
Student3[] array = {s1, s2, s3};
Arrays.sort(array, ageComp);
for (Student3 s : array) {System.out.println(s);}
Arrays.sort(array, nameComp);
for (Student3 s : array) {System.out.println(s);}
5.reversed是Java比较器功能接口的默认方法。reversed返回一个比较器,该比较器强制执行反向排序。
Collections.sort(list, nameComp.reversed());
list.forEach(System.out::println);
6.reverseOrder是一个静态方法,返回比较器,对对象集合进行反向自然排序。
Collections.sort(list, Comparator.reverseOrder());
list.forEach(System.out::println);
7.naturalOrder方法返回一个比较器,该比较器以自然顺序比较可比较的对象。
List<Integer> numList = Arrays.asList(12, 10, 15, 8, 11);
Collections.sort(numList, Comparator.naturalOrder());
numList.forEach(System.out::println);
List<String> strList = Arrays.asList("Varanasi", "Allahabad", "Kanpur", "Noida");
strList.sort(Comparator.naturalOrder());
strList.forEach(System.out::println);
8.nullsFirst方法返回一个对null友好的比较器,它认为null小于非null。
(1)空元素被认为是小于非空元素的。
(2)当两个元素都是空的时候,那么它们就被认为是相等的。
(3)当两个元素都是非空的时候,指定的比较器决定了顺序。
(4)如果指定的比较器是空的,那么返回的比较器认为所有非空的元素是相等的。
List<Student3> list = Arrays.asList(s1, s2, null, s3);
Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student3::getName)));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student3::getName)));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student3::getName).reversed()));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Student3::getName)).reversed());
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsFirst(Comparator.naturalOrder()));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsFirst(null));
list.forEach(System.out::println);
9.nullsLast方法返回一个对null友好的比较器,认为null大于非null。
(1)空元素被认为是大于非空元素的。
(2)当两个元素都是空的时候,那么它们就被认为是相等的。
(3)当两个元素都是非空的时候,指定的比较器决定了顺序。
(4)如果指定的比较器是空的,那么返回的比较器认为所有非空的元素是相等的。
List<Student3> list = Arrays.asList(s1, s2, null, s3);
Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student3::getName)));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student3::getName)));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student3::getName).reversed()));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Student3::getName)).reversed());
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsLast(Comparator.naturalOrder()));
list.forEach(System.out::println);
list = Arrays.asList(s1, null, s2, null, s3);
Collections.sort(list, Comparator.nullsLast(null));
list.forEach(System.out::println);
10.comparing接受一个函数,该函数从给定的类型中提取一个可比较的排序键,并返回一个通过该排序键进行比较的比较器。
Collections.sort(list, Comparator.comparing(Student3::getName));
list.forEach(System.out::println);
Collections.sort(list, Comparator.comparing(Student3::getName, (s1, s2) -> s2.compareTo(s1)));
list.forEach(System.out::println);
10.comparingInt它接受一个从类型T中提取一个int排序键的函数,并返回一个通过该排序键进行比较的比较器。。
Collections.sort(list, Comparator.comparingInt(Student3::getAge));
list.forEach(s->System.out.print(s.getAge() + " "));
11.comparingLong它接受一个从类型T中提取一个long排序键的函数,并返回一个通过该排序键进行比较的比较器。。
Collections.sort(list, Comparator.comparingLong(Student3::getHomeDistance));
list.forEach(s->System.out.print(s.getHomeDistance() + " "));
12.comparingDouble它接受一个从类型T中提取一个double排序键的函数,并返回一个通过该排序键进行比较的比较器。。
Collections.sort(list, Comparator.comparingDouble(Student3::getWeight));
list.forEach(s->System.out.print(s.getWeight() + " "));
13.thenComparingInt它返回一个词表顺序(lexicographic-order)比较器,其中包含一个提取int排序键的函数。找到例子。
Comparator<Student3> comparing = Comparator.comparing(Student3::getName, (s1, s2) -> s1.charAt(0) - s2.charAt(0));
Comparator<Student3> comparator = comparing.thenComparingInt(Student3::getAge);
Collections.sort(list, comparator);
list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()));
14.thenComparingLong它返回一个词表顺序(lexicographic-order)比较器,其中包含一个提取long排序键的函数。找到例子。
Comparator<Student3> comparator = comparing.thenComparingLong(Student3::getHomeDistance);
Collections.sort(list, comparator);
list.forEach(s->System.out.println(s.getName() + "-" + s.getHomeDistance()));
15.thenComparingDouble它返回一个词表顺序(lexicographic-order)比较器,其中包含一个提取double排序键的函数。找到例子。
Comparator<Student3> comparator = comparing.thenComparingDouble(Student3::getWeight);
Collections.sort(list, comparator);
list.forEach(s->System.out.println(s.getName() + "-" + s.getWeight()));
16.返回一个词表顺序(lexicographic-order)的比较器,该比较器被一个比较器实例调用,使用一组排序键对项目进行排序。
System.out.println("--------Example-1---------");
Comparator<Student3> compByStdName = Comparator.comparing(Student3::getName);
Comparator<Student3> schoolComparator1 = Comparator.comparing(Student3::getAge)
.thenComparing(compByStdName);
Collections.sort(list, schoolComparator1);
list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()));
System.out.println("--------Example-2---------");
Comparator<Student3> schoolComparator2 = Comparator.comparing(Student3::getSchool)
.thenComparing(Student3::getAge).thenComparing(Student3::getName);
Collections.sort(list, schoolComparator2);
list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()+ "-" + s.getSchool().getCity()));
System.out.println("--------Example-3---------");
Comparator<Student3> schoolComparator3 = Comparator.comparing(Student3::getSchool)
.thenComparing(Student3::getSchool, (school1, school2) -> school1.getSname().compareTo(school2.getSname()))
.thenComparing(Student3::getAge).thenComparing(Student3::getName);
Collections.sort(list, schoolComparator3);
list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()+ "-" + s.getSchool().getSname() + "-" + s.getSchool().getCity()));
17.在SortedSet使用比较器TreeSet根据元素的自然排序,或者通过在集合创建时提供的比较器对元素进行排序,这取决于使用哪个构造函数。
System.out.println("---TreeSet Order With Comparator---");
Comparator<Student3> ageComparator = Comparator.comparing(Student3::getAge);
TreeSet<Student3> myTreeSet = new TreeSet<>(ageComparator);
myTreeSet.addAll(Arrays.asList(s1, s2, s3));
myTreeSet.forEach(s -> System.out.println(s));
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));
18.在SortedSet使用比较器ConcurrentSkipListSet根据元素的自然排序或在集合创建时提供的比较器来排序,这取决于使用哪种构造函数。
System.out.println("---ConcurrentSkipListSet Order With Comparator---");
Comparator<Student3> ageComparator = Comparator.comparing(Student3::getAge);
ConcurrentSkipListSet<Student3> myConcurrentSkipList = new ConcurrentSkipListSet<>(ageComparator);
myConcurrentSkipList.addAll(Arrays.asList(s1, s2, s3));
myConcurrentSkipList.forEach(s -> System.out.println(s));
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));
19.在SortedMap使用比较器TreeMap根据其键的自然排序或在Map创建时提供的比较器进行排序,这取决于使用哪个构造函数。
System.out.println("---TreeMap Order With Comparator---");
Comparator<Student3> ageComparator = Comparator.comparing(Student3::getAge);
TreeMap<Student3, 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("---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));
20.在SortedMap使用比较器ConcurrentSkipListMap根据其键的自然排序,或者根据Map创建时提供的比较器进行排序,这取决于使用哪个构造函数。
System.out.println("---ConcurrentSkipListMap Order With Comparator---");
Comparator<Student3> ageComparator = Comparator.comparing(Student3::getAge);
ConcurrentSkipListMap<Student3, 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("---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));