comparator 是javase中的接口,位于java.util包下,该接口抽象度极高,有必要掌握该接口的使用,排序是comparator能实现的功能之一,他不仅限于排序,还有分组
接口功能:
该接口代表一个比较器,比较器具有可比性!大多数文章都写如何用comparator排序,是因为javase数组工具类和集合工具类中提供的sort方法sort就是使用Comparator接口来处理排序的
Arrays.sort(T[],Comparator<? super T> c); Collections.sort(List<T> list,Comparator<? super T> c);
使用场景:
1.排序,需要比较两个对象谁排在前谁排在后(排序也可以让类实现Comparable接口,实现后该类的实例也具有排序能力)。
2.分组,需要比较两个对象是否是属于同一组。
举例说明:
排序
通过实现Comparator接口,定义需要排序的字段
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * 实现Comparator 的排序功能 * @author gcc * * 2018年3月6日 */ public class TestComparator { 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<Dog> list= new ArrayList<>(); list.add(new TestComparator().new Dog(8, "DogA")); list.add(new TestComparator().new Dog(6, "DogB")); list.add(new TestComparator().new Dog(7, "DogC")); //按年龄排序 Collections.sort(list,new TestComparator().new SortDogAge()); System.out.println("给狗狗按照年龄倒序:"+list); //按姓名排序 Collections.sort(list,new TestComparator().new SortDogName()); System.out.println("给狗狗按名字字母顺序排序:"+list); } /** * 按照年龄排序 * @author gcc * * 2018年3月6日 */ class SortDogAge implements Comparator<Dog>{ @Override public int compare(Dog o1, Dog o2) { return o1.age-o2.age; } } /** * 按照名字排序 * @author gcc * * 2018年3月6日 */ class SortDogName implements Comparator<Dog>{ @Override public int compare(Dog o1, Dog o2) { return o1.name.compareTo(o2.name); } } }
分组
使用Comparator和for循环处理列表,来进行分类;通过调用者实现Comparator接口的比较逻辑,来告诉程序应该怎么比较,通过比较之后得结果来进行分组。比如生活中的拳击比赛,会有公斤级的概念,那么程序中应该实现的处理逻辑是只要两个人的体重在同一个区间则为同一组公斤级的选手。下面例子中分别按照狗狗的颜色和体重级别两个维度来进行分组,因此分组的核心逻辑其实就是比较逻辑。相面我抽了一个工具方法:dividerList,第一个参数为需要处理的数据源,第二参数是分组时的比较逻辑。
import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; import com.gcc.interview.TestComparator.Dog; /** * 分组 * @author gcc * * 2018年3月6日 */ public class GroupTest implements Divider{ 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 <T> List<List<T>> divider(Collection<T> datas,Comparator<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; } /** * 按照颜色分组 * @author gcc * * 2018年3月6日 */ class SortAppleColor implements Comparator<Apple>{ @Override public int compare(Apple o1, Apple o2) { // TODO Auto-generated method stub return o1.color.compareTo(o2.color); } } /** * 按照重量分组 * @author gcc * * 2018年3月6日 */ class SortAppleWeight implements Comparator<Apple>{ @Override public int compare(Apple o1, Apple o2) { return o1.weight-o2.weight; } } public static void main(String[] args) { GroupTest test = new GroupTest(); 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 = test.divider(list,new GroupTest().new SortAppleColor()); System.out.println("按颜色分组" + byColors); List<List<Apple>> byWeights = test.divider(list,new GroupTest().new SortAppleColor()); System.out.println("按重量分组" + byWeights); } }