按流排序不适用

时间:2018-12-15 11:19:07

标签: java java-8 functional-programming java-stream

我有这段Java8代码:

Set<Purchase> purchases = 
    user.getAcquisitions()
        .parallelStream()
        .map(a -> a.getPurchases())
    .sorted(Comparator.comparing(Purchase::getPurchaseDate).reversed());

但是我有这个编译错误,我也不知道为什么:

The method sorted(Comparator<? super Set<Purchase>>) in the type Stream<Set<Purchase>> is not applicable for the arguments 
 (Comparator<Purchase>)

4 个答案:

答案 0 :(得分:9)

.map(a -> a.getPurchases())之后,您似乎期望得到一个Stream<Purchase>,但是您真正拥有的却是一个Stream<Set<Purchase>>

如果确实需要Stream<Purchase>,则应该使用

.flatMap(a -> a.getPurchases().stream())

答案 1 :(得分:2)

要扩展到Joe's answer,似乎您想要排序的Set<Purchase>(无论出于何种原因),因为您有充分的理由这样做,您可以使用LinkedHashSet

user.getAcquisitions()
    .parallelStream()
    .flatMap(e -> e.getPurchase().stream())
    .sorted(Comparator.comparing(Purchase::getPurchaseDate).reversed())
    .collect(toCollection(LinkedHashSet::new));
  • flatMap将嵌套的Set<Purchase>展平为Stream<Purchase>
  • 然后根据提供的比较器对元素进行排序
  • 然后将元素收集到遵守插入顺序的LinkedHashSet实现中。

请注意,您也可以这样做:

user.getAcquisitions()
    .parallelStream()
    .flatMap(e -> e.getPurchase().stream())
    .distinct()
    .sorted(Comparator.comparing(Purchase::getPurchaseDate).reversed())
    .collect(toCollection(ArrayList::new));

因此,根据所使用的上下文元素,最好将其收集到列表实现中。

  • flatMap将嵌套的Set<Purchase>展平为Stream<Purchase>
  • distinct根据equals方法返回唯一对象的新流。
  • 然后根据提供的比较器对元素进行排序
  • 最后,它随后将流中的元素收集到ArrayList实现中。

答案 2 :(得分:1)

a.getPurchases()为您提供了一个集合,并且您的比较器正在比较集合中的元素,而不是集合中的元素。

根据您的预期输出,我了解您想获取具有最新购买日期的套装。 如果每组只包含相同的购买日期购买,则可以这样创建比较器:

 .sorted(Comparator.comparing(purchases -> purchases.iterator().next(), (p1, p2) -> -p1.compareTo(p2)));

如果一组中的购买日期不同,则需要获取一组中的最大(或最小)购买日期,然后比较各组之间的购买日期,例如:

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)));

答案 3 :(得分:0)

尝试通过这种方式进行操作:

 Set<Purchase> purchases = 
    user.getAcquisitions()
        .parallelStream()
        .map(Acquisition::getPurchases)
        .flatMap(Set::stream)
        .collect(Collectors.toCollection(TreeSet::new));