今天在做导入功能时,看到一个感觉很好的去重算法,特分享给大家看看:

其原理利用了以下几点:

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集合元素去重的更多相关文章

  1. List集合对象去重及按属性去重的8种方法-java基础总结系列第六篇

    最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大.基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华.所以我更想把java ...

  2. 【转载】C#中通过Distinct方法对List集合进行去重

    在C#的List集合对象中,可以使用Distinct方法来对List集合元素进行去重,如果list集合内部元素为值类型,则Distinct方法根据值类型是否相等来判断去重,如果List集合内部元素为引 ...

  3. Java学习笔记--集合元素的比较Comparable,Comparator

    原文见: http://www.cnblogs.com/sunflower627/p/3158042.html 1. Comparator 和 Comparable 相同的地方 他们都是java的一个 ...

  4. TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树

    TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树   本文链接:https://blog.csdn.net/u010698072/article/de ...

  5. TreeSet和Comparator 对TreeSet排序

    使用TreeSet和Comparator,编写TreeSetTestInner类,要求对TreeSet中的元素"HashSet"."ArrayList".&qu ...

  6. TreeMap和TreeSet在排序时如何比较元素,Collections工具类中的sort()方法如何比较元素

    TreeSet和TreeMap排序时比较元素要求元素对象必须实现Comparable接口 Collections的sort方法比较元素有两种方法: 元素对象实现Comparable接口 实体类Dog ...

  7. Map / Set / Treeset 取出指定下标index的元素

    Treeset 属于 set  集合中的一种数据类型,HashSet 以及LinkedHashSet 原理相同 需求:想直接在Treeset类型下,取出指定下标的元素,但是Set 下没有 get()方 ...

  8. struts2指定集合元素的泛型

    public class LoginAction implements Action{ private List users; public void setUsers(List users){ th ...

  9. 当JAVA集合移除自身集合元素时发生的诸多问题

    一段代码目的是想删除集合中包括"a"字符串的集合项: public class TestForeach { public static void main(String[] arg ...

随机推荐

  1. HTTP协议(二)之确保web安全的HTTPS

    一.概述 https并非是应用层的一种新协议.只是HTTP通信接口部分用SSL和TLS协议替代. 通常,HTTP直接和TCP通信.当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了. 简 ...

  2. 原生JS获取DOM 节点到浏览器顶部的距离或者左侧的距离

    关于js获取dom 节点到浏览器顶/左部的距离,Jquery里面有封装好的offset().top/offset().left,只到父级的顶/左部距离position().top/position() ...

  3. 解决Gephi导入csv文件时提示“边表格需要一个包含节点标号‘源’和‘目标’列” 问题的两个方案

    1.将csv文件在Excel中打开,并重新保存为csv. 2.将csv文件导入到sqlite,使用sqlite作为数据来源. 标准格式如下

  4. Yii框架实现restful 接口调用,增删改查

    创建模块modules; 在main.php中配置文件:(1) (2)控制器层: namespace frontend\modules\v1\controllers;use frontend\modu ...

  5. 在 .NET项目中使用 Redis(2018.10.16)

    1. 打开NuGet管理器搜索redis,安装:“StackExchange.Redis” 2. 配置 Web.config 文件 <connectionStrings> <add ...

  6. static_assert enable_if 模板编译期检查

    conceptC++ http://www.generic-programming.org/faq/?category=conceptcxx Checking Concept Without Conc ...

  7. 微信小程序silk格式转码成mp3格式

    最近小程序项目需要录制语音并上传到服务器,经过查资料了解 目前微信小程序录音的文件后缀名是silk,因此需要转换. 经过查资料了解,参考一下的地址 https://github.com/kn007/s ...

  8. C++解析八-多态

    多态多态按字面的意思就是多种形态.当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态.C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数.下面的实例中,基类 Sh ...

  9. SpringBoot使用CORS解决跨域请求问题

    什么是跨域? 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 如果一个请求地址里面的协议.域名和端口号都相同,就属于同源. ...

  10. unity中获取七天的日期

    private List<string> Date; private List<string> Day; private string now; private WMG_Axi ...