版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Pengjx2014/article/details/82529965
Comparable使用
Comparable只是一个简单的接口,
public interface Comparable<T> {
public int compareTo(T o);
}
使用如下:
public class Person implements Comparable<Person> {
int age;
String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
@Override
public String toString() {
return "age=" + age + ", name='" + name;
}
public static void main(String[] args) {
List<Person> list = Arrays.asList(new Person[]{new Person(23, "Merry"),
new Person(18, "Jack"),
new Person(25, "Lx")});
Collections.sort(list);
System.out.println(list.toString());
}
}
Comparator源码如下
Comparator在Java8中是一个函数式接口,除去原始的jdk7中保留的equals
和compare
方法,还添加了部分针对java8函数式编程添加的default
和static
方法。
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
/**
* 返回一个倒序比较器
*/
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
/**
* 返回二次比较器
*/
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
/**
* 根据给定的关键字抽取函数返回二次比较器
*/
default <U> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> keyComparator)
{
return thenComparing(comparing(keyExtractor, keyComparator));
}
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor)
{
return thenComparing(comparing(keyExtractor));
}
/**
* 根据整形关键字抽取起返回二次比较器
*
*/
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
return thenComparing(comparingInt(keyExtractor));
}
/**
* Returns a lexicographic-order comparator with a function that
* extracts a {@code long} sort key.
*/
default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
return thenComparing(comparingLong(keyExtractor));
}
default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
return thenComparing(comparingDouble(keyExtractor));
}
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
/**
* 返回非空的比较器
*/
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
return new Comparators.NullComparator<>(true, comparator);
}
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
return new Comparators.NullComparator<>(false, comparator);
}
/**
* Accepts a function that extracts a sort key from a type {@code T}, and
* returns a {@code Comparator<T>} that compares by that sort key using
*/
public static <T, U> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> keyComparator)
{
Objects.requireNonNull(keyExtractor);
Objects.requireNonNull(keyComparator);
return (Comparator<T> & Serializable)
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
keyExtractor.apply(c2));
}
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}
public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
}
public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
}
}
Comparator使用方式如下
对一个学生列表,实现按照年龄顺序,成绩倒序的排序,实现如下:
public class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
@Data
public class Student {
String name;
int age;
double score;
public Student(String name, int age, float score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}'+"\n";
}
public static void main(String[] args) {
List<Student> list = Arrays.asList(new Student[]{new Student("lx", 27, 99.5f),
new Student("xs", 26, 89.5f),
new Student("mj", 25, 92.5f),
new Student("lx2", 27, 79.5f),
new Student("xs2", 26, 79.5f),
new Student("mj2", 25, 62.5f)}
);
//二次排序采用传入Lamda表达式的方式
Collections.sort(list, new StudentComparator().thenComparing((s1,s2)->(int)(s2.score-s2.score)));
System.out.println(list.toString());
}
}
执行结果如下:
[Student{name='mj', age=25, score=92.5}
, Student{name='mj2', age=25, score=62.5}
, Student{name='xs', age=26, score=89.5}
, Student{name='xs2', age=26, score=79.5}
, Student{name='lx', age=27, score=99.5}
, Student{name='lx2', age=27, score=79.5}
]
Comparator与Comparable的比较
相同点
- 都是用于比较两个对象“顺序”的接口
- 都可以使用Collections.sort()方法来对对象集合进行排序
不同点
- Comparable位于java.lang包下,而Comparator则位于java.util包下
- Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序
- 使用Comparable接口来实现对象之间的比较时,可以使这个类型(设为A)实现Comparable接口,并可以使用Collections.sort()方法来对A类型的List进行排序,之后可以通过a1.comparaTo(a2)来比较两个对象;
当使用Comparator接口来实现对象之间的比较时,只需要创建一个实现Comparator接口的比较器(设为AComparator),并将其传给Collections.sort()方法即可对A类型的List进行排序,之后也可以通过调用比较器AComparator.compare(a1, a2)来比较两个对象。例如上面的二次排序问题;
可以说一个是自己完成比较,一个是外部程序实现比较的差别而已。用Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。