繁体   English   中英

基于两个有序元素在两个其他流中是否相等来创建流

[英]Creating a Stream based on if both ordered elements are equal in two other streams

我正在尝试学习如何在我通常会强制执行的情况下使用Java Streams。

所以,如果我有一个如下所示的流1:

1 4 3 5 6 9 4 1 ...

和流2看起来像这样

1 0 3 0 0 9 4 0 ...

我想创建一个只包含相同元素的第三个流,所以:

1 3 9 4 ...

除了将它们转换为迭代器并以这种方式手动执行之外,对于流来说,这看起来并不可行。 没有真正的方法来组合这样的两个流。

如果您的来源是随机访问列表,则可以执行以下操作:

List<Integer> list1 = Arrays.asList(1, 4, 3, 5, 6, 9, 4, 1, ...);
List<Integer> list2 = Arrays.asList(1, 0, 3, 0, 0, 9, 4, 0, ...);

IntStream.range(0, list1.size())
    .mapToObj(i -> list1.get(i).equals(list2.get(i)) ? list1.get(i) : null)
    .filter(Objects::nonNull).collect(Collectors.toList());

在我的StreamEx库中,有一个专门针对这种情况的快捷方式:

StreamEx.zip(list1, list2, (a, b) -> a.equals(b) ? a : null).nonNull().toList();

此外,如果您不关心并行处理,可以使用jOOL库,它允许您将两个流压缩在一起:

Seq.of(list1).zip(Seq.of(list2), (a, b) -> a.equals(b) ? a : null)
             .filter(Objects::nonNull).toList();

这将对并行流执行不良,但适用于任何流源(不仅是随机访问列表或数组)。

你必须压缩你的流 - 我可以推荐你protonpack微型库。 这是一种测试方法:

import com.codepoetics.protonpack.StreamUtils;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.junit.Test; 

// ... skipped test class declaration
@Test
public void shouldRetrieveOnlyEqual() {
    // given
    Stream<Integer> s1 = Stream.of(1, 4, 3, 5, 6, 9, 4, 1);
    Stream<Integer> s2 = Stream.of(1, 0, 3, 0, 0, 9, 4, 0);

    // when
    List<Integer> actual = StreamUtils.zip(s1, s2, (v1, v2) -> v1.equals(v2) ? v1 : null)
            .filter(Objects::nonNull).collect(Collectors.toList());

    // then
    assertThat(actual, contains(1, 3, 9, 4));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM