Java 多个流过滤器或forEach(如果有)

Java 多个流过滤器或forEach(如果有),java,performance,java-8,java-stream,Java,Performance,Java 8,Java Stream,我有一个小列表,我必须根据元素的值将其分为两个列表。我正在寻找两种方法来做到这一点- 或者使用过滤器迭代列表两次 List sublist1=List.stream().filter(条件1.collect)(ImmutableList.toImmutableList()); List sublist2=List.stream().filter(条件2).collect(ImmutableList.toImmutableList()); 在流中使用forEach来指定值 List sublis

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

  • 或者使用过滤器迭代列表两次
  • List sublist1=List.stream().filter(条件1.collect)(ImmutableList.toImmutableList());
    List sublist2=List.stream().filter(条件2).collect(ImmutableList.toImmutableList());
    
  • 在流中使用forEach来指定值
  • List sublist1=newlinkedlist();
    List sublist2=新建LinkedList();
    list.stream().forEach(元素->{
    if(条件1)子列表1.添加(元素);
    else if(条件2)子列表2.添加(元素);
    })
    

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

    如果您有两个特定的条件导致两个子列表,并且它们是可选的,那么这两个条件中只有一个可能是正确的,您可以在
    过滤器
    谓词或
    中使用或,然后使用
    收集器。按以下任一条件进行分区:

    Map sublistMap=list
    .stream()
    .过滤器(条件1.或(条件2))
    .collect(Collectors.partitionby(condition1,Collectors.toUnmodifiableList());
    List sublist1=sublistMap.get(Boolean.TRUE);//条件1
    List sublist2=sublistMap.get(Boolean.FALSE);//条件2
    
    试验


    如果您有两个特定的条件导致两个子列表,并且它们是可选的,那么这两个条件中只有一个可能为真,您可以使用或在
    过滤器中
    谓词中。或
    然后使用
    收集器。按任一条件进行分区:

    Map sublistMap=list
    .stream()
    .过滤器(条件1.或(条件2))
    .collect(Collectors.partitionby(condition1,Collectors.toUnmodifiableList());
    List sublist1=sublistMap.get(Boolean.TRUE);//条件1
    List sublist2=sublistMap.get(Boolean.FALSE);//条件2
    
    试验


    当然,当您只迭代一次而不是两次时。对于一个特定的案例,我们还可以对其重要性进行基准测试。看起来您正在“对列表进行分区”,请参阅Java8的单次迭代选项。除了对所有内容进行两次迭代之外,第一个示例可能涉及在最后复制整个结果集合。(如果您考虑不可变收集器必须如何工作,那么在最后一步从可变收集器创建一个新的不可变列表之前,很可能会可变地累积元素)顺便说一下,您应该总是更喜欢ArrayList而不是LinkedList。您可以将它们都初始化为原始列表的大小,该大小可能比您需要的大,但这比可能多次调整大小以达到必要的容量要好。在第二种情况下,stream().forEach()似乎是多余的,可以替换为
    list.forEach
    或(E元素:list)
    的等效循环
    ,当然,当您只迭代一次而不是两次时。对于一个特定的案例,我们还可以对其重要性进行基准测试。看起来您正在“对列表进行分区”,请参阅Java8的单次迭代选项。除了对所有内容进行两次迭代之外,第一个示例可能涉及在最后复制整个结果集合。(如果您考虑不可变收集器必须如何工作,那么在最后一步从可变收集器创建一个新的不可变列表之前,很可能会可变地累积元素)顺便说一下,您应该总是更喜欢ArrayList而不是LinkedList。您可以将它们都初始化为原始列表的大小,该大小可能比您需要的大,但这比可能多次调整大小以达到必要的容量要好。在第二种情况下,stream().forEach()似乎是多余的,可以替换为
    list.forEach
    或(E元素:list)的等效循环
    我的用例更像是类对象中某个属性值的字符串比较。因此,
    partitioning by
    在我的情况下不起作用。你是说
    condition1
    condition2
    可能同时成立吗?虽然这是一个很酷的技巧,但我相信它既不比原始问题中的任何方法更快,也不比原始问题中的任何方法更具可读性。@apangin,仅供参考:我的用例更像是类对象中某个属性值的字符串比较。因此,
    partitioning by
    在我的情况下不起作用。你是说
    condition1
    condition2
    可能同时成立吗?虽然这是一个很酷的技巧,但我相信它既不比原始问题中的任何方法更快,也不比原始问题中的任何方法更具可读性。@apangin,仅供参考:
    List<String> sublist1 = list.stream().filter(condition1).collect(ImmutableList.toImmutableList());
    List<String> sublist2 = list.stream().filter(condition2).collect(ImmutableList.toImmutableList());
    
    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);
    })
    
    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]