• Comparable接口和Comparator接口的使用和区别


    转载于:https://blog.csdn.net/IT_10/article/details/104747173

    Comparable

    Comparable接口在JDK8中的源码:

    package java.lang;
    import java.util.*;
    
    package java.lang;
    public interface Comparable<T> {
        public int compareTo(T o);
    }
    

    用法:

    public class User implements Comparable<User>{
        private Integer id;
        private Integer age;
    
        public User() {
        }
    
        public User(Integer id, Integer age) {
            this.id = id;
            this.age = age;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", age=" + age +
                    '}';
        }
    
        public int compareTo(User o) {
            if(this.age > o.getAge()) {
                return 1;
            }else if(this.age < o.getAge()) {
                return -1;
            }else{
                return 0;
            }
        }
    }
    
    public class Test {
        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);
            Arrays.stream(users).forEach(System.out::println);
        }
    }
    

    int compareTo(T o)

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

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

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

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

    Comparator

    Comparator接口在JDK8中的源码:

    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;
    
    public interface Comparator<T> {
    	int compare(T o1, T o2);
    	//还有很多其他方法...
    }
    

    使用:

    public class Child {
        private Integer id;
        private Integer age;
    
        public Child() {
        }
    
        public Child(Integer id, Integer age) {
            this.id = id;
            this.age = age;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Child{" +
                    "id=" + id +
                    ", age=" + age +
                    '}';
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Child child1 = new Child(1, 14);
            Child child2 = new Child(2, 12);
            Child child3 = new Child(3, 10);
    
            List<Child> list = new ArrayList<>();
            list.add(child1);
            list.add(child2);
            list.add(child3);
    
            Collections.sort(list, new Comparator<Child>() {
                @Override
                public int compare(Child o1, Child o2) {
                    return  o1.getAge() > o2.getAge() ? 1 : (o1.getAge() == o2.getAge() ? 0 : -1);
                }
            });
    
            // 或者使用JDK8中的Lambda表达式
            //Collections.sort(list, (o1, o2) -> (o1.getAge()-o2.getAge()));
    
            list.stream().forEach(System.out::println);
        }
    }
    

    或者也可以通过实现的方式使用Comparator接口:

    import java.util.Comparator;
    
    public class Child implements Comparator<Child> {
        private Integer id;
        private Integer age;
    
        public Child() {
        }
    
        public Child(Integer id, Integer age) {
            this.id = id;
            this.age = age;
        }
    
        @Override
        public int compare(Child o1, Child o2) {
            return o1.getAge() > o2.getAge() ? 1 : (o1.getAge() == o2.getAge() ? 0 : -1);
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Child{" +
                    "id=" + id +
                    ", age=" + age +
                    '}';
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Child child1 = new Child(1, 14);
            Child child2 = new Child(2, 12);
            Child child3 = new Child(3, 10);
    
            List<Child> list = new ArrayList<>();
            list.add(child1);
            list.add(child2);
            list.add(child3);
            
            Collections.sort(list, new Child());
            list.stream().forEach(System.out::println);
        }
    }
    

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

    reversed方法

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

    这个方法是用来生成一个逆序器,比如我们开始需要得到一个正序的排序序列,然后又想得到一个反转的排序序列,就可以使用该方法。比如:

    public class Test {
        public static void main(String[] args) {
            Child child1 = new Child(1, 14);
            Child child2 = new Child(2, 12);
            Child child3 = new Child(5, 10);
            Child child4 = new Child(4, 10);
    
            List<Child> list = new ArrayList<>();
            list.add(child1);
            list.add(child2);
            list.add(child3);
            list.add(child4);
    
            Comparator<Child> comparator = Comparator.comparingInt(x -> x.getAge());
            Collections.sort(list, comparator);
            list.stream().forEach(System.out::println);
            Collections.sort(list, comparator.reversed());
            list.stream().forEach(System.out::println);
        }
    }
    

    thenComparing

    default <U extends Comparable<? super U>> Comparator<T> thenComparing(
                Function<? super T, ? extends U> keyExtractor)
        {
            return thenComparing(comparing(keyExtractor));
        }
    

    该方法是在原有的比较器上再加入一个比较器,比如先按照年龄排序,年龄相同的在按照id排序。比如:

    public class Test {
        public static void main(String[] args) {
            Child child1 = new Child(1, 14);
            Child child2 = new Child(2, 12);
            Child child3 = new Child(5, 10);
            Child child4 = new Child(4, 10);
    
            List<Child> list = new ArrayList<>();
            list.add(child1);
            list.add(child2);
            list.add(child3);
            list.add(child4);
    
            Comparator<Child> comparator = Comparator.comparingInt(x -> x.getAge());
            Collections.sort(list, comparator);
            list.stream().forEach(System.out::println);
            System.out.println("-----");
            Collections.sort(list, comparator.thenComparing(x->x.getId()));
            list.stream().forEach(System.out::println);
        }
    }
    

    Comparable接口和Comparator接口的区别

    • Comparable接口位于java.lang包下;Comparator位于java.util包下
    • Comparable接口只提供了一个compareTo()方法;Comparator接口不仅提供了compara()方法,还提供了其他默认方法,如reversed()、thenComparing(),使我们可以按照更多的方式进行排序
    • 如果要用Comparable接口,则必须实现这个接口,并重写comparaTo()方法;但是Comparator接口可以在类外部使用,通过将该接口的一个匿名类对象当做参数传递给Collections.sort()方法或者Arrays.sort()方法实现排序。Comparator体现了一种策略模式,即可以不用要把比较方法嵌入到类中,而是可以单独在类外部使用,这样我们就可有不用改变类本身的代码而实现对类对象进行排序。
  • 相关阅读:
    【zZ】OpenCV HOGDescriptor 参数图解
    [C]遍历目录下所有文件
    drawing
    转:基于用户投票的排名算法系列
    编码格式
    泛型
    接口
    隐藏方法不能实现多态性
    结构
    静态
  • 原文地址:https://www.cnblogs.com/gkgkgk/p/13618951.html
Copyright © 2020-2023  润新知