用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 ...
随机推荐
- express+mockjs实现模拟后台数据发送
前言: 大多数时候,前端会和后端同时进行开发,即在我们开发完页面的时候,很可能还不能立马进入联调阶段,这个时候,为了保证我们接口的有效性和代码的功能完整,我们可能需要模拟数据. 模拟数据方法 1.通过 ...
- Matlab:高阶常微分三种边界条件的特殊解法(中心差分法,高精度导数边界处理)
函数文件1: function b=F(f,x0,h,N) % b(1,1)=x0(1)-h*x0(2)-u(1); % b(2,1)=x0(2)+h*x0(1)^2-u(2)-h*f; b=zero ...
- 记不住的Android活动的生命周期
Activity基类定义了管理一个互动的生命周期的一系列事件. Activity生命周期的一系列事件onCreate()——当前活动首次被创建时使用.onStart()——当前活动对用户可见时调用.o ...
- CopyOnWriteArrayList&Collections.synchronizedList()
1.ArrayList ArrayList是非线性安全,此类的 iterator() 和 listIterator() 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remov ...
- commons-lang3工具类学习(二)
三.BooleanUtils 布尔工具类 and(boolean... array) 逻辑与 BooleanUtils.and(true, true) = true Boolea ...
- Autotools setting
./configure CFLAGS="-ggdb3 -O0" CXXFLAGS="-ggdb3 -O0" LDFLAGS="-ggdb3" ...
- 微信开发】【Asp.net MVC】-- 微信分享功能
[微信开发][Asp.net MVC]-- 微信分享功能 2017-01-15 09:09 by stoneniqiu, 12886 阅读, 15 评论, 收藏, 编辑 内嵌在微信中的网页,右上角都会 ...
- php加密
域名授权函数 function allow_doamin(){ $is_allow=false; $url=trim($_SERVER['SERVER_NAME']); $arr_a ...
- Windows环境安装tesseract-ocr 4.00并配置环境变量
最近要做文字识别,不让直接用别人的接口,所以只能尝试去用开源的类库.tesseract-ocr是惠普公司开源的一个文字识别项目,通过它可以快速搭建图文识别系统,帮助我们开发出能识别图片的ocr系统.因 ...
- 为什么ssh 执行完命令以后 挂了, hang , stop respond