转载地址:https://blog.csdn.net/u012250875/article/details/55126531
该接口代表一个比较器,比较器具有可比性!大多数文章都写如何用 comparator 排序,是因为 javase 数组工具类和集合工具类中提供的 sort 方法 sort 就是使用Comparator 接口来处理排序的,大家见久了都认为 Comparator 接口是用来排序的,按照 java 抽象的尿性来看,该接口如果为排序而生,应该叫 Sortable,Sortor 之类的名字吧!下面是 javase 一些使用到Comparator接口的地方:
Arrays.sort(T[],Comparator super T> c);
Collections.sort(List list,Comparator super T> c);
什么场景需要做比较,那么什么场景就是 Comparator 接口的用武之地,我总结的两个场景:
1. 排序
在 List 或数组中的对象如果没有实现 Comparable 接口时,那么就需要调用者为需要排序的数组或 List 设置一个 Compartor,Compartor 的 compare 方法用来告诉代码应该怎么去比较两个实例,然后根据比较结果进行排序
package com.java.demo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @author puyf
*/
public class SortTest {
class Dog{
public int age;
public String name;
public Dog(int age, String name) {
super();
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Dog [age=" + age + ", name=" + name + "]";
}
}
public static void main(String[] args) {
List list= new ArrayList<>();
list.add(new SortTest().new Dog(5, "DogA"));
list.add(new SortTest().new Dog(6, "DogB"));
list.add(new SortTest().new Dog(7, "DogC"));
Collections.sort(list, new Comparator() {
@Override
public int compare(Dog o1, Dog o2) {
return o2.age - o1.age;
}
});
System.out.println("给狗狗按照年龄倒序:"+list);
Collections.sort(list, new Comparator() {
@Override
public int compare(Dog o1, Dog o2) {
return o1.name.compareTo(o2.name);
}
});
System.out.println("给狗狗按名字字母顺序排序:"+list);
}
}
2. 分组
使用 Comparator 和 for 循环处理列表,来进行分类;通过调用者实现 Comparator 接口的比较逻辑,来告诉程序应该怎么比较,通过比较之后得结果来进行分组。比如生活中的拳击比赛,会有公斤级的概念,那么程序中应该实现的处理逻辑是只要两个人的体重在同一个区间则为同一组公斤级的选手。下面例子中分别按照狗狗的颜色和体重级别两个维度来进行分组,因此分组的核心逻辑其实就是比较逻辑。相面我抽了一个工具方法:dividerList ,第一个参数为需要处理的数据源,第二参数是分组时的比较逻辑。
package com.java.demo;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* @author puyf
*/
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 + "]";
}
}
/**
* @author puyf
* @Description:按条件分组
* @param datas
* @param c
* 是否为同一组的判断标准
* @return
*/
public static List> divider(Collection datas, Comparator super T> c) {
List> result = new ArrayList>();
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 innerList = new ArrayList();
result.add(innerList);
innerList.add(t);
}
}
return result;
}
public static void main(String[] args) {
List 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> byColors = divider(list, new Comparator() {
@Override
public int compare(Apple o1, Apple o2) {
// 按颜色分组
return o1.color.compareTo(o2.color);
}
});
System.out.println("按颜色分组" + byColors);
List> byWeight = divider(list, new Comparator() {
@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]
]
]