Java Comparator
原文:(130条消息) 【Java 8 新特性】Java Comparator | 比较器_猫巳的博客-CSDN博客_javacomparator
比较器的功能方法:Compare(T o1,T o2)
compare是比较器接口的功能方法。
使用Lambda表达式定义compare
1 2 3
| Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge(); Comparator<Student> nameComp = (s1, s2) -> s1.getName().compareTo(s2.getName());
|
实例:
1 2 3
| Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge(); list.sort(ageComp); list.forEach(s -> System.out.println(s));
|
自定义compare实现比较器(定制排序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| 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)); } }
|
在实现比较器接口的同时实现Serializable
是一个很好的做法,因为它们可能被用作可序列化数据结构(如TreeSet
和TreeMap
)的排序方法。
什么时候选择定制排序
Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。
个人认为有两种情况可以使用实现Comparator接口的方式:
- 对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较(大都是这种情况);
- 对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式;
- 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
- 还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
比较器的使用
我们可以用Stream.sorted
、Collections.sort
、List.sort
和Arrays.sort
方法来使用我们的比较器。
Stream.sorted
功能说明:以自然序或着自定义Comparator
接口排序规则来排序一个流。
1 2
| Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge(); list.stream().sorted(ageComp).forEach(s -> System.out.println(s));
|
Collections.sort
Collections是一个工具类,该集合中的Student对象必须实现Comparable接口(强制),然后实现它的compareTo方法,否则编译器会报错。sort是其中的静态方法,是用来对List类型进行排序的,它有两种参数形式:
1 2 3
| Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge(); Collections.sort(list, ageComp); list.forEach(s -> System.out.println(s));
|
List.sort
1 2 3
| Comparator<Student> ageComp = (s1, s2) -> s1.getAge() - s2.getAge(); list.sort(ageComp); list.forEach(s -> System.out.println(s));
|
比较器的方法
reversed
reversed是Java比较器功能接口的默认方法。reversed返回一个比较器,该比较器==强制执行反向排序==。
1 2 3
| Comparator<Student> nameComparator = (s1, s2) -> s1.getName().compareTo(s2.getName()); Collections.sort(list, nameComparator.reversed());
|
reverseOrder
1 2 3 4 5
| List<String> strList = Arrays.asList("Varanasi", "Allahabad", "Kanpur", "Noida"); Collections.sort(strList, Comparator.reverseOrder()); strList.forEach(s -> System.out.print(s + " ")); System.out.println("\n-----------");
|
naturalOrder
Comparator.naturalOrder
方法返回一个比较器,该比较器以自然顺序比较可比较的对象。
1 2 3
| List<Student> stdList = Student.getStudentList(); stdList.sort(Comparator.naturalOrder()); stdList.forEach(s -> System.out.print(s.getName() + " "));
|
nullsFirst
- 空元素被认为是小于非空元素的。
- 当两个元素都是空的时候,那么它们就被认为是相等的。
- 当两个元素都是非空的时候,指定的比较器决定了顺序。
- 如果指定的比较器是空的,那么返回的比较器认为所有非空的元素是相等的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| 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)); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| -------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
|