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

猜你喜欢

转载自www.cnblogs.com/wangxuejian/p/10421347.html