今天在做导入功能时,看到一个感觉很好的去重算法,特分享给大家看看:
其原理利用了以下几点:
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