【问题标题】:Multiple streams filter or forEach if-else多个流过滤器或 forEach if-else
【发布时间】:2021-04-16 16:51:44
【问题描述】:

我有一个小列表,我必须根据元素的值将其分成 2 个列表。我正在寻找两种方法来做到这一点 -

  1. 使用过滤器对列表进行两次迭代。
List<String> sublist1 = list.stream().filter(condition1).collect(ImmutableList.toImmutableList());
List<String> sublist2 = list.stream().filter(condition2).collect(ImmutableList.toImmutableList());
  1. 在流​​中使用 forEach 来分配值
List<String> sublist1 = new LinkedList<>();
List<String> sublist2 = new LinkedList<>();
list.stream().forEach(element -> {
    if(condition1) sublist1.add(element);
    else if (condition2) sublist2.add(element);
})

我想知道哪种方式更好更有效地实现这一点?

【问题讨论】:

  • 当然,当您只迭代一次而不是两次时。对于特定案例,还可以对显着程度进行基准测试。
  • 看起来您正在“对列表进行分区”,请参阅 baeldung.com/java-list-split#use-java8-to-partition-the-list 了解 Java8 的单次迭代选项。
  • 除了遍历所有内容两次之外,第一个示例可能涉及到最后复制整个结果集合。 (如果您考虑不可变收集器必须如何工作,它可能会可变地累积元素,然后最终从可变列表创建一个新的不可变列表作为最后一步)
  • 顺便说一下,你应该总是更喜欢 ArrayList 而不是 LinkedList。您可以将它们都初始化为原始列表的大小,这可能比您需要的要大,但这比可能多次调整大小以达到必要的容量要好
  • list.stream().forEach() 在第二种情况下似乎是多余的,可以替换为list.forEach 或等效循环for(E element: list)

标签: java performance java-8 java-stream


【解决方案1】:

如果您有两个明确的条件导致两个子列表,并且它们是替代,这两个条件中只有一个可能为真,您可以在filterPredicate.or 中使用 OR然后在任一条件下使用Collectors.partitioningBy

Map<Boolean, List<String>> sublistMap = list
        .stream()
        .filter(condition1.or(condition2))
        .collect(Collectors.partitioningBy(condition1, Collectors.toUnmodifiableList()));

List<String> sublist1 = sublistMap.get(Boolean.TRUE); // condition1
List<String> sublist2 = sublistMap.get(Boolean.FALSE); // condition2

测试

List<String> list = Arrays.asList("a", "b", "cc", "ddd", "aaaa", "vvv", "oo");
Predicate<String> condition1 = (s) -> s.contains("o");
Predicate<String> condition2 = (s) -> s.contains("a");

System.out.println(sublist1);
System.out.println(sublist2);

输出:

[oo]
[a, aaaa]

【讨论】:

  • 我的用例更多的是对类对象中的一个属性中的值进行字符串比较。所以partitioningBy 在我的情况下不起作用。
  • 你的意思是condition1condition2可能同时为真吗?
  • 虽然这是一个很酷的技巧,但我相信它既不比原始问题中的任何方法更快也更易读。
猜你喜欢
  • 2016-11-30
  • 1970-01-01
  • 2014-02-11
  • 2020-04-09
  • 2013-08-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多