[英]How to merge two streams in Java?
假设我们有如下两个流:
IntStream stream1 = Arrays.stream(new int[] {13, 1, 3, 5, 7, 9});
IntStream stream2 = Arrays.stream(new int[] {1, 2, 6, 14, 8, 10, 12});
stream1.merge(stream2); // some method which is used to merge two streams.
有没有什么方便的方法可以使用 Java 8 流 API 将两个流合并到 [13, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 14] (顺序无关紧要) . 还是我们只能同时处理一个流?
此外,如果这两个流是对象流,如何在不覆盖equals()
和hashCode()
方法的情况下只保留不同的对象? 例如:
public class Student {
private String no;
private String name;
}
Student s1 = new Student("1", "May");
Student s2 = new Student("2", "Bob");
Student s3 = new Student("1", "Marry");
Stream<Student> stream1 = Stream.of(s1, s2);
Stream<Student> stream2 = Stream.of(s2, s3);
stream1.merge(stream2); // should return Student{no='1', name='May'} Student{no='2', name='Bob'}
当他们的no
相同no
考虑name
时,我们认为两个学生相同(因此 May 和 Marry 是同一个人,因为他们的编号都是“1”)。
我找到了distinct()
方法,但该方法基于Object#equals()
。 如果我们不允许覆盖equals()
方法,我们如何将stream1
和stream2
合并到一个没有重复项的流?
你可以使用concat()
IntStream.concat(stream1, stream2)
@Jigar Joshi回答了你的问题的第一部分,即“如何将两个IntStream合并为一个” 。
你的另一个问题是“如何在不覆盖equals()
和hashCode()
方法的情况下合并两个Stream<T>
?” 可以使用toMap
收集器完成,即假设您不希望结果为Stream<T>
。 例:
Stream.concat(stream1, stream2)
.collect(Collectors.toMap(Student::getNo,
Function.identity(),
(l, r) -> l,
LinkedHashMap::new)
).values();
如果你想把结果作为Stream<T>
那么可以做:
Stream.concat(stream1, stream2)
.collect(Collectors.collectingAndThen(
Collectors.toMap(Student::getNo,
Function.identity(),
(l, r) -> l,
LinkedHashMap::new),
f -> f.values().stream()));
这可能不如它有效,但它是返回Stream<T>
的另一种方式,其中T
项都是不同的,但是没有使用覆盖的equals
和hashcode
,如上所述。
对于第一个问题,您可以使用“flatMap”
IntStream stream1 = Arrays.stream(new int[] {13, 1, 3, 5, 7, 9});
IntStream stream2 = Arrays.stream(new int[] {1, 2, 6, 14, 8, 10, 12});
List<Integer> result = Stream.of(stream1, stream2).flatMap(IntStream::boxed)
.collect(Collectors.toList());
//result={13, 1, 3, 5, 7, 9, 1, 2, 6, 14, 8, 10, 12}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.