Reputation: 2136
I have this piece of Java8 code:
Set<Purchase> purchases =
user.getAcquisitions()
.parallelStream()
.map(a -> a.getPurchases())
.sorted(Comparator.comparing(Purchase::getPurchaseDate).reversed());
But I have this compilation error and I don't know why:
The method sorted(Comparator<? super Set<Purchase>>) in the type Stream<Set<Purchase>> is not applicable for the arguments
(Comparator<Purchase>)
Upvotes: 4
Views: 934
Reputation: 104
The a.getPurchases() gives you a set, and your comparator is comparing elements of the set, not sets.
Based on your expected output, I understand you want to get the set which has the latest purchase date. If each set contains only same purchase date purchases, you can create your comparator like this:
.sorted(Comparator.comparing(purchases -> purchases.iterator().next(), (p1, p2) -> -p1.compareTo(p2)));
If purchase dates differ inside a set, you need to get max (or min) purchase date inside a set, then compare that in between the sets, something like:
final Stream<Set<Purchase>> sorted = acquisitions.stream()
.map(Acquisition::getPurchases)
.sorted(Comparator.comparing(purchases ->
Collections.max(purchases, Comparator.comparing(Purchase::getPurchaseDate)).getPurchaseDate(),
(date1, date2) -> -date1.compareTo(date2)));
Upvotes: 1
Reputation: 15704
After .map(a -> a.getPurchases())
, you appear to be expecting a Stream<Purchase>
, but what you really have is a Stream<Set<Purchase>>
.
If a Stream<Purchase>
is indeed what you want, instead you should use
.flatMap(a -> a.getPurchases().stream())
Upvotes: 9
Reputation: 56453
To expand upon Joe's answer, it seems like you want a Set<Purchase>
in sorted order (for whatever reason that may be), given you have a good reason to do so in which case you can use a LinkedHashSet
:
user.getAcquisitions()
.parallelStream()
.flatMap(e -> e.getPurchase().stream())
.sorted(Comparator.comparing(Purchase::getPurchaseDate).reversed())
.collect(toCollection(LinkedHashSet::new));
flatMap
flattens the nested Set<Purchase>
into a Stream<Purchase>
LinkedHashSet
implementation which respects insertion order.btw note that you could as well just do:
user.getAcquisitions()
.parallelStream()
.flatMap(e -> e.getPurchase().stream())
.distinct()
.sorted(Comparator.comparing(Purchase::getPurchaseDate).reversed())
.collect(toCollection(ArrayList::new));
so, depending on the context you're using the resulting elements you might be better off collecting to a list implementation.
flatMap
flattens the nested Set<Purchase>
into a Stream<Purchase>
equals
method.ArrayList
implementation. Upvotes: 2
Reputation: 7279
Try doing it this way:
Set<Purchase> purchases =
user.getAcquisitions()
.parallelStream()
.map(Acquisition::getPurchases)
.flatMap(Set::stream)
.collect(Collectors.toCollection(TreeSet::new));
Upvotes: 0