如何用Java Stream实现根据作者年龄筛选对应关联书籍的方法
前置注意
你需要先为三个类的私有属性补充对应的公共Getter方法,否则流操作无法读取属性值:
Author类添加getId()、getAge()Book类添加getAuthorId()
最优实现方案
这里推荐分两步实现,兼顾可读性和运行效率:
import java.util.List; import java.util.Set; import java.util.stream.Collectors; public List<Book> getBooksByAuthorAge(int age) { // 第一步:直接筛选出符合年龄的作者ID,存入HashSet提升后续匹配效率 Set<String> targetAuthorIds = authorList.stream() .filter(author -> author.getAge() == age) .map(Author::getId) .collect(Collectors.toSet()); // 第二步:过滤图书列表,匹配作者ID即可 return bookList.stream() .filter(book -> targetAuthorIds.contains(book.getAuthorId())) .collect(Collectors.toList()); }
方案说明
- 相比你原来的写法,省去了中间存储
Author对象列表的步骤,直接映射为ID集合,减少不必要的内存占用 - 用
Set代替List存储ID集合,匹配图书时的contains操作时间复杂度从O(n)降到O(1),作者和图书数据量越大,效率优势越明显 - 两步拆分逻辑清晰,后续维护成本低,比强行合并成单行流的可读性好很多
注意:不推荐强行把逻辑合并为单一流操作(如下写法),这种写法每过滤一本图书都要遍历一次作者列表,时间复杂度为O(图书数量*作者数量),数据量稍大就会出现性能问题:
// 效率极低的错误示范 public List<Book> getBooksByAuthorAge(int age) { return bookList.stream() .filter(book -> authorList.stream() .anyMatch(author -> author.getAge() == age && author.getId().equals(book.getAuthorId()))) .collect(Collectors.toList()); }
内容的提问来源于stack exchange,提问作者Fox_H_Adams
相关产品推荐
相关产品推荐

