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

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

  • 前言
  • 一、lambda表达式的去重方式
  • 二、Stream API中的collect去重方法
  • 三、Stream API 中的distinct方法去重


前言

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方法的实现有关。java中给对象的List集合去重的几种方法(Lambda)_第1张图片
要实现对实体类对象的去重需要引入比较器(或者实体类需要实现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方法的重写就不多做解释啦……

你可能感兴趣的:(java,jdk1.8,lambda,集合)