Comparable:
是集合内部的方法实现的排序,只有一个方法
public interface Comparable{public intcompareTo(T o);
}
对于String和一些基本数据类型,默认实现了Comparable 接口,实现了compareTo方法,可以直接使用。
public final classStringimplements java.io.Serializable, Comparable, CharSequence {public intcompareTo(String anotherString) {int len1 =value.length;int len2 =anotherString.value.length;int lim =Math.min(len1, len2);char v1[] =value;char v2[] =anotherString.value;int k = 0;while (k
}
k++;
}return len1 -len2;
}
}public final class Integer extends Number implements Comparable{public intcompareTo(Integer anotherInteger) {return compare(this.value, anotherInteger.value);
}
}
使用场景:
同一个类的两个对象相互比较,类内部的比较
可以进行排序,但是一定要实现Comparable,否则出现异常
Collections.sort()和Arrays.sort()内部都有应用
使用样例:
@Slf4j
@Data
@AllArgsConstructorpublic class TestUnit implements Comparable{privateString name;privateInteger age;
@Overridepublic intcompareTo(TestUnit o) {return this.age.compareTo(o.age);
}public static voidmain(String[] args) {
List list = new ArrayList();
list.add(new TestUnit("a",2));
list.add(new TestUnit("b",1));
list.add(new TestUnit("c",3));
System.out.println(list);
Collections.sort(list);
System.out.println(list);
TestUnit unit = new TestUnit("a", 1);
TestUnit unit1 = new TestUnit("b", 2);
System.out.println(unit.compareTo(unit1));
} }
结果:
[TestUnit(name=a, age=2), TestUnit(name=b, age=1), TestUnit(name=c, age=3)]
[TestUnit(name=b, age=1), TestUnit(name=a, age=2), TestUnit(name=c, age=3)]
-1
Comparator:
是集合外部的方法实现的排序,多个方法
public interface Comparator{intcompare(T o1, T o2);public static Comparator comparingInt(ToIntFunction super T>keyExtractor) {
Objects.requireNonNull(keyExtractor);return (Comparator &Serializable)
(c1, c2)->Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}
}
使用场景:
Comparator接口代码更加灵活,可以定义某个类的多个比较器,以满足不用的需求,而不改变对象自身,而用一个策略对象来改变对象的比较
行为(策略模式)。
使用样例:
@Slf4j
@Data
@AllArgsConstructor
@NoArgsConstructorpublic class TestUnit implements Comparator{privateString name;privateInteger age;public static voidmain(String[] args) {
List list = new ArrayList();
list.add(new TestUnit("a",2));
list.add(new TestUnit("b",1));
list.add(new TestUnit("c",3));
System.out.println(list);
Collections.sort(list,newTestUnit());
System.out.println(list);
TestUnit unit= new TestUnit("a", 1);
TestUnit unit1= new TestUnit("b", 2);
System.out.println(unit.compare(unit, unit1));;
}
@Overridepublic intcompare(TestUnit o1, TestUnit o2) {return o1.age -o2.age;
}
}
结果:
[TestUnit(name=a, age=2), TestUnit(name=b, age=1), TestUnit(name=c, age=3)]
[TestUnit(name=b, age=1), TestUnit(name=a, age=2), TestUnit(name=c, age=3)]-1
注意事项:
无论是Comparable还是Comparator实现类在重写compareTo、compare方法时,一般要求compare(o1,o2))==0的逻辑结果要和o1.equals(o2)
保持一致。
总结:
(1)如果比较的方法只用在一个类中,则该类实现Comparable接口就可以
(2)如果比较的方法在很多类中需要用到,就自己写个类实现Comparator接口,实现松耦合
(3)在用Collections类的sort方法排序时,若不指定Comparator,那就以自然顺序排序(自然顺序就是实现Comparable接口设定的排序方式)