java 8流收集最大对象并按属性区分

jjo*_*ahu 3 java foreach java-8 java-stream

一些列表在这里

List<Book> list = new ArrayList<>();
{
   list.add(new Book("Core Java", 200));
   list.add(new Book("Core Java", 500));
   list.add(new Book("Core Java", 800));
   list.add(new Book("Learning Freemarker", 150));          
   list.add(new Book("Learning Freemarker", 1350));   
   list.add(new Book("Learning Freemarker", 1250));   
   list.add(new Book("Spring MVC", 300));
   list.add(new Book("Spring MVC", 600)); 
   list.add(new Book("Spring MVC", 1600));
}
Run Code Online (Sandbox Code Playgroud)

我想显示这样的书单

Core Java", 800
Learning Freemarker", 1350
Spring MVC", 1600
Run Code Online (Sandbox Code Playgroud)

每1个元素

list .stream().distinct()
     .sorted(Comparator.comparing(Book::bookname)
     .thenComparing(Book::getPrice)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

此代码仅排序。

Dea*_*ool 5

首先,您可以按Book名称进行分组并将它们收集到Map<String, List<Book>>,然后map.values()从每种类型中收集最高价格的书

List<Book> books = list.stream()
                       .collect(Collectors.groupingBy(Book::getName))
                       .values()
                       .stream()
                       .map(book -> Collections.max(book, Comparator.comparingInt(Book::getCost)))
                       .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

Collectors.toMap与收集和查找最大元素相比,@Holger 使用的另一种解决方案将更有效

List<Book> books = list.stream()
            .collect(Collectors.collectingAndThen(
                    Collectors.toMap(Book::getName, Function.identity(),
                            BinaryOperator.maxBy(Comparator.comparingInt(Book::getCost))),
                    m -> new ArrayList<>(m.values())));
Run Code Online (Sandbox Code Playgroud)

  • 人们也可以使用“分组”和“减少”来在一个收集操作中执行比较,然后进一步从中获取值。据我回忆和联系,最好使用“toMap”而不是这样的分组和归约组合。再次链接[问答](/sf/ask/3992932751/)。 (2认同)
  • 简而言之, `List&lt;Book&gt; books = list.stream() .collect(Collectors.collectingAndThen( Collectors.toMap(Book::getName, Function.identity(), BinaryOperator.maxBy( Comparator.comparing(Book::getPrice)) )), m -&gt; new ArrayList&lt;&gt;(m.values())));` (2认同)