常见的接口与类 -- Comparator

Posted 当康

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常见的接口与类 -- Comparator相关的知识,希望对你有一定的参考价值。

Comparable和Comparator

Java提供了一个用于比较的接口Comparable,实际上Java中还提供了一个接口Comparator,该接口也具有比较的功能,其更注重的是比较容器,然后对其排序。

  • Comparable在java.lang包中,它是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”,其相当于“内部比较器”。
  • Comparator在java.util包中,它是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序,其相当于“外部比较器”。

两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。

使用场景

  • 排序
    需要比较两个对象谁排在前谁排在后
  • 分组
    需要比较两个对象是否是属于同一组

接口方法

作为接口Comparator提供了两个抽象方法:

返回值 方法
int compare(T o1, T o2) 比较用来排序的两个参数
boolean equals(Object obj) 指示某个其他对象是否“等于”此 Comparator

Compare() 比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
Compare() 方法大于0,就把前一个数和后一个数交换,即所谓的升序。

类实现此接口时,只需要实现compare方法,因为Java中类都继承于Object类,而Object类默认实现了equals方法,所以不需要必须去实现equals方法。

实践操作

排序时,两个对象比较的结果有三种:大于,等于,小于。
分组时,两个对象比较的结果只有两种:等于(两个对象属于同一组),不等于(两个对象属于不同组)。

排序

    public static void main(String[] args){
        Lc452_findMinArrowShots lc452_findMinArrowShots = new Lc452_findMinArrowShots();
        int[][] points = {{10,16},{2,8},{1,6},{7,12}};
        Arrays.sort(points, new Comparator<int[]>() {
            public int compare(int[] point1, int[] point2) {
                if (point1[1] > point2[1]) {
                    return 1;
                } else if (point1[1] < point2[1]) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        for(int[] arr:points){
            System.out.println(Arrays.toString(arr));
        }
    }

结果:

[1, 6]
[2, 8]
[7, 12]
[10, 16]

分组

public class GroupTest {
    class Apple {
    public String color;
    public int weight;

    public Apple(String color, int weight) {
        super();
        this.color = color;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Apple [color=" + color + ", weight=" + weight + "]";
    }
    }

    public static <T> List<List<T>> divider(Collection<T> datas, Comparator<? super T> c) {
        List<List<T>> result = new ArrayList<List<T>>();
        for (T t : datas) {
            boolean isSameGroup = false;
            for (int j = 0; j < result.size(); j++) {
                if (c.compare(t, result.get(j).get(0)) == 0) {
                    isSameGroup = true;
                    result.get(j).add(t);
                    break;
                }
            }
            if (!isSameGroup) {
                // 创建
                List<T> innerList = new ArrayList<T>();
                result.add(innerList);
                innerList.add(t);
            }
        }
        return result;
    }

    public static void main(String[] args) {
    List<Apple> list = new ArrayList<>();
    list.add(new GroupTest().new Apple("红", 205));
    list.add(new GroupTest().new Apple("红", 131));
    list.add(new GroupTest().new Apple("绿", 248));
    list.add(new GroupTest().new Apple("绿", 153));
    list.add(new GroupTest().new Apple("黄", 119));
    list.add(new GroupTest().new Apple("黄", 224));
    List<List<Apple>> byColors = divider(list, new Comparator<Apple>() {

        @Override
        public int compare(Apple o1, Apple o2) {
        // 按颜色分组
        return o1.color.compareTo(o2.color);
        }
    });
    System.out.println("按颜色分组" + byColors);
    List<List<Apple>> byWeight = divider(list, new Comparator<Apple>() {

        @Override
        public int compare(Apple o1, Apple o2) {
        // 按重量级

        return (o1.weight / 100 == o2.weight / 100) ? 0 : 1;
        }
    });
    System.out.println("按重量级分组" + byWeight);
    }
}

结果:

// 按颜色分组
[
[Apple [color=红, weight=205],Apple [color=红, weight=131]],
[Apple [color=绿, weight=248],Apple [color=绿, weight=153]],
[Apple [color=黄, weight=119],Apple [color=黄, weight=224]]
]

//按重量级分组
[
[Apple [color=红, weight=205],Apple [color=绿, weight=248],Apple [color=黄, weight=224]],
[Apple [color=红, weight=131],Apple [color=绿, weight=153],Apple [color=黄, weight=119]]
]

以上是关于常见的接口与类 -- Comparator的主要内容,如果未能解决你的问题,请参考以下文章

常见的接口与类 -- Comparable

集合排序: Comparator和Comparable的使用区别

关于Comparable和Comparator那些事

Comparable,Comparator,Clonable 接口使用剖析

Comparable,Comparator,Clonable 接口使用剖析

Comparable,Comparator,Clonable 接口使用剖析