zoukankan      html  css  js  c++  java
  • Comparable与Comparator

    Comparable & Comparator 都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

    1.Comparable 接口:

    Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种情况:

    • 比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数
    • 比较者等于被比较者,那么返回0
    • 比较者小于被比较者,那么返回负整数

    实例:

    将对象Student 按照名字排序; (Comparable的泛型未必就一定要是Student,可以是任何自己定义的规则 )

    
    public class Student implements Comparable<Student> {
        private String name;
    
        public Student(String name) {
            super();
            this.name = name;
        }
    
        @Override
        public int compareTo(Student o) {
            if (this.name.compareTo(o.name) > 0) {
                return 1;
            } else if (this.name.compareTo(o.name) == 0) {
                return 0;
            } else {
                return -1;
            }
    
        }
    
        public static void main(String[] args) {
            Student student1 = new Student("a");
            Student student2 = new Student("c");
            Student student3 = new Student("f");
            System.out.println(student2.compareTo(student1));
            System.out.println(student2.compareTo(student3));
    
        }
    
    }
    

    2.Comparator接口:

    Comparator可以认为是是一个外比较器,用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。

    1、一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较

    2、一个对象实现了Comparable接口,但是开发者想要自定义比较规则;

    Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:

    • o1大于o2,返回正整数;
    • o1等于o2,返回0;
    • o1小于o2,返回负整数;

    实例:

    package package1;
    
    import java.util.Comparator;
    
    public class StudentComparator implements Comparator<Student>{
    
        @Override
        public int compare(Student o1, Student o2) {
            // TODO Auto-generated method stub
            return o1.getAge()-o2.getAge()==0?0:(o1.getAge()-o2.getAge()>1?1:-1);
        }
        public static void main(String[] args) {
            StudentComparator studentComparator = new StudentComparator();
            Student s1 = new Student ("e",12);
            Student s2 = new Student ("f",15);
            System.out.println(studentComparator.compare(s1, s2));
        }
    }
    

    总结一下,两种比较器Comparable和Comparator,后者相比前者有如下优点:

    1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法.

    2、实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator 接口的方式后面会写到就是一种典型的策略模式。

    源码

    Comparable 源码

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

    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;
    
    
    @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();
        }
    
        @SuppressWarnings("unchecked")
        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));
        }
    }
    
  • 相关阅读:
    Selenium入门15 截图
    selenium入门14 窗口切换
    Locust的官网及安装
    命令行输入Jmeter提示不是内部或外部命令,处理方式:添加环境变量
    python pip安装报错python setup.py egg_info failed with error code 1
    Selenium入门13 cookie的增删改查
    Selenium入门12 鼠标和键盘事件
    Selenium入门11 滚动条控制(通过js)
    Selenium入门10 弹出框的处理 switch_to.alert
    Selenium入门9 上传文件
  • 原文地址:https://www.cnblogs.com/DiZhang/p/12544959.html
Copyright © 2011-2022 走看看