1. 常规元素去重
// 遍历后判断赋给另一个list集合,保持原来顺序
public static void ridRepeat1(List<String> list) {
System.out.println("list = [" + list + "]");
List<String> listNew = new ArrayList<String>();
for (String str : list) {
if (!listNew.contains(str)) {
listNew.add(str);
}
}
System.out.println("listNew = [" + listNew + "]");
}
// set集合去重,保持原来顺序
public static void ridRepeat2(List<String> list) {
System.out.println("list = [" + list + "]");
List<String> listNew = new ArrayList<String>();
Set set = new HashSet();
for (String str : list) {
if (set.add(str)) {
listNew.add(str);
}
}
System.out.println("listNew = [" + listNew + "]");
}
// Set去重 由于Set的无序性,不会保持原来顺序
public static void ridRepeat3(List<String> list) {
System.out.println("list = [" + list + "]");
List<String> listNew = new ArrayList<String>(new HashSet(list));
System.out.println("listNew = [" + listNew + "]");
}
// Set去重并保持原先顺序的两种方法
public static void ridRepeat4(List<String> list) {
System.out.println("list = [" + list + "]");
List<String> listNew = new ArrayList<String>(new TreeSet<String>(list));
List<String> listNew2 = new ArrayList<String>(new LinkedHashSet<String>(list));
System.out.println("listNew = [" + listNew + "]");
System.out.println("listNew2 = [" + listNew2 + "]");
}
//利用java8的stream去重
List uniqueList = list.stream().distinct().collect(Collectors.toList());
System.out.println(uniqueList.toString());
2. 对象去重
1.可以利用for循环遍历的方式进行判断去重。
2.使用Java8新特性stream去重
//根据name属性去重
List<User> unique1 = userList.stream().collect(
collectingAndThen(
toCollection(() -> new TreeSet<>(comparing(User::getName))), ArrayList::new));
System.out.println(unique1.toString());
//根据name,age属性去重
List<User> unique2 = userList.stream().collect(
collectingAndThen(
toCollection(() -> new TreeSet<>(comparing(o -> o.getName() + ";" + o.getAge()))), ArrayList::new)
);
System.out.println(unique2.toString());
3.使用set去重(需重写对象的hashcode与euqals方法)。
set集合判断元素是否重复时,会先比较两个对象的hashcode是否相同,如果相同,再去调用equals方法判断对象是否相同,如果相同,则set认为这两个元素是相同的,否则会认为两个元素不同。所以,要想实现对象去重,就需要重写这两个方法。
我认为主要是重写equals,但是根据《Effective Java》第二版的第九条:覆盖equals时总要覆盖hashCode 中的内容:
- 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一地返回同一个整数。
- 如果两个对象根据equals方法比较是相等的,那么调用两个对象的hashCode方法必须返回相同的整数结果。
- 如果两个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。