用TreeSet和Comparator给list集合元素去重

本文介绍了一种利用Java的TreeSet和Comparator实现的高效去重算法,适用于大量元素或多个字段的去重场景,通过自定义比较规则实现灵活的元素判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

其原理利用了以下几点:

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<>()时一定要加泛型

转载于:https://www.cnblogs.com/wangxuejian/p/10421347.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值