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

本文详细介绍了在Java中如何对List对象进行去重操作,包括基本类型和对象类型的去重方法,利用Set、Stream API以及根据对象属性去重的多种策略,并提供了具体的代码示例。

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

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);
}

参考文献:
1、https://www.cnblogs.com/pcheng/p/10930944.html 20200525
2、https://blog.youkuaiyun.com/tangerr/article/details/90349986 20200525
3、https://blog.youkuaiyun.com/lin252552/article/details/81128296 20200525
4、https://blog.youkuaiyun.com/xingxiupaioxue/article/details/83786320 20200525

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值