我在学习java8过程中,看到了对象比较使用了多种方式,感觉有必要总结一下。
1. comparator接口与Comparable接口的区别
有的文章这样解释二者的区别,Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。现在通过一个例子,就能明白什么是内部比较器,外部比较器了。
//Comparable 定义在 Person类的内部:
public class Persion implements Comparable {
@Override
public int compareTo(Person p)
{
....
}
}
//Comparator 定义在 Person类的外部:
public class Persion{
...
}
public PersonComparator implements Comparator() {
@Override
public int compare(Person one, Person another) {
{
....
}
}
Comparable:直接用Collections.sort(personList)进行排序
Comparator:Collections.sort( personList, new PersonComparator()) 可以对其排序
2. java8 Comparator接口
@FunctionalInterface
public interface Comparator<T> {
// 核心方法,用来比较两个对象,如果o1小于o2,返回负数;等于o2,返回0;大于o2返回正数
int compare(T o1, T o2);
// 好像很少用到,一般都用对象自带的equals
boolean equals(Object obj);
/**-----------下面的都是JDK1.8新增的接口,挑几个放进去----------*/
//返回反向排序比较器
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
//根据名字知道,先进行compare比较后,再进行一次比较
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);
};
}
//对int类型的key进行比较
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 extends Comparable<? super T>> Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
}
2.1 JDK1.8以前的用法
Collections.sort(books,new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
// TODO Auto-generated method stub
return o1.getBookPrice() - o2.getBookPrice();
}
});
}
或者创建一个比较器
package com.my.test.compare;
import java.util.Comparator;
public class SimpleCompator implements Comparator<Book> {
@Override
public int compare(Book o1, Book o2) {
// TODO Auto-generated method stub
return o1.getBookPrice() -o2.getBookPrice();
}
}
Collections.sort(books,new SimpleCompator());
JDK1.8以前的用法要自己手动实现Comparator接口,然后调用Collections.sort(),传入实现类来完成排序,非常麻烦。
2.2 JDK1.8的用法
Collections.sort(books,(Book a, Book b) -> { return a.getBookPrice()-b.getBookPrice(); });
或者可以简单的写为
Collections.sort(books,(Book a, Book b) -> a.getBookPrice()-b.getBookPrice());
甚至,我们可以不使用Collections.sort:
books.sort((Book a, Book b) -> a.getBookPrice()-b.getBookPrice() );
2.3 更多例子
Optional<String> min = servers.stream
.collect(Collectors.minBy(Comparator.comparingInt(String::length)));
apples.sort(Comparator.comparing(Apple::getColor));
apples.sort((a1, a2) -> a1.getColor().compareTo(a2.getColor()));
Double minResult = test.binaryOperatorMinBy(100.0, 150.0, Double::compareTo);
personList.stream().sorted(Comparator.comparing((Person::getAge).thenComparing(Person::getId())).collect(Collectors.toList()) //先按年龄从小到大排序,年龄相同再按id从小到大排序