【java】Comparator的用法

时间:2023-02-15 20:16:01

文章转载自: http://blog.csdn.net/u012250875/article/details/55126531

1.为什么写?

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

2.接口功能

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

 Arrays.sort(T[],Comparator<? super T> c);
Collections.sort(List<T> list,Comparator<? super T> c);

3.使用场景

考虑什么场景使用该接口就需要考虑什么时候需要比较,比较常用的场景:
1. 排序需要比较,需要比较两个对象谁在前谁在后。
2. 分组需要比较,需要比较两个对象是否是属于同一组。
3. 待补充

4.举个栗子

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

talk is cheap show me the code

 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<Dog> 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<Dog>() { @Override
public int compare(Dog o1, Dog o2) {
return o2.age - o1.age;
}
});
System.out.println("给狗狗按照年龄倒序:"+list);
Collections.sort(list, new Comparator<Dog>() { @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 + "]";
}
} /**
* @param list
* @param comparator 比较是否为同一组的比较器
* @return
*/
public static <T> List<List<T>> dividerList(List<T> list,Comparator<? super T> comparator) {
List<List<T>> lists = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
boolean isContain = false;
for (int j = 0; j < lists.size(); j++) {
if (lists.get(j).size() == 0
||comparator.compare(lists.get(j).get(0), list.get(i)) == 0) {
lists.get(j).add(list.get(i));
isContain = true;
break;
}
}
if (!isContain) {
List<T> newList = new ArrayList<>();
newList.add(list.get(i));
lists.add(newList);
}
}
return lists;
} 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 = dividerList(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 = dividerList(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]
]
]

5.总结

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

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

【java】Comparator的用法的更多相关文章

  1. 关于comparable与comparator的用法(即自定义集合框架用法 )

    package javastudy; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; ...

  2. JAVA的continue用法

    JAVA的continue用法: public class test{ public static void main(String [] args){  for(int i=0;i<=10;i ...

  3. Java Spring AOP用法

    Java Spring AOP用法 Spring AOP Java web 环境搭建 Java web 项目搭建 Java Spring IOC用法 spring提供了两个核心功能,一个是IoC(控制 ...

  4. Java Spring IOC用法

    Java Spring IOC用法 Spring IoC 在前两篇文章中,我们讲了java web环境搭建 和 java web项目搭建,现在看下spring ioc在java中的运用,开发工具为In ...

  5. 四种Java线程池用法解析

    本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...

  6. JAVA中ArrayList用法

    JAVA中ArrayList用法 2011-07-20 15:02:03|  分类: 计算机专业 |  标签:java  arraylist用法  |举报|字号 订阅     Java学习过程中做题时 ...

  7. this在java中的用法

    this在java中的用法 1.使用this关键字引用成员变量 作用:解决成员变量与参数或局部变量命名冲突的问题 public class Dog { String name; public Dog( ...

  8. java assert的用法简介【转】

    assert的基本用法 assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制,如C,C++和Eiffel等,但是支持的形式不尽相同,有的是通过语言本身.有的是通过库 ...

  9. java Arrays&period;asList用法

    java Arrays.asList用法 用途 Arrays是java容器相关操作的工具类,asList方法将Array转换为list,是Array和List之间的桥梁. 注意 Arrays.asLi ...

  10. Java自学基础用法

    在慕课上面简单学习了一下java语言的用法 简单的用法总结记录一下. 代码(学习输入,输出): package hello; import java.util.Scanner; public clas ...

随机推荐

  1. Java读写文本文件

    1 字符输入(FileReader , char) import java.io.IOException; import java.io.FileReader; public class ep10_1 ...

  2. 如何复制DataRow(dataTabel中的行)

    由于需要对dataTabel中的行进行上移和下移操作: row 1      行号0 row2       行号1 row3       行号2 例如将row3上移一行,即row2和row3对调位置. ...

  3. BZOJ 1221&colon; &lbrack;HNOI2001&rsqb; 软件开发&lpar;最小费用最大流&rpar;

    不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...

  4. apue chapter 4 文件和目录

    1.文件信息结构体 struct stat{ mode_t st_mode; //file type and permissions ino_t st_ino; //i-node number (se ...

  5. tvtk管线技术、数据集与数据加载

    管线技术也称流水线技术(Pipeline)每个对象只实现相对简单的任务,整个管线进行复杂的可视化处理在tvtk中分为可视化管线和图形管线 可视化管线(Visualization Pipeline):将 ...

  6. delphi使用sqlite数据库时的中文路径问题

    https://blog.csdn.net/yuehaiyang/article/details/4184198 如果数据库所在的路径是中文路径的话,根本运行不起来,会报错,因为sqlite用的是ut ...

  7. &lbrack;leetcode&period;com&rsqb;算法题目 - Pascal&&num;39&semi;s Triangle

    Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Retur ...

  8. 20155308『网络对抗技术』Exp5 MSF基础应用

    20155308『网络对抗技术』Exp5 MSF基础应用 一.原理与实践说明 实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻击实 ...

  9. Linux内核设计(第一周)——从汇编语言出发理解计算机工作原理

    Linux内核设计(第一周)——从汇编语言出发理解计算机工作原理 计算机工作原理 汇编指令 C语言代码汇编分析 by苏正生 原创作品转载请注明出处 <Linux内核分析>MOOC课程htt ...

  10. python2&period;7中可以使用到的一些模块地址

    1.reportlab:由很多部分组成且允许用户使用多种方法创建输出,地址: 下载ReportLab https://pypi.python.org/simple/reportlab/ http:// ...