Comparator 和 Comparable的区别

2020-02-26  本文已影响0人  shengjk1

1.位置
Comparable 位于 java.lang,我们都知道 java.lang包可以说是 java体系中基础包,有 ClassLoader、Class、Object、基本类型等
Comparator 位于 java.util,也就是 java 自带的类库,包括一些常用的集合类、strem、function

所以从这个角度来说,Comparator 也属于类库的一种就是为了方便开发,而 Comparable 就很重要了,整个 java 体系中的基础类而不是仅仅为了开发方便。

2.描述
Comparable: This interface imposes a total ordering on the objects of each class that implements it.
可以通过 Collections.sort()、Arrays.sort() 方法进行排序,若某对象实现了 Comparable 则该对象的 SortedMap 、SortSet 会自动对对象进行排序,并不需要 Comparator 对其进行手动排序。

Comparator: A comparison function, which imposes a total ordering on some collection of objects.
Comparator可以对非已经排好序的进行排序,而且还可以对已经有顺序的SortedMap、SortSet 进行排序。

3.使用

public class ComparatorTextList {
    public static void main(String[] args) {
        List<User> userlist = new ArrayList<User>();
        User user1 = new User("Y - 易小星 ", 31);
        User user2 = new User("W - 王大锤", 33);
        userlist.add(user1);
        userlist.add(user2);
        //更偏向于对一系列的对象,需要手动对对象进行排序
        Comparator<User> cmp = new ComparatorUser();
        Collections.sort(userlist, cmp);
        for (User user : userlist) {
            System.out.println(user.getName());
        }
        
        System.out.println("hsahSet=====");
        HashSet<User> users = new HashSet<>();
        users.add(user1);
        users.add(user2);
        for (User user : users) {
            System.out.println(user.getName());
        }
        System.out.println("treeSet=====");

        //实现了 Comparable 接口,对于有序集合是自动排序的。但让也可以通过 Comparator 对其进行排序
        TreeSet<User> treeSet = new TreeSet<>();
        treeSet.addAll(users);
        for (User user : treeSet) {
            System.out.println(user.getName());
        }
        //实现了 Comparable 接口,它可以与相应的类对象进行比较
        System.out.println(user2.compareTo(user1));
    }
}

//也需要遵循 the general contract,建议实现 Serializable 接口
class ComparatorUser implements Comparator<User> {
    @Override
    public int compare(User u1, User u2) {
        // 先按年龄排序
        int flag = u1.getAge().compareTo(u2.getAge());
        // 年龄相等比较姓名
        if (flag == 0) {
            return u1.getName().compareTo(u2.getName());
        } else {
            return flag;
        }
    }
}

class User implements Comparable<User> {
    private String name;
    private Integer age;
    
    public User() {
        super();
    }
    
    public User(String name, Integer age) {
        super();
        this.name = name;
        this.age = 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;
    }
    
    @Override
    public int compareTo(@NotNull User user) {
        // 先按年龄排序
        int flag = this.age.compareTo(user.getAge());
        // 年龄相等比较姓名
        if (flag == 0) {
            return this.getName().compareTo(user.getName());
        } else {
            return flag;
        }
    }
    
    //最好是重写一下 equals 方法,防止两个类对象相同而 equals 不同,不满足 Object 的约束
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(name, user.name) &&
                Objects.equals(age, user.age);
    }
    
    //同理的,重写 equals 方法,一般都需要重写 hashCode 方法,这样才能保证,equals 相等的两个对象的 hashCode 也相同,
    // 满足 Object 约束
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读