博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【java】Comparator的用法
阅读量:6936 次
发布时间:2019-06-27

本文共 5019 字,大约阅读时间需要 16 分钟。

文章转载自:

1.为什么写?

  1. comparator 是javase中的接口,位于java.util包下,javase中的所有接口抽象度都很高,有必要重视
  2. 网上太多的文章告诉大家comparator是用来排序;确实,可以用来排序,但不仅限于排序
  3. 工作中实际需求出现很多需要使用comparator去处理的问题,在此总结一下。

2.接口功能

该接口的功能表示一个比较器,比较器当然具有可比性!那为什么一百度全是说是用来排序的?这是因为数组工具类和集合工具类中提供的工具方法sort方法都给出了含有Comparator接口的重载方法,大家见久了都只想到Comparator接口是用来排序的,按照java抽象的尿性来看,该接口如果为排序而生,我估计应该叫类似Sortable,Sortor之类的名字吧!下面是javase中该接口的使用原型:

1 Arrays.sort(T[],Comparator
c);2 Collections.sort(List
list,Comparator
c);

 

3.使用场景

考虑什么场景使用该接口就需要考虑什么时候需要比较,比较常用的场景:

1. 排序需要比较,需要比较两个对象谁在前谁在后。
2. 分组需要比较,需要比较两个对象是否是属于同一组。
3. 待补充

4.举个栗子

1.排序

在List或数组中的对象如果没有实现Comparable接口时,那么就需要调用者为需要排序的数组或List设置一个Compartor,Compartor的compare方法用来告诉代码应该怎么去比较两个实例,然后根据比较结果进行排序

talk is cheap show me the code

1 package com.java.demo; 2  3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.List; 7 /** 8  * @author puyf 9  */10 public class SortTest {11     class Dog{12     public int age;13     public String name;14     public Dog(int age, String name) {15         super();16         this.age = age;17         this.name = name;18     }19     @Override20     public String toString() {21         return "Dog [age=" + age + ", name=" + name + "]";22     }23     }24     public static void main(String[] args) {25     List
list= new ArrayList<>();26 list.add(new SortTest().new Dog(5, "DogA"));27 list.add(new SortTest().new Dog(6, "DogB"));28 list.add(new SortTest().new Dog(7, "DogC"));29 Collections.sort(list, new Comparator
() {30 31 @Override32 public int compare(Dog o1, Dog o2) {33 return o2.age - o1.age;34 }35 });36 System.out.println("给狗狗按照年龄倒序:"+list);37 Collections.sort(list, new Comparator
() {38 39 @Override40 public int compare(Dog o1, Dog o2) {41 return o1.name.compareTo(o2.name);42 }43 });44 System.out.println("给狗狗按名字字母顺序排序:"+list);45 }46 }

 

2.分组

使用Comparator和for循环处理列表,来进行分类;通过调用者实现Comparator接口的比较逻辑,来告诉程序应该怎么比较,通过比较之后得结果来进行分组。比如生活中的拳击比赛,会有公斤级的概念,那么程序中应该实现的处理逻辑是只要两个人的体重在同一个区间则为同一组公斤级的选手。下面例子中分别按照狗狗的颜色和体重级别两个维度来进行分组,因此分组的核心逻辑其实就是比较逻辑。相面我抽了一个工具方法:dividerList,第一个参数为需要处理的数据源,第二参数是分组时的比较逻辑。

1 package com.java.demo; 2  3 import java.util.ArrayList; 4 import java.util.Comparator; 5 import java.util.List; 6 /** 7  * @author puyf 8  */ 9 public class GroupTest {10     class Apple {11     public String color;12     public int weight;13 14     public Apple(String color, int weight) {15         super();16         this.color = color;17         this.weight = weight;18     }19 20     @Override21     public String toString() {22         return "Apple [color=" + color + ", weight=" + weight + "]";23     }24     }25 26     /**27      * @param list 28      * @param comparator 比较是否为同一组的比较器29      * @return30      */31     public static 
List
> dividerList(List
list,Comparator
comparator) {32 List
> lists = new ArrayList<>();33 for (int i = 0; i < list.size(); i++) {34 boolean isContain = false;35 for (int j = 0; j < lists.size(); j++) {36 if (lists.get(j).size() == 037 ||comparator.compare(lists.get(j).get(0), list.get(i)) == 0) {38 lists.get(j).add(list.get(i));39 isContain = true;40 break;41 }42 }43 if (!isContain) {44 List
newList = new ArrayList<>();45 newList.add(list.get(i));46 lists.add(newList);47 }48 }49 return lists;50 }51 52 public static void main(String[] args) {53 List
list = new ArrayList<>();54 list.add(new GroupTest().new Apple("红", 205));55 list.add(new GroupTest().new Apple("红", 131));56 list.add(new GroupTest().new Apple("绿", 248));57 list.add(new GroupTest().new Apple("绿", 153));58 list.add(new GroupTest().new Apple("黄", 119));59 list.add(new GroupTest().new Apple("黄", 224));60 List
> byColors = dividerList(list, new Comparator
() {61 62 @Override63 public int compare(Apple o1, Apple o2) {64 // 按颜色分组65 return o1.color.compareTo(o2.color);66 }67 });68 System.out.println("按颜色分组" + byColors);69 List
> byWeight = dividerList(list, new Comparator
() {70 71 @Override72 public int compare(Apple o1, Apple o2) {73 // 按重量级74 75 return (o1.weight / 100 == o2.weight / 100) ? 0 : 1;76 }77 });78 System.out.println("按重量级分组" + byWeight);79 }80 }

结果如下(为了方便看,手动回车换行格式化了下):

按颜色分组
[
[
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]
]
]

5.总结

一般需要做比较的逻辑都可以使用的上Comparator,最常用的场景就是排序和分组,排序常使用Arrays和Collections的sort方法,而分组则可以使用上面提供的dividerList方法。

排序和分组的区别在于:

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

转载于:https://www.cnblogs.com/huaixiaonian/p/7508452.html

你可能感兴趣的文章
Caliburn.Micro 关闭父窗体打开子窗体
查看>>
powershell实现离线ip扫描
查看>>
Fragment使用findFragmentById返回null
查看>>
Logger日志级别说明及设置方法、说明
查看>>
SPOJ PGCD(莫比乌斯反演)
查看>>
oracle常用命令入门
查看>>
关于MFC程序快捷键失效的问题
查看>>
bzoj 1965 数学
查看>>
链接静态库的顺序问题
查看>>
for(;;){}循环语句
查看>>
利用edtftpj组件实现FTP文件的上传。
查看>>
csuoj1009
查看>>
为app添加动态gif背景
查看>>
括号配对问题1
查看>>
Xamarin开发Android笔记:TextView行间距设定
查看>>
div间的小红点,可能是BOM头,利用ultraedit另存为UTF-8无BOM即可
查看>>
如何利用altera 给出的megafunction配置成自己想要的FIFO和RAM ——本文为转载
查看>>
熟悉常用的Linux操作
查看>>
如何用java实现数据脱敏
查看>>
html5 本地存储有多少种方案:
查看>>