Comparator接口的使用 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;

* @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接口需要另外定义一个类,作为比较器,比较复杂,但实现不需要对原代码修改,只需要另外定义比较规则的类即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值