如何使用java lambda stream:给出一个拥有书籍的学生列表,查找所有阅读最便宜书籍的学生

如何使用java lambda stream:给出一个拥有书籍的学生列表,查找所有阅读最便宜书籍的学生,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我只是想和lambda和stream玩一玩。假设我有一个图书列表域,其中有一套图书。我想找出谁在读最便宜的书。我应该可以得到最低价格的书。我可以得到最低价格的书,但我如何得到学生的名字 编辑:我更新如下。还有更好的办法吗 供应商学生列表供应商=()->{ 返回createStudentList2(); }; BookBookWithMinPrice=studentListSupplier.get().stream().flatMap(sl->sl.getBookSet().stream()).m

我只是想和lambda和stream玩一玩。假设我有一个图书列表域,其中有一套图书。我想找出谁在读最便宜的书。我应该可以得到最低价格的书。我可以得到最低价格的书,但我如何得到学生的名字

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

供应商学生列表供应商=()->{
返回createStudentList2();
};
BookBookWithMinPrice=studentListSupplier.get().stream().flatMap(sl->sl.getBookSet().stream()).min(new BookComparator()).get();
列出StudentShungBookWithMinPrice=new ArrayList();
studentListSupplier.get().forEach(s->{
如果(s.getBookSet()包含(bookWithMinPrice)){
带最小价格的学生预订。添加;
}
});
班级学生{
私有字符串名称;
私人套装书;
////
}
课堂用书{
国际价格;
字符串名;
////  
}
//数据集
私有静态列表createStudentList2(){
Set bookSet1=新的HashSet();
图书b11=新书(10,“AAA”);
bookSet1.add(b11);
b12册=新书(20,“BBB”);
bookSet1.add(b12);
Set bookSet2=新的HashSet();
图书b21=新书(30,“XXX”);
书店2.add(b21);
图书b22=新书(15,“ZZZ”);
bookSet2.add(b22);
图书b23=新书(10,“KKA”);
书店2.add(b23);
学生s1=新学生();
s1.设置书架集(书架1);
s1.设定名称(“s1”);
学生s2=新学生();
s2.setBookSet(书店2);
s2.设定名称(“s2”);
学生s3=新学生();
s3.setBookSet(bookSet1);
s3.设定名称(“s3”);
List studentListWithBooks=Arrays.asList(s1、s2、s3);
用书本归还学生名单;
}
您可以这样做:

Student studentWithCheapestBook = students.stream()
    .min(comparingInt(s -> Collections.min(s.getBookSet(), comparingInt(Book::getPrice)).getPrice()))
    .orElse(null);
收集器。将其作为静态导入进行比较

除了
comparingit(Book::getPrice)
之外,您还可以使用
bookcompariator
:)

如果你需要所有的学生,那么你不能用一个流来完成。你需要先计算最便宜的价格,然后相应地过滤学生名单

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()));
int cheapestPrice=students.stream()
.flatMap(s->s.getBookSet().stream())
.mapToInt(Book::getPrice)
.min().orElse(0);
Set readingCheapestBooks=students.stream()
.collect(筛选)(s->s.getBookSet().stream()).anyMatch(b->b.getPrice()要查找所有阅读最便宜书籍(复数)的学生,首先需要查找最便宜的价格,然后查找以该价格拥有书籍的学生

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());
int minPrice=students.stream()
.flatMap(s->s.getBookSet().stream())
.mapToInt(Book::getPrice)
.min().orElse(整数.min_值);
列出StudentShungBookWithMinPrice=students.stream()
.filter(s->s.getBookSet().stream().anyMatch(b->b.getPrice()==minPrice))
.collect(Collectors.toList());

orElse(Integer.MIN_值)
确保没有书籍时结果列表为空。比
getAsInt()更好
如果没有书,这会引发异常。

你在找什么?找到所有书的最低价格,然后列出拥有该价格的书的学生?或者为每个学生找到他们拥有的最便宜的书?或者为每本书(按名称),找到那本书最便宜的价格,然后列出以该价格拥有这本书的学生?既然找到了最便宜的价格书,我能找到拥有那本书的学生吗?或者有其他方法吗..请输入代码片段..哪一部分让你不安?迭代所有学生?迭代所有书籍?找到最低价格?找到有一本这样价格的书吗?请自己尝试一下。这样你会学到很多东西。如果你不知道如何使用流,请先尝试使用
for
循环。好的:)找到了。我们必须迭代列表,然后用contains检查inset。会更新。但有更好的方法吗?“用contains检查”??你为什么要这样做?——“有更好的方法吗?”比什么更好?你还没有展示你的完整解决方案。我将检查你的解决方案。我更新了上面的尝试。如果有多个学生以最低价格购买一本书怎么办?@VivekMisra什么是有多本最低价格的书?例如,约翰有“傻瓜景观设计”0.50美元,史蒂夫有“傻瓜园艺”价格是0.50美元。它们不是都应该退回吗?你必须比较价格,而不是书籍,这就是为什么当你提到使用
contains
时我最初感到困惑的原因。我想我的代码已经首先找到了最便宜的价格书。编辑:是的,如果有多本书的最低价格,那么它会增加复杂性。我不确定简单的解决方案复杂度较低。第一种解决方案对性能不好,因为它可能会多次调用同一个学生的
Collections.min
。但如果有多本书价格相同,我们将需要修改。@VivekMisra是否有一本或多本书价格最便宜并不重要价格。这两种方法都可以。@Michael那么为什么代码给我的结果是只有学生s1和s3有最便宜的书。如果你看到数据集,所有三个s1、s2和s3都有价格为10的最便宜的书。(我更新了OP并添加了数据集)。它还应该给我买两本最便宜的书10。@VivekMisra使用哪种解决方案?我指的是这个答案和我自己的答案中概述的方法。然后你得到s1、s2和s3。@Andreas我可能在尝试不同的数据集时为你的解决方案使用了错误的数据。它现在返回正确。你和Mic的两次尝试海尔很好,几乎一样。(但只有一个能被接受:)