美文网首页Java 杂谈Java学习笔记
认识一下Comparator和Comparable

认识一下Comparator和Comparable

作者: 邮差在行动 | 来源:发表于2018-04-17 13:35 被阅读1次

    先从表面上来看

    1. 功能上都是用来排序
    2. Comparator是在java.util包下,Comparable是在java.lang包下。
    3. Comparable和Comparator都是接口,Comparable下只有一个int compareTo(Object o1)方法,Comparator下有多个方法,比如int compare(Object o1, Object o2)
    4. compareTo和compare这两个方法都是返回int(1,0,-1三个值)

    实现了排序功能的集合

    1. java.util.Collection.sort(List)java.util.Arrays.sort(Object[])自然顺序(natural order)来实现集合和数组的排序。【注:这里面的对象必须实现Comparable接口
    2. java.util.Collections.sort(List, Comparator)java.util.Arrays.sort(Object[], Comparator)可以指定Comparator来排序。

    举例

    基础类型排序(Sort an array/list of primitive type)

    int[] ints = {11,2,44,5,12};
    Arrays.sort(ints);
    System.out.println(Arrays.toString(ints));
    
    List<Integer> integers = new ArrayList<>();
    integers.add(12);
    integers.add(32);
    integers.add(5);
    integers.add(3);
    integers.add(42);
    Collections.sort(integers);
    System.out.println(integers);
    

    输出结果:

    [2, 5, 11, 12, 44]
    [3, 5, 12, 32, 42]
    

    对String数组、集合排序

    List<String> strList = new ArrayList<>();
    strList.add("123");
    strList.add("abc");
    strList.add("eee");
    strList.add("1w2");
    Collections.sort(strList);
    System.out.println(strList);
    
    String[] strs =  {"1r","e2","1q","2","f2"};
    Arrays.sort(strs);
    System.out.println(Arrays.toString(strs));
    

    输出结果:

    [123, 1w2, abc, eee]
    [1q, 1r, 2, e2, f2]
    

    对自定义对象排序

    自定义一个User类

    public class User {
        private int id;
        private String name;
        private String email;
        public User(int id, String name, String email) {
            super();
            this.id = id;
            this.name = name;
            this.email = email;
        }
        public User() {
            super();
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + ", email=" + email + "]";
        }
        //omit the setter and getter
    }
    

    对这个对象的数组、集合排序

    List<User> userList = new ArrayList<>();
    userList.add(new User(10,"na","a@a.com"));
    userList.add(new User(21,"bna","ba@a.com"));
    userList.add(new User(15,"cna","ca@a.com"));
    
    Collections.sort(userList);
    

    如果排序方法是 Collections.sort(userList),就会报编译错误:
    The method sort(List<T>) in the type Collections is not applicable for the arguments (List<User>)

    那该怎么办呢?

    有2种解决办法:
    1)自己指定比较器
    Collections.sort(userList, Comparator.comparing(User::getId));
    2)让User实现Comparable接口

    public class User implements Comparable<User>{
        //..............omit 
        
        @Override
        public int compareTo(User o) {
            return Integer.compare(this.getId(), o.getId());
        }
    }
    

    这样再使用Collections.sort(userList)就可以了。

    实际应用

    在实际情况中,如果我们定义的对象需要用于比较,而且要比较的字段很多时,我们可以让这个类实现Comparable接口,然后再调用不同的比较器(Comparator)。
    举例:

    private static final Comparator<User> IDCOMPARATOR = Comparator.comparing(User::getId);
    private static final Comparator<User> IDNameCOMPARATOR = Comparator.comparing(User::getId).thenComparing(User::getName);
    private static final Comparator<User> NameCOMPARATOR = Comparator.comparing(User::getName);
    private static final Comparator<User> NameCOMPARATORReversed = Comparator.comparing(User::getId).reversed();
    private static final Comparator<User> IDNameEmailCOMPARATOR = Comparator.comparing(User::getId).thenComparing(User::getName).thenComparing(User::getEmail);
        
    @Override
    public int compareTo(User o) {
        return IDNameEmailCOMPARATOR.compare(this, o);
        //return Integer.compare(this.getId(), o.getId());
    }
    

    其中compareTo方法可以指定你实际最常用的比较方式。
    如果有特殊需要,可以在调用sort方法时指定你的比较器:Collections.sort(userList, NameCOMPARATOR);

    相关文章

      网友评论

        本文标题:认识一下Comparator和Comparable

        本文链接:https://www.haomeiwen.com/subject/udwukftx.html