假设我们有两个流,如下所示:
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
相同的情况下是相同的,而与name
无关(因此May和Marry是同一个人,因为他们的人数都是“ 1”)。
我已经找到了distinct()
方法,但是该方法基于Object#equals()
。如果不允许我们覆盖equals()
方法,如何将stream1
和stream2
合并到一个没有重复项的流中?
答案 0 :(得分:9)
您可以使用concat()
IntStream.concat(stream1, stream2)
答案 1 :(得分:3)
@Jigar Joshi已经回答了您问题的第一部分,即“ “如何将两个IntStream合并为一个” 。
您的另一个问题是“如何合并两个Stream<T>
而不会覆盖equals()
和hashCode()
方法?”可以使用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
和{{1})的另一种方式}。