Stream 流 根据对象属性去重

目录

前言

一、实现原理

二、实现过程

三、filter过滤器的原理

总结


前言

这篇文章介绍一种通过stream流对集合中的对象根据key值去重的简便方法。


一、实现原理

        通过Stream流中的filter方法实现对数据的去重,具体操作是构造一个Predict对象,在Predict中通过检查数据是否存在返回断言中的布尔值。

二、实现过程

代码如下:

public static   Predicate distinctPredicate(Function function){
        ConcurrentHashMap map = new ConcurrentHashMap<>();
        return (t)-> null == map.putIfAbsent(function.apply(t),true);

  }



// 测试代码
public static void main(String[] args) {

        HashMap map1 = new HashMap<>();
        map1.put("key1","value1");
        HashMap map2 = new HashMap<>();
        map2.put("key1","value1");
        ArrayList maps = new ArrayList<>();
        maps.add(map1);
        maps.add(map2);

        List distinctMap= maps.stream().filter(distinctPredicate(m -> m.get("key1"))).collect(Collectors.toList());



    }
对于上面代码distinctPredicate方法,我是有一点疑惑的,因为在我看来filter方法每次调用distinctPredicate方法,都会重新初始化ConcurrentHashMap map = new ConcurrentHashMap<>()这行代码,这就意味着,这个方法的map对象里永远只会有一个值,那么也就不会出现存在key就put的情况。如果你也有这样的疑问,下面有这个问题的答案。

三、filter过滤器的原理

        下面是filter中的源码部分,通过接口中的注释可以看到filter对每一个输入的元素都执行一次predicate的test方法,从而决定集合中是否需要包含这个元素。

        需要注意的是filter方法的入参是一个Predict对象,也就意味着filter每次调用的是precdict对象中的方法,并不是我们前面使用的distinctPredicate方法。distinctPredicate方法的唯一作用就是构造一个precdict对象,所以也不会重复的初始化ConcurrentHashMap map = new ConcurrentHashMap<>()这行代码,因此前一个放入map的数据会一致保存到stream的结束。

 /**
     * Returns a stream consisting of the elements of this stream that match
     * the given predicate.
     *
     * 

This is an intermediate * operation. * * @param predicate a non-interfering, * stateless * predicate to apply to each element to determine if it * should be included // 对每一个元素执行断言,从而判断集合中是否包含这个元素 * @return the new stream */ public final Stream filter(Predicate predicate) { Objects.requireNonNull(predicate); return new StatelessOp(this, StreamShape.REFERENCE, StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { return new Sink.ChainedReference(sink) { @Override public void begin(long size) { downstream.begin(-1); } @Override public void accept(P_OUT u) { if (predicate.test(u)) downstream.accept(u); } }; } }; }


总结

以上就是通过stream流对集合对象中的根据key去重的方法。如有疑问欢迎指出。。。

你可能感兴趣的:(jdk1.8新特性,python,pandas,数据分析)