我只是想玩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;
}
答案 0 :(得分:1)
您可以这样做:
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
。 :)
答案 1 :(得分:1)
要找到所有阅读最便宜的书(复数)的学生(复数),您首先需要找到最便宜的价格,然后找到按此价格有书的学生。
int minPrice = students.stream()
.flatMap(s -> s.getBookSet().stream())
.mapToInt(Book::getPrice)
.min().orElse(Integer.MIN_VALUE);
List<Student> studentsHavingBookWithMinPrice = students.stream()
.filter(s -> s.getBookSet().stream().anyMatch(b -> b.getPrice() == minPrice))
.collect(Collectors.toList());
如果没有书籍,orElse(Integer.MIN_VALUE)
将确保结果列表为空。比getAsInt()
更好,如果没有书籍,后者会引发异常。