本文共 5733 字,大约阅读时间需要 19 分钟。
Comparable & Comparator 都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。
Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种情况:
将对象Student 按照名字排序; (Comparable的泛型未必就一定要是Student,可以是任何自己定义的规则 )
public class Student implements Comparable{ private String name; public Student(String name) { super(); this.name = name; } @Override public int compareTo(Student o) { if (this.name.compareTo(o.name) > 0) { return 1; } else if (this.name.compareTo(o.name) == 0) { return 0; } else { return -1; } } public static void main(String[] args) { Student student1 = new Student("a"); Student student2 = new Student("c"); Student student3 = new Student("f"); System.out.println(student2.compareTo(student1)); System.out.println(student2.compareTo(student3)); }}
Comparator可以认为是是一个外比较器,用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
1、一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较
2、一个对象实现了Comparable接口,但是开发者想要自定义比较规则;
Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:
package package1;import java.util.Comparator;public class StudentComparator implements Comparator{ @Override public int compare(Student o1, Student o2) { // TODO Auto-generated method stub return o1.getAge()-o2.getAge()==0?0:(o1.getAge()-o2.getAge()>1?1:-1); } public static void main(String[] args) { StudentComparator studentComparator = new StudentComparator(); Student s1 = new Student ("e",12); Student s2 = new Student ("f",15); System.out.println(studentComparator.compare(s1, s2)); }}
总结一下,两种比较器Comparable和Comparator,后者相比前者有如下优点:
1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法.
2、实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator 接口的方式后面会写到就是一种典型的策略模式。
Comparable 源码
package java.lang;import java.util.*;public interface Comparable{ public int compareTo(T o);}
Comparator源码 :
package java.util;import java.io.Serializable;import java.util.function.Function;import java.util.function.ToIntFunction;import java.util.function.ToLongFunction;import java.util.function.ToDoubleFunction;import java.util.Comparators;@FunctionalInterfacepublic interface Comparator{ int compare(T o1, T o2); boolean equals(Object obj); default Comparator reversed() { return Collections.reverseOrder(this); } default Comparator thenComparing(Comparator other) { Objects.requireNonNull(other); return (Comparator & Serializable) (c1, c2) -> { int res = compare(c1, c2); return (res != 0) ? res : other.compare(c1, c2); }; } default Comparator thenComparing( Function keyExtractor, Comparator keyComparator) { return thenComparing(comparing(keyExtractor, keyComparator)); } default > Comparator thenComparing( Function keyExtractor) { return thenComparing(comparing(keyExtractor)); } default Comparator thenComparingInt(ToIntFunction keyExtractor) { return thenComparing(comparingInt(keyExtractor)); } default Comparator thenComparingLong(ToLongFunction keyExtractor) { return thenComparing(comparingLong(keyExtractor)); } default Comparator thenComparingDouble(ToDoubleFunction keyExtractor) { return thenComparing(comparingDouble(keyExtractor)); } public static > Comparator reverseOrder() { return Collections.reverseOrder(); } @SuppressWarnings("unchecked") public static > Comparator naturalOrder() { return (Comparator ) Comparators.NaturalOrderComparator.INSTANCE; } public static Comparator nullsFirst(Comparator comparator) { return new Comparators.NullComparator<>(true, comparator); } public static Comparator nullsLast(Comparator comparator) { return new Comparators.NullComparator<>(false, comparator); } public static Comparator comparing( Function keyExtractor, Comparator keyComparator) { Objects.requireNonNull(keyExtractor); Objects.requireNonNull(keyComparator); return (Comparator & Serializable) (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1), keyExtractor.apply(c2)); } public static > Comparator comparing( Function keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); } public static Comparator comparingInt(ToIntFunction keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2)); } public static Comparator comparingLong(ToLongFunction keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2)); } public static Comparator comparingDouble(ToDoubleFunction keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2)); }}
转载地址:http://qawji.baihongyu.com/