Rog*_*gue 8 java java-8 java-stream
我有一个情况,我Player
在开发项目中有对象,任务只是测量距离并返回低于某个阈值的结果.当然,我想以最简洁的方式使用流.
目前,我有一个映射流的解决方案,然后通过迭代器过滤:
Stream<Player> str = /* source of my player stream I'm filtering */;
Map<Player, Double> dists = str.collect(Collectors.toMap(...)); //mapping function
Iterator<Map.Entry<Player, Double>> itr = map.entrySet().iterator();
while (itr.hasNext()) {
if (itr.next().getValue() <= radiusSquared) {
itr.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我想要实现的是在对流进行操作时执行此过滤的内容,即"如果此谓词失败,不收集",则尝试并保存第二次迭代.另外,我不想计算两次距离,所以通过映射函数进行过滤,然后重新映射不是一个合理的解决方案.
我想到的唯一真正可行的解决方案是映射到a Pair<A, B>
,但如果有某种形式的二进制流的原生支持,那就更好了.
java的流API中是否有本机支持?
Map
之后过滤并不像看起来那么糟糕,请记住,迭代a Map
并不意味着执行查找(例如散列)的成本相同.
而不是
Iterator<Map.Entry<Player, Double>> itr = map.entrySet().iterator();
while (itr.hasNext()) {
if (itr.next().getValue() <= radiusSquared) {
itr.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
你可以简单地使用
map.values().removeIf(value -> value <= radiusSquared);
Run Code Online (Sandbox Code Playgroud)
即使您坚持将其作为collect
操作的一部分,您也可以将其作为后缀操作:
Map<Player, Double> dists = str.collect(
Collectors.collectingAndThen(Collectors.toMap(p->p, p->calculate(p)),
map -> { map.values().removeIf(value -> value <= radiusSquared); return map; }));
Run Code Online (Sandbox Code Playgroud)
可以首先避免put
不需要的条目,但它意味着手动回溯现有toMap
收集器的作用:
Map<Player, Double> dists = str.collect(
HashMap::new,
(m, p) -> { double value=calculate(p); if(value > radiusSquared) m.put(p, value); },
Map::putAll);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1418 次 |
最近记录: |