用TreeSet和Comparator给list集合元素去重
今天在做导入功能时,看到一个感觉很好的去重算法,特分享给大家看看:
其原理利用了以下几点:
1.TreeSet里面不会有重复的元素,所以当把一个List放进TreeSet里面后,会自动去重
2.TreeSet去重也是有条件的,它依靠放入其中的元素的排序规则,所以放入其中的元素要有一个自定义的排序规则(此处表述不是很清楚,欢迎指正)
下面开始看好戏:
原本List<Person> persons 里面有3个元素:
List<Person> persons = new ArrayList<Person>();
Person p1 = new Person("a",10,100);
Person p2 = new Person("a",10,100);
Person p3 = new Person("b",10,100);
persons.add(p1);
persons.add(p2);
persons.add(p3);
它们中person1和person2元素相同,但是对于对象来说,它们是不同的元素,所以现在我要把它们去重,只保留一个,怎么搞?
也许有人说遍历,比较,这样自然也可以,但是当元素很多很多时,或者字段非常多时,那比较久非常麻烦了,因为涉及到foreach循环和字段的筛选.
编程不就是为了让一切更简单嘛,所以我们不用那种原始方法,我们用现成的简单方法,jdk给我们提供的TreeSet和Comparator搭配,特别适合做这种"比较"的事.
首先我们回顾一下思路:把List放进一个设定好比较规则的TreeSet中.
如下:
public static ArrayList<Person> removeDuplicated(List<Person> persons){
//1.创建一个带比较规则的set,这里使用匿名内部类创建了一个比较器
Set<Person> set = new TreeSet(new Comparator<Person>() {
public int compare(Person o1, Person o2) {
int a = o1.getName().compareTo(o2.getName());//比较name的自然顺序,0表示相同
int b = o1.getAge().compareTo(o2.getAge());//比较age的自然顺序,0表示相同
if(a==0 && b==0){
return 0;//如果name和age同时都相同,则返回0,0表示Person对象是相同的
}else{
return 1;
}
}
});
//2.将list放进Set中,自动去重
set.addAll(persons);
//3.将去重后的集合set再放进一个新的list中返回
return new ArrayList<Person>(set);
}
测试:
System.out.println(persons);
ArrayList<Person> newPersons = removeDuplicated(persons);
System.out.println(newPersons); 结果:
[Person{name='a', age=10, height=100}, Person{name='a', age=10, height=100}, Person{name='b', age=10, height=100}]
[Person{name='a', age=10, height=100}, Person{name='b', age=10, height=100}]
扩展:
以上是去除list中完全一样的元素,大家有没有发现,Person有三个字段,但我比较的时候却只使用了两个,为什么没使用第三个?
有意思的就在这里,因为你可以随心所欲去决定:只要对象的某些特征相同,我就可以判它们是相同对象,感受到了吗?
所以你可以通过更改比较规则,去翻云覆雨,去一手遮天地决定:比 ! 较 ! 规 ! 则 !
注意点:new Comparator<>()时一定要加泛型
用TreeSet和Comparator给list集合元素去重的更多相关文章
- List集合对象去重及按属性去重的8种方法-java基础总结系列第六篇
最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大.基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华.所以我更想把java ...
- 【转载】C#中通过Distinct方法对List集合进行去重
在C#的List集合对象中,可以使用Distinct方法来对List集合元素进行去重,如果list集合内部元素为值类型,则Distinct方法根据值类型是否相等来判断去重,如果List集合内部元素为引 ...
- Java学习笔记--集合元素的比较Comparable,Comparator
原文见: http://www.cnblogs.com/sunflower627/p/3158042.html 1. Comparator 和 Comparable 相同的地方 他们都是java的一个 ...
- TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树
TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树 本文链接:https://blog.csdn.net/u010698072/article/de ...
- TreeSet和Comparator 对TreeSet排序
使用TreeSet和Comparator,编写TreeSetTestInner类,要求对TreeSet中的元素"HashSet"."ArrayList".&qu ...
- TreeMap和TreeSet在排序时如何比较元素,Collections工具类中的sort()方法如何比较元素
TreeSet和TreeMap排序时比较元素要求元素对象必须实现Comparable接口 Collections的sort方法比较元素有两种方法: 元素对象实现Comparable接口 实体类Dog ...
- Map / Set / Treeset 取出指定下标index的元素
Treeset 属于 set 集合中的一种数据类型,HashSet 以及LinkedHashSet 原理相同 需求:想直接在Treeset类型下,取出指定下标的元素,但是Set 下没有 get()方 ...
- struts2指定集合元素的泛型
public class LoginAction implements Action{ private List users; public void setUsers(List users){ th ...
- 当JAVA集合移除自身集合元素时发生的诸多问题
一段代码目的是想删除集合中包括"a"字符串的集合项: public class TestForeach { public static void main(String[] arg ...
随机推荐
- icpc2018-焦作-F Honeycomb bfs
http://codeforces.com/gym/102028/problem/F 就是一个bfs,主要问题是建图,要注意奇数和偶数列的联通方案是略有不同的.比赛的时候写完一直不过样例最后才发现没考 ...
- 关于IDEA每次修改HTML,Css等静态资源文件都需要重启的设置修改
~ ~ ~ ~ ~ 关于IDEA每次修改HTML,Css等静态资源文件都需要重启的设置修改 最近开始使用IDEA进行项目开发,但是对于每次修改HTML文件中css和js文件之后都必须重启服务这件事表示 ...
- js验证银行卡号 luhn校验规则
<script type="text/javascript"> //luhn校验规则:16位银行卡号(19位通用): // 1.将未带校验位的 15(或18)位卡号从右 ...
- Redis缓存设计及常见问题
Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使 用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的 ...
- Starting MySQL....The server quit without updating PID file[失败]/lib/mysql/ip12189.pid). 错误一例
[root@ip12189 etc]# service mysqld startStarting MySQL....The server quit without updating PID file[ ...
- python批量插入mysql数据库(性能相关)以及反引号的使用
参考link: https://blog.csdn.net/qq_35958094/article/details/78462800(插入相关) https://www.cnblogs.com/hya ...
- NPOI 操作excel之 将图片插入到指定位置;
//新建类 重写Npoi流方法 public class NpoiMemoryStream : MemoryStream { public NpoiMemoryStream() { AllowClos ...
- SQL-46 在audit表上创建外键约束,其emp_no对应employees_test表的主键id。
题目描述 在audit表上创建外键约束,其emp_no对应employees_test表的主键id.CREATE TABLE employees_test(ID INT PRIMARY KEY NOT ...
- Costura.Fody合并DLL和EXE
1.打开Nuget包管理器 2. 输入 Install-Package Costura.Fody -Version 3.3.0 3.之后Costura.Fody会嵌入到工程中,如果没有手动添加一下 4 ...
- windows 安装mysql 5.7的正确姿势
1.首先上MySql的官网下载 https://dev.mysql.com/downloads/mysql/ 2. 以我所选版本为例(免安装版),选择MYSQL Community Server 然 ...