I have a Java Set
that I give information to:
Set<myData> dataLocations = getData(location);
I would like to sort this Set I have tried a sortedSet and couldn't get it to work, so I tried this
dataLocations = dataLocations.stream().sorted(Comparator.comparing(myData -> myData.expDtTm)).collect(Collectors.toSet());
The only problem is that in the Java documentation it doesn't guarantee retaining any orders. So I tried this:
TreeSet<myData> sortedDataLocations = dataLocations.stream().sorted(Comparator.comparing(myData -> myData.expDtTm)).collect(Collectors.toCollection(TreeSet<myData>));
needless to say it didn't work so anyone that has any other ideas they would be much appreciated.
You can use TreeSet
and provide a comparator
TreeSet<myData> sorted = new TreeSet<>(Comparator.comparing(MyData::expDtTm));
sorted.addAll(dataLocations);
Or as described in Collector
class Javadocs create your own collector for TreeSet
:
Collector<Widget, ?, TreeSet<Widget>> intoSet =
Collector.of(
TreeSet::new,
TreeSet::add,
(left, right) -> { left.addAll(right); return left; }
);
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With