Java8 List去掉重复对象以及保证添加顺序

JAVA中List对象去除重复值,大致分为两种情况,一种是List、List这类,直接根据List中的值进行去重,另一种是List这种,List中存的是javabean对象,需要根据List中对象的某个值或某几个值进行比较去重。
一、去重

1、List、List对象去重复值

利用Set集合的特性:

   Set<String> set = new LinkedHashSet<>();
   set.addAll(list);
   list.clear();
   list.addAll(set);


通过JDK1.8新特性stream的distinct方法,可以直接处理:

List<String> list = list.stream().distinct().collect(Collectors.toList());

2、List<Student>中对象去重复值

这种的话,不能直接比较List中的对象,需要重写bean对象的equals和hashCode方法,然后通过进行去重,具体例子如下:

public class Student
   private Long id;
   private String name;
 

重写Student对象的equals()方法和hashCode()方法:

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student Student = (Student) o;
        if (!id.equals(Student.id)) return false;
        return name.equals(Student.name);
    }
    @Override
    public int hashCode() {
        int result = id.hashCode();
        result = 19 * result + name.hashCode();
        return result;
    }
 
 
    List<Student> students = Arrays.asList(s1, s2, s3);
    List<Student> studentsNew = new ArrayList<>();
    // 去重
    students.stream().forEach(
           s -> {
               if (!studentsNew.contains(s)) {
                   studentsNew.add(s);
               }
           }
       );
    
    List的contains()方法实际上是用对象的equals方法去比较


3、根据对象的属性去重

java8的stream流能完美解对象集合去重问题:

        List<UserCar> list1 = new ArrayList();
        UserCar userCar = new UserCar();
        userCar.setId(1);
        userCar.setCarNo("AA");
        list1.add(userCar);

        UserCar userCar1 = new UserCar();
        userCar1.setId(2);
        userCar1.setCarNo("AA");
        list1.add(userCar1);


        Person p1 = new Person(1, "11");
        Person p2 = new Person(1, "22");
        Person p3 = new Person(2, "11");
        List<Person> persons = Arrays.asList(p1, p2, p3);



1、不使用java8


 private List<UserCar> removeDupliByRecordId(List<UserCar> userCars) {
     Set<UserCar> personSet = new TreeSet<UserCar>((o1, o2) ->                                                        o1.getRecordId().compareTo(o2.getRecordId()));
     personSet.addAll(userCars);

     return new ArrayList<UserCar>(personSet);
 }


这也是大多数人第一想到的,借助 TreeSet 去重,其中 TreeSet 的其中一个构造函数接收一个排序的算法,同时这也会用到 TreeSet 的去重策略上。


public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
}

2、第一种java8写法


List<Person> unique = persons.stream().collect(
      Collectors.collectingAndThen(
              Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))), ArrayList::new)
);
unique.forEach(p -> System.out.println(p));


3、第二种java8写法


 List<String> names = new ArrayList<>();//用来临时存储person的id

 List<Person> personList = persons.stream().filter(// 过滤去重
         v -> {
             boolean flag = !names.contains(v.getName());
             names.add(v.getName());
             return flag;
         }
 ).collect(Collectors.toList());

二、保证添加顺序

1、方式一 利用HashSet不能添加重复数据的特性 由于HashSet不能保证添加顺序,所以只能作为判断条件:

private static void removeDuplicate(List<String> list) {
    HashSet<String> set = new HashSet<String>(list.size());
    List<String> result = new ArrayList<String>(list.size());
    for (String str : list) {
        if (set.add(str)) {
            result.add(str);
        }
    }
    list.clear();
    list.addAll(result);
}


2、方式二 利用LinkedHashSet不能添加重复数据并能保证添加顺序的特性 :

private static void removeDuplicate(List<String> list) {
    LinkedHashSet<String> set = new LinkedHashSet<String>(list.size());
    set.addAll(list);
    list.clear();
    list.addAll(set);
}

3、方式三 利用List的contains方法循环遍历:

private static void removeDuplicate(List<String> list) {
    List<String> result = new ArrayList<String>(list.size());
    for (String str : list) {
        if (!result.contains(str)) {
            result.add(str);
        }
    }
    list.clear();
    list.addAll(result);
}

posted @ 2022-07-23 08:50  锐洋智能  阅读(11372)  评论(1编辑  收藏  举报