Your third attempt was close though as written doesn't compile. The method Collectors.toCollection
takes a Supplier
that returns the desired Collection
, not the Collection
itself.
If MyData
was defined as:
public class MyData {
private Instant instant;
public Instant getInstant() { return instant; }
public void setInstant(Instant instant) { this.instant = instant; }
}
Then in order to collect them into a SortedSet
via Stream
s you could do:
Comparator<MyData> comparator = Comparator.comparing(MyData::getInstant);
TreeSet<MyData> set = getMyData().stream()
.collect(Collectors.toCollection(() -> new TreeSet<>(comparator));
Note that I don't use Stream.sorted
here. It is actually detrimental if you were to use Stream.sorted
because it adds work that doesn't help the end result. The Stream
would sort its elements and then later start adding them to the TreeSet
which will also sort the elements.
That said, there are cases where using Stream.sorted
would be beneficial: when Stream.collect
returns a Collection
that guarantees insertion order. A LinkedHashSet
, as well as any implementation of List
, guarantee insertion order. So you could do:
LinkedHashSet<MyData> set = getMyData().stream()
.sorted(comparator)
.collect(Collectors.toCollection(LinkedHashSet::new));
// Or use a List
List<MyData> list = getMyData().stream()
.distinct() // If you want only unique elements in the end List
.sorted(comparator)
.collect(Collectors.toList());
Note: It is not enough that the end Collection
guarantees insertion order. The Collector
being used must not have unordered as a characteristic. This is the case with the Collector
s returned by Collectors.toCollection
and Collectors.toList
. It is not the case when using Collectors.toSet
.