Java基础(八): Comparable和Comparator接口梳理

x33g5p2x  于2021-09-23 转载在 Java  
字(3.1k)|赞(0)|评价(0)|浏览(326)

1、Comparable

1.1、源码

Comparable接口在JDK8中的源码:

public interface Comparable<T> {
    public int compareTo(T o);
}

1.2、用法

@Data
@AllArgsConstructor
public class User implements Comparable<User>{

    private int id;
    private int age;

    @Override
    public int compareTo(User o) {
        if( this.age > o.age){
            return 1;
        }else if(this.age < o.age){
            return -1;
        }else{
            return 0;
        }
    }

    public static void main(String[] args) {
        User user1 = new User(1, 14);
        User user2 = new User(2, 12);
        User user3 = new User(3, 10);
        User[] users = {user1, user2, user3};
        Arrays.sort(users);
        System.out.println(Arrays.toString(users));
        //[User(id=3, age=10), User(id=2, age=12), User(id=1, age=14)]
    }
}

1.3、原理:

int compareTo(T o)

比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

参数: o - 要比较的对象。

返回:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。

抛出:ClassCastException - 如果指定对象的类型不允许它与此对象进行比较

2、Comparator

2.1、源码

Comparable接口在JDK8中的源码:

@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 Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) 
   {
        return thenComparing(comparingInt(keyExtractor));
    }

   ...
    }
}

2.2、用法1

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserComparator implements Comparator<UserComparator> {

    private Integer id;
    private Integer age;

    @Override
    public int compare(UserComparator o1, UserComparator o2) {
        if(o1.getAge() > o2.getAge()) {
            return 1;
        } else if(o1.getAge() < o2.getAge()){
            return -1;
        }else
            return 0;
    }

    public static void main(String[] args) {
        UserComparator u1 = new UserComparator(1, 14);
        UserComparator u2 = new UserComparator(2, 12);
        UserComparator u3 = new UserComparator(3, 10);

        List<UserComparator> list = new ArrayList<UserComparator>();
        list.add(u1);
        list.add(u2);
        list.add(u3);

        Collections.sort(list,new UserComparator());
        System.out.println(list.toString());
        //[User(id=3, age=10), User(id=2, age=12), User(id=1, age=14)]
    }

2.3、用法2

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserComparator2 {

    private Integer id;
    private Integer age;

    public static void main(String[] args) {
        UserComparator u1 = new UserComparator(1, 14);
        UserComparator u2 = new UserComparator(2, 12);
        UserComparator u3 = new UserComparator(3, 10);

        List<UserComparator> list = new ArrayList<UserComparator>();
        list.add(u1);
        list.add(u2);
        list.add(u3);

        Collections.sort(list, (o1,o2) -> (o1.getAge()-o2.getAge()));
        list.stream().forEach(System.out::println);
        //UserComparator(id=3, age=10)
        //UserComparator(id=2, age=12)
        //UserComparator(id=1, age=14)
    }
}

2.4、Comparator接口其他默认方法的用法

reversed方法

default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }

3、总结

  • Comparable接口位于java.lang包下;
  • Comparator位于java.util包下
  • Comparable接口只提供了一个compareTo()方法;
  • Comparator接口不仅提供了compara()方法,还提供了其他默认方法,如reversed()、thenComparing(),使我们可以按照更多的方式进行排序
  • 如果要用Comparable接口,则必须实现这个接口,并重写comparaTo()方法;
  • Comparator接口可以在类外部使用,通过将该接口的一个匿名类对象当做参数传递给Collections.sort()方法或者Arrays.sort()方法实现排序。
  • Comparator体现了一种策略模式,即可以不用要把比较方法嵌入到类中,而是可以单独在类外部使用,这样我们就可有不用改变类本身的代码而实现对类对象进行排序。

参考:Comparable接口和Comparator接口的使用和区别_IT_10的博客-CSDN博客

相关文章