如何在Java中合并两个流?

wea*_*ver 6 java java-8 java-stream

假设我们有两个流如下:

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.
Run Code Online (Sandbox Code Playgroud)

是否有任何方便的方法使用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'}
Run Code Online (Sandbox Code Playgroud)

我们认为两个学生在相同时no是相同的而且不管是什么name(所以May和Marry是同一个人,因为他们的数字都是"1").

我找到了distinct()方法,但这种方法是基于Object#equals().如果我们不能覆盖equals()的方法,我们该如何合并stream1以及stream2到有没有重复的项目一个流?

Ous*_* D. 11

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

你的另一个问题是“如何在Stream<T>不覆盖equals()andhashCode()方法的情况下合并两个?” 可以使用toMap收集器完成,即假设您不希望结果为Stream<T>. 例子:

Stream.concat(stream1, stream2)
      .collect(Collectors.toMap(Student::getNo, 
               Function.identity(), 
               (l, r) -> l, 
               LinkedHashMap::new)
      ).values();
Run Code Online (Sandbox Code Playgroud)

如果你想要结果,Stream<T>那么你可以这样做:

 Stream.concat(stream1, stream2)
       .collect(Collectors.collectingAndThen(
               Collectors.toMap(Student::getNo,
                    Function.identity(),
                    (l, r) -> l,
                    LinkedHashMap::new), 
                    f -> f.values().stream()));
Run Code Online (Sandbox Code Playgroud)

这可能不像它那样有效,但它是另一种返回 a 的方法,Stream<T>其中T项目都是不同的,但不使用覆盖equalshashcode正如您所提到的。


Jig*_*shi 10

您可以使用 concat()

IntStream.concat(stream1, stream2)
Run Code Online (Sandbox Code Playgroud)

  • @weaver为什么你会期望`concat`删除重复的项目? (2认同)
  • 为了删除重复项,您可以在连接后调用 `.distinct()`。 (2认同)
  • @weaver这就是流的要点...流上的链式操作。 (2认同)