根据两个有序元素在其他两个流中是否相等创建一个流
Creating a Stream based on if both ordered elements are equal in two other streams
我正在尝试学习如何在通常命令式的情况下使用 Java 流。
因此,如果我的流 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));
}
我正在尝试学习如何在通常命令式的情况下使用 Java 流。
因此,如果我的流 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));
}