当前位置:  开发笔记 > 编程语言 > 正文

根据toMap集合中的值过滤流

如何解决《根据toMap集合中的值过滤流》经验,为你挑选了1个好方法。

我有一个情况,我Player在开发项目中有对象,任务只是测量距离并返回低于某个阈值的结果.当然,我想以最简洁的方式使用流.

目前,我有一个映射流的解决方案,然后通过迭代器过滤:

Stream str = /* source of my player stream I'm filtering */;
Map dists = str.collect(Collectors.toMap(...)); //mapping function
Iterator> itr = map.entrySet().iterator();
while (itr.hasNext()) {
    if (itr.next().getValue() <= radiusSquared) {
        itr.remove();
    }
}

但是,我想要实现的是在对流进行操作时执行此过滤的内容,即"如果此谓词失败,不收集",则尝试并保存第二次迭代.另外,我不想计算两次距离,所以通过映射函数进行过滤,然后重新映射不是一个合理的解决方案.

我想到的唯一真正可行的解决方案是映射到a Pair,但如果有某种形式的二进制流的原生支持,那就更好了.

java的流API中是否有本机支持?



1> Holger..:

Map之后过滤并不像看起来那么糟糕,请记住,迭代a Map并不意味着执行查找(例如散列)的成本相同.

而不是

Iterator> itr = map.entrySet().iterator();
while (itr.hasNext()) {
    if (itr.next().getValue() <= radiusSquared) {
        itr.remove();
    }
}

你可以简单地使用

map.values().removeIf(value -> value <= radiusSquared);

即使您坚持将其作为collect操作的一部分,您也可以将其作为后缀操作:

Map dists = str.collect(
    Collectors.collectingAndThen(Collectors.toMap(p->p, p->calculate(p)),
    map -> { map.values().removeIf(value -> value <= radiusSquared); return map; }));

可以首先避免put不需要的条目,但它意味着手动回溯现有toMap收集器的作用:

Map dists = str.collect(
    HashMap::new,
    (m, p) -> { double value=calculate(p); if(value > radiusSquared) m.put(p, value); },
    Map::putAll);

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有