[英]Java streams perform different operations by multiple filters
I want to return different error messages minimum and maximum constraints on the values in a given list.我想针对给定列表中的值返回不同的错误消息最小和最大限制。 I was hoping to use Java streams but i am having to filter the same list twice.
我希望使用 Java 流,但我不得不两次过滤相同的列表。 Whereas using a for loop i would only have to go over the list once.
而使用 for 循环我只需要 go 遍历列表一次。 Is there a better way to achieve this via streams?
有没有更好的方法通过流来实现这一点?
My code looks something like this:我的代码看起来像这样:
list.stream().filter(i -> i < 0).findAny().ifPresent(i -> System.out.println("below min"));
list.stream().filter(i -> i > 100).findAny().ifPresent(i -> System.out.println("above max"));
Using a for loop i can place two if conditions while traversing over the list once,使用 for 循环我可以放置两个 if 条件,同时遍历列表一次,
In actual implementation there are other constraints as well and I'm adding an error to a list, if it not already exists, depending on each violation.在实际实施中,还有其他约束,如果错误不存在,我会根据每次违规情况向列表中添加一个错误。
Will i have to filter the list each time for each violation?每次违规我都必须过滤列表吗? Help would be appreciated!
帮助将不胜感激!
If you are using Java 12+
you can utilize teeing collector to achieve what you want using Java Streams API:如果您使用的是
Java 12+
,您可以利用发球收集器使用 Java Streams API 来实现您想要的:
list.stream()
.collect(Collectors.teeing(
Collectors.minBy(Comparator.comparingInt(Integer.class::cast)),
Collectors.maxBy(Comparator.comparingInt(Integer.class::cast)),
(min, max) -> {
min.ifPresent(i -> System.out.println("below min"));
max.ifPresent(i -> System.out.println("above max"));
return 0;
}
));
You can collect those elements as well:您也可以收集这些元素:
list.stream()
.collect(Collectors.teeing(
Collectors.filtering(i -> i < 0, Collectors.toList()),
Collectors.filtering(i -> i > 100, Collectors.toList()),
(l1, l2) -> {
System.out.printf("%s %s%n", l1, l2);
return 0;
}
));
Though, whether such approach with streams should be used in place of a for
loop needs careful consideration.但是,是否应该使用这种流方法代替
for
循环需要仔细考虑。 For this specific question, the code using the for
loop will probably be more readable.对于这个特定问题,使用
for
循环的代码可能更具可读性。
You can simply stream and use a forEach loop to filter out elements in a single loop:您可以简单地使用 stream 并使用 forEach 循环在单个循环中过滤掉元素:
List<Integer> smaller = new ArrayList<>();
List<Integer> larger = new ArrayList<>();
List<Integer> intList = Arrays.asList(200, 345, -132, -2, -34, null);
intList.stream().filter(Objects::nonNull).forEach(element -> {
if (element < 0) {
smaller.add(element);
} else if (element > 100) {
larger.add(element);
}
});
System.out.println("Smaller:-" + smaller);
System.out.println("Larger:-" + larger);
The real focus should be on code readability even if it takes some more code line to write logic.真正的重点应该放在代码的可读性上,即使需要更多的代码行来编写逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.