java 8 stream collect max对象和distinct by属性

java 8 stream collect max对象和distinct by属性,java,foreach,java-8,java-stream,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

这里有一些清单

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));
}
每个元素

list .stream().distinct()
     .sorted(Comparator.comparing(Book::bookname)
     .thenComparing(Book::getPrice)).collect(Collectors.toList());

此代码仅排序。

首先,您可以在
Book
name上进行分组,并将它们收集到
Map
,然后从
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());

“distinct and then using”排序意味着将选择所有不同的书籍(不仅仅是名称),进一步排序仍然不会删除输入列表中的其他条目,直到您以某种方式减少它们。进一步基于期望的输出,这不应该是一条路要走

相反,您可以使用
bookName
作为属性来检查唯一性,然后合并这些书籍,比较它们的价格,并将它们收集到我们的最终结果

对于您所期待的内容,一个相当简单的代码是使用
toMap
,例如:

List<Book> distinctMaxPriceBooks = new ArrayList<>(list.stream()
        .collect(Collectors.toMap(Book::getBookName, Function.identity(),
                (b1, b2) -> b1.getPrice() >= b2.getPrice() ? b1 : b2))
        .values());
List distinctMaxPriceBooks=newarraylist(List.stream())
.collect(Collectors.toMap(Book::getBookName,Function.identity(),
(b1,b2)->b1.getPrice()>=b2.getPrice()?b1:b2)
.values());

当然,如果名称符合要求,则可以根据名称对其进行排序。

一个使用
max
方法并打印排序结果的版本

 list.stream()
        .collect(Collectors.groupingBy(Book::getaString))
        .values()
        .stream()
            .map( (books) -> books.stream().max(Comparator.comparingInt(Book::getaNumber)).get())
            .sorted(Comparator.comparingInt(Book::getaNumber))
            .forEach(System.out::println);

请出示
书籍
课程的代码。您是否在其中覆盖了
equals
hashCode
?Book是示例类
私有字符串bookname;私人字符串价格完成@user3066285-ernest_k最感兴趣的是
equals
hashcode
实现,如果您因为在示例代码中使用了
distinct
而覆盖了它们。谢谢。您节省了我的时间。您可以使用
分组
减少
在一个收集操作中执行比较,然后进一步从中获取值。正如我回忆和叙述的那样,最好使用
toMap
而不是这样的分组和减少组合。再次链接。简而言之,
List books=List.stream().collect(Collectors.collectingAndThen(Collectors.toMap(Book::getName,Function.identity(),binarymoperator.maxBy(Comparator.comparating(Book::getPrice))),m->newarrarylist(m.values())谢谢@Holger我试过类似的东西但你成功了
List<Book> distinctMaxPriceBooks = new ArrayList<>(list.stream()
        .collect(Collectors.toMap(Book::getBookName, Function.identity(),
                (b1, b2) -> b1.getPrice() >= b2.getPrice() ? b1 : b2))
        .values());
 list.stream()
        .collect(Collectors.groupingBy(Book::getaString))
        .values()
        .stream()
            .map( (books) -> books.stream().max(Comparator.comparingInt(Book::getaNumber)).get())
            .sorted(Comparator.comparingInt(Book::getaNumber))
            .forEach(System.out::println);