首先:我们先来看一波源码!!!
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;
* @author Josh Bloch
* @author Neal Gafter
* @see Comparable
* @see java.io.Serializable
* @since 1.2
*/
@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));
}
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();
}
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);
}
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的源码,我们可以看到Comparator接口包含很多方法,但是真正需要我们实现的只有第一第二个
int compare(T o1, T o2);
boolean equals(Object obj);
但是equals方法是从基类Object继承的。有默认的实现。
所以真的需要我们实现的 只有方法
int compare(T o1, T o2);
下面我们就来学习Comparator接口的具体用法
我们先定义一个简单的Person类
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person() {
}
private Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.util.*;
public class PersonComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
public static void main(String[] args) {
Person[] array=new Person[5];
array[0]=new Person("张三",75);
array[1]=new Person("李四",28);
array[2]=new Person("王二麻子",18);
array[3]=new Person("陈九斤",37);
array[4]=new Person("陆有钱",5);
Arrays.sort(array,new PersonComparator());
System.out.println(Arrays.toString(array));
}
}
当然如果我们觉得 定制排序还需要 另外定义一个类作为比较器,很麻烦,本人就觉得很麻烦!
我们可以使用匿名实现类,从而不需要再另外定义一个类。
写法如下:
import java.util.Arrays;
import java.util.Comparator;
public class PersonTest {
public static void main(String[] args) {
Person[] array = new Person[5];
array[0] = new Person("张三", 75);
array[1] = new Person("李四", 28);
array[2] = new Person("王二麻子", 18);
array[3] = new Person("陈九斤", 37);
array[4] = new Person("陆有钱", 5);
Arrays.sort(array, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
}
);
System.out.println(Arrays.toString(array));
}
}
自然排序和定制排序的异同点:
自然排序:需要进行排序的类实现Comparable接口,并且重写compareTo方法,compareTo方法只有一个参数。
定制排序:需要在需要排序的类之外再定义一个类实现Comparator接口,并且重写compare方法,compare方法有两个参数。
相同点:compareTo和compare方法返回值都是int类型,并且方法内部比较的两个对象,大于返回正数,小于则返回负数,如果相等则返回0.
优缺点:
自然排序实现Comparable接口比较简单,不需要另外定义一个比较器类,但要修改进行比较类的原有代码。定制排序实现Comparator接口需要另外定义一个类,作为比较器,比较复杂,但实现不需要对原代码修改,只需要另外定义比较规则的类即可。