如何在Java中合并两个流?

2022-09-03 05:19:04

假设我们有两个流,如下所示:

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](顺序无关紧要)。或者我们只能同时处理一个流吗?

此外,如果这两个流是对象流,如何只保留不同的对象,而不覆盖 and 方法?例如: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'}

我们认为两个学生是一样的,当他们是一样的,无论什么(所以May和Mary是同一个人,因为他们的号码都是“1”)。noname

我已经找到了方法,但这种方法是基于.如果我们不允许覆盖该方法,我们如何合并并合并到一个没有重复项的流中?distinct()Object#equals()equals()stream1stream2


答案 1

@Jigar Joshi已经回答了你问题的第一部分,即“如何将两个IntStream合并为一个”。

您的另一个问题是“如何在不覆盖 and 方法的情况下合并两个?”可以使用收集器来完成,即假设您不希望将结果作为 .例:Stream<T>equals()hashCode()toMapStream<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>Tequalshashcode


答案 2

你可以使用 concat()

IntStream.concat(stream1, stream2)

推荐