3

I have multiple streams of Student Object. I have to merge them in sorted order.

class Student {
    private String branch;
    private Integer rollNo;
    private Date doj;
    // Getters and Setters
}

In another class, I have a method

private Stream<Student> mergeAndSort(Stream<Student> s1, Stream<Student> s2, Stream<Student> s3) {
    return Stream.of(s1, s2, s3).sorted(...
        // I tried this logic multiple times but is not working. How can I inject Student comparator here.
        // I have to sort based on branch and then rollNo.
    );
}
Holger
  • 243,335
  • 30
  • 362
  • 661
pankaj_ar
  • 697
  • 2
  • 10
  • 29
  • The logic quoted is missing from the question I believe. you just need to place the `Comparator` there. What matters is the definition of the comparator in your code. – Naman Sep 17 '19 at 12:15
  • Possible duplicate of [Adding two Java 8 streams, or an extra element to a stream](https://stackoverflow.com/questions/22740464/adding-two-java-8-streams-or-an-extra-element-to-a-stream) – Naman Sep 17 '19 at 12:21
  • you have to call `.flatMap(Function.identity())` before sorting. Also you can change the signature of the method to `mergeAndSort(Stream... s1)` – Adrian Sep 17 '19 at 12:22

1 Answers1

5

Stream.of(s1, s2, s3) gives you a Stream<Stream<Student>>. In order to get a Stream<Student>, use flatMap:

Stream.of(s1, s2, s3).flatMap(Function.identity()).sorted(...)...

To sort according to the required properties:

return Stream.of(s1, s2, s3)
             .flatMap(Function.identity())
             .sorted(Comparator.comparing(Student::getBranch).thenComparing(Student::getRollNo));
Eran
  • 359,724
  • 45
  • 626
  • 694
  • how about `Stream.concat(Stream.concat(s1, s2), s3).sorted(...)...` – Ousmane D. Sep 17 '19 at 12:20
  • Reading further from the comments, *I have to sort based on branch and then rollNo* ...`sorted(Comparator.comparing(Student::getBranch).thenComparing(Student::getRollNo))` – Naman Sep 17 '19 at 12:22
  • @Aomine a nice read [about that here](https://stackoverflow.com/a/22741520/1746118()) – Naman Sep 17 '19 at 12:23
  • @Aomine I don't know. It seems less elegant to me. Perhaps if there was a `concat()` variant taking more than two `Stream`s. – Eran Sep 17 '19 at 12:25
  • @Eran yeah, it varies from person to person I guess. – Ousmane D. Sep 17 '19 at 12:26
  • 2
    @Aomine both variants have pros and cons, so there’s no clear decision. `concat` is early binding, which allows it to retain size information and support splitting for parallel streams, but is prone to stack overflows when nested too often. In contrast, `flatMap` works with large numbers of substreams, but less efficient with larger substreams, [especially with older Java versions](https://stackoverflow.com/q/29229373/2711488) due to the lack of laziness (which makes it even break with infinite streams). So for the task of combining three streams of unknown size, I’d go for `concat`… – Holger Sep 17 '19 at 14:52
  • @Holger interesting, appreciated for the enlightenment. – Ousmane D. Sep 17 '19 at 15:19