【问题标题】:Java filters, how to extend the filter?Java过滤器,如何扩展过滤器?
【发布时间】:2018-04-14 22:21:21
【问题描述】:
Java 流的过滤器使用Predicates 来允许或拒绝元素通过流。
感谢.compose 或.andThen 可以限制过滤器。
但是,如果我想根据一些标志让它更宽松怎么办?
例如,我可能希望用户以参数方式设置isAppleAllowed 和isPearAllowed。
.filter(f -> isAppleAllowed || isPearAllowed) 的使用不起作用,因为如果其中一个为 True,则两者都被允许。
我可以使用什么来更宽松地扩展过滤器?
提前感谢您的帮助。
【问题讨论】:
标签:
java
lambda
filter
java-stream
predicates
【解决方案1】:
你的例子没有意义。如果isAppleAllowed 和isPearAllowed 是boolean 参数,正如它们的名称和您的散文所表明的那样,那么它们单独或两者的任何布尔组合都不构成您可以用于应用它们描述的过滤的谓词。相反,您会想要一些类似于
的东西
fruitStream.filter(f -> { return f.isApple() && isAppleAllowed; })
过滤苹果,类似的过滤梨。要联合过滤,您可以使用
fruitStream.filter(f -> {
return (f.isApple() && isAppleAllowed)
|| (f.isPear() && isPearAllowed);
})
或者,给定两个Predicate<Fruit> 对象,比如applePredicate 和pearPredicate,Predicate 类提供了形成联合谓词的方法:
fruitStream.filter(applePredicate.or(pearPredicate))
【解决方案2】:
您可以创建一个帮助函数,它会为您返回Predicate。在此函数中,您可以同时使用两个布尔函数。
【解决方案3】:
我不得不更改此答案,因为您要查找的内容与我最初回答的内容不同。正如我之前建议的那样,对Stream#filter 使用两个单独的调用是没有意义的,因为在这种情况下,Predicates 需要相互依赖。
.filter(f -> (f.isApple() && isAppleAllowed) || (f.isPear() && isPearAllowed))
这样的事情应该可以工作,因为它会在尝试过滤元素之前检查元素的属性。假设元素可以是苹果或梨,那么如果isAppleAllowed 或isPearAllowed 分别为true,它将被过滤掉。