我有以下函数,它试图逐步缩小输入集合的范围,直到找到单个元素,即当发现单个项目时,过滤应该停止,因为应用其他过滤器可能会导致根本不匹配。
public List<MyObject> determinePotentialCandidates(List<MyObject> allCandidates) {
List<MyObject> candidates = allCandidates.stream()
.filter(this::firstCondition)
.toList();
if (candidates.size() > 1) {
candidates = candidates.stream()
.filter(this::secondCondition)
.toList();
if (candidates.size() > 1) {
candidates = candidates.stream()
.filter(this::thirdCondition)
.collect(Collectors.toList());
}
// ... and so on
}
logResult(candidates);
return candidates;
}
随着每增加一个嵌套级别,这变得越来越难阅读,我想知道是否有更简洁的方法来编写这篇文章。
优选地,该方法应最多执行一次每个过滤步骤(尽管输入大小较小且过滤成本较低-对于同一输入可以执行多次),并包含单个出口点。
我在这里看到了一些选项:
在这两种情况下,我假设条件是已知的。但这使解决方案保持了刚性,并且不可扩展。从您发布的示例中,我不能说您是否在原始解决方案中遵守了一些可靠的原则,例如打开/关闭。
选项:
对于这两种情况,我建议进行更多调整。
制作一个抽象类或接口,将条件表示为概念。创建另一个类作为条件提供程序,此条件提供程序将维护条件实例列表。稍后可以通过依赖注入或工厂使用您的条件初始化条件提供程序。
您的类(在本例中是此提供程序的客户端)将接收作为依赖项(构造函数)注入的提供程序。类将向提供程序请求它必须验证的所有条件。您的类将在for循环中使用此条件列表来过滤集合。
这样,您可以灵活地使用哪些条件进行过滤。希望您的代码更易于维护。
希望这对你有帮助。
您可以将所有条件放入一个列表中,并在其上循环,在每次迭代中应用一个过滤器,直到只剩下一个元素。
List<Predicate<MyObject>> conditions = List.of(this::firstCondition, this::secondCondition, this::thirdCondition /*...*/ );
for(int i = 0; i < conditions.size() && allCandidates.size() > 1; i++)
allCandidates = allCandidates.stream().filter(conditions.get(i)).toList();
// Note: you may need to check if the list is empty here
return allCandidates;
并在匹配一些条件后用Java8流对其进行过滤 那将如何完成呢? 上面示例的结果应该是
我想在找到第一个值时终止流的执行。然而,当我运行下面的代码时,它显示,即使第一个方法中存在值,也会调用两个方法。 我登记了文件: 表示 如果存在值,则返回{@code true},否则返回{@code false}。 返回描述此流的第一个元素的{@link Optional},如果流为空,则返回空的{@code Optional}。如果流没有遭遇顺序,那么可以返回任何元素。 所以它满足了第一个条件
现在我有一个列表: 我想得到一个字符串列表,即从map中匹配键值的值,在' pick '列表中找到。所以,我期望得到结果{"f "," a"}。有没有办法用java stream api优雅地做到? 当有一个值时,我会这样做: 但是,当有一个键/选择列表要过滤时,就很难了。
我有这个密码 但是,我有这样的错误消息: 怎么解决这个?
问题内容: 如何在Linux和Windows中正常停止Java进程? 什么时候被调用,什么时候不被调用? 终结器又如何呢? 我可以从外壳向Java进程发送某种信号吗? 我正在寻找最好的便携式解决方案。 问题答案: 在所有未强制终止VM的情况下,都会执行关机挂钩。因此,如果要发出“标准” kill(通过kill命令),则它们将执行。同样,它们将在调用后执行。 但是强行杀死(或),然后它们将不会执行。