java - 如何使用 java lambda 流 :Given a list of students having books, 查找所有正在阅读最便宜书籍的学生

标签 java lambda java-8 java-stream

我只是想玩弄 lambda 和流。假设我有一组书籍域的书籍列表。我想找出正在读最便宜的书的学生姓名。我应该能够以最低价格获得这本书。我能够以最低价格获得这本书,但是我如何获得学生姓名?

编辑:我更新如下。还有更好的办法吗?

    Supplier<List<Student>> studentListSupplier = () -> {
            return createStudentList2();
        };
        Book bookWithMinPrice=studentListSupplier.get().stream().flatMap(sl->sl.getBookSet().stream()).min(new BookComparator()).get();
        List<Student> studentsHavingbookWithMinPrice = new ArrayList<>();
        studentListSupplier.get().forEach(s->{
            if(s.getBookSet().contains(bookWithMinPrice)){
                studentsHavingbookWithMinPrice.add(s);
            }

        });


class Student {
    private String name;
    private Set<Book> bookSet;
    ////
}

class Book {
    int price;
    String name;
    ////  
}
 //DataSet
private static List<Student> createStudentList2() {
        Set<Book> bookSet1 =   new HashSet<>();
        Book b11=new Book(10, "AAA");
        bookSet1.add(b11);
        Book b12= new Book(20, "BBB");
        bookSet1.add(b12);

        Set<Book> bookSet2 =   new HashSet<>();
        Book b21=new Book(30, "XXX");
        bookSet2.add(b21);
        Book b22= new Book(15, "ZZZ");
        bookSet2.add(b22);
        Book b23 =  new Book(10, "KKA");
        bookSet2.add(b23);

        Student s1 = new Student();
        s1.setBookSet(bookSet1);
        s1.setName("s1");

        Student s2 = new Student();
        s2.setBookSet(bookSet2);
        s2.setName("s2");

        Student s3 = new Student();
        s3.setBookSet(bookSet1);
        s3.setName("s3");

        List<Student> studentListWithBooks = Arrays.asList(s1,s2,s3);
        return studentListWithBooks;
    }

最佳答案

你可以这样做:

Student studentWithCheapestBook = students.stream()
    .min(comparingInt(s -> Collections.min(s.getBookSet(), comparingInt(Book::getPrice)).getPrice()))
    .orElse(null);

Collectors.comparingInt 作为静态导入。

除了使用 comparingInt(Book::getPrice) 之外,您还可以使用 BookComparator。 :)

如果您需要所有学生,那么您无法通过一个流来完成。您需要先计算最便宜的价格,然后相应地过滤学生列表。

int cheapestPrice = students.stream()
    .flatMap(s -> s.getBookSet().stream())
    .mapToInt(Book::getPrice)
    .min().orElse(0);

Set<Student> readingCheapestBooks = students.stream()
    .collect(filtering(s -> s.getBookSet().stream().anyMatch(b -> b.getPrice() <= cheapestPrice), 
             toSet()));

我刚刚发现从 Java 9 开始就有了一个Collectors.filtering。 :)

关于java - 如何使用 java lambda 流 :Given a list of students having books, 查找所有正在阅读最便宜书籍的学生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57118165/

相关文章:

java - 需要从 jboss 6.4 模块中排除 apache httpcomponent

java - 如何确定 Wildfly 10 支持的密码套件

java - 通过聚合和分组将一个对象映射到另一个对象

java - 有没有办法压缩两个流?

java - 将 XMLGregorianCalendar 转换为日期,即 "MM/DD/YYYY hh:mm:ss AM"

检查整个多行 HTML header 时 HTML 状态代码的 Java 正则表达式

java - 如何在 ANDROID 中使用 XSLT 将 XML 转换为 HTML?

python - 将使用 lambda 解包的元组从 Python 2 移植到 Python 3 的大多数 pythonic 方法

scala - 更新元组列表

Python "with"Lambda 函数中的关键字