java中给对象的List集合去重的几种方法(Lambda)

本文介绍了Java中三种有效的对象List去重方法:利用lambda表达式、Stream API的collect方法和distinct方法。涵盖JDK 8特性,如ConcurrentHashMap的putIfAbsent方法及TreeSet的使用,并强调实体类需重写equals和hashCode方法。

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


前言

JDK8的对象去重方式的总结,不包含常规的去重方式,例如:List、Set(HashSet)、TreeSet和LinkedHashSet的遍历去重方式。包含lambda表达式的去重方式、Stream API的去重方式,distinct
如果有解释错误的地方,欢迎留言指正哦!!!


一、lambda表达式的去重方式

lambda表达式去重有两个值得注意的点,一个是JDK8的四大内置函数式接口。另一个ConcurrentHashMap集合。

这里用到了ConcurrentHashMap的putIfAbsent方法,这也是该去重方法的核心。该方法存入的参数会生成一对键值对保存,**如果集合中没有存入过该键值对,那么会返回null,如果已经存入了,那么返回该key对应的value。配合JDK8的Predicate断言式函数式接口,如果是null 那么表示还没存入即没有重复,返回true。那么调用该方法时,通过filter将返回值为true的对象保留。**则实现的对集合中对象的某一属性去重。

private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

附上putIfAbsent方法的源码:

  default V putIfAbsent(K key, V value) {
        V v = get(key);
        if (v == null) {
            v = put(key, value);
        }

        return v;
    }

二、Stream API中的collect去重方法

该方法的核心是TreeSet。我们都知道,默认情况下,TreeSet可以实现去重并且按照自然顺序排序。同样的,还有HashSet以及LinkedHashSet都可以实现去重,但对于实体类对象,后两者的去重与实体类中equals和hashCode方法的实现有关。在这里插入图片描述
要实现对实体类对象的去重需要引入比较器(或者实体类需要实现Comparable中的compareTo方法)。如果不使用比较器,那么将会报错(只针对TreeSet,HashSet以及LinkedHashSet都不会报错);

java.lang.ClassCastException: com.asiainfo.grid.sop.base.po.GsopKpiPool cannot be cast to java.lang.Comparable
在这里插入图片描述

接下来,我们使用TreeSet来去重。TreeSet根据Comparator中写入的对象的某一属性去重

 Set<GsopKpiPool> gsopKpiPools = new TreeSet<>(Comparator.comparing(GsopKpiPool::getSourceTable));
        gsopKpiPools.addAll(cpList);
        gsopKpiPools.forEach(t->System.out.println(t));
        System.out.println("-----------------------将TreeSet转换成List");
        ArrayList<GsopKpiPool> gsopKpiPools1 = Lists.newArrayList(gsopKpiPools);
        gsopKpiPools1.forEach(t->System.out.println(t));

Collectors的collectingAndThen方法,则是执行完Collector之后,将该集合以某种格式返回

cpList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(GsopKpiPool::getSourceTable))), ArrayList::new));
//上述代码相当于
cpList.stream().collect(Collectors.toCollection(()->new ArrayList<>(new TreeSet<>(Comparator.comparing(GsopKpiPool::getSourceTable)))));       

三、Stream API 中的distinct方法去重

使用该方法对实体类对象去重需要重写实体类的equals和hashCode方法。否则起不到任何去重的效果。

List<GsopKpiPool> collect = cpList.stream().distinct().collect(Collectors.toList());

equals和hashCode方法的重写就不多做解释啦……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值