常见的接口与类 -- 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的主要内容,如果未能解决你的问题,请参考以下文章
集合排序: Comparator和Comparable的使用区别
Comparable,Comparator,Clonable 接口使用剖析