一种选择是使用Collectors.toMap()
使用title
and pages
值作为键。如果发现重复项,您可以合并两个列表:
Collection<Book> result = list.stream()
.collect(Collectors.toMap(
b -> Map.entry(b.getTitle(), b.getPages()),
b -> new Book(b.getTitle(), b.getPages(), b.getList()),
(b1, b2) -> new Book(b1.getTitle(), b1.getPages(),
Stream.concat(b1.getList().stream(), b2.getList().stream()).collect(Collectors.toList())),
LinkedHashMap::new))
.values();
或者你可以使用Collectors.groupingBy()
:
List<Book> result = list.stream().collect(
Collectors.groupingBy(b -> Map.entry(b.getTitle(), b.getPages()), LinkedHashMap::new,
Collectors.flatMapping(b -> b.getList().stream(), Collectors.toList())))
.entrySet().stream()
.map(e -> new Book(e.getKey().getKey(), e.getKey().getValue(), e.getValue()))
.collect(Collectors.toList());
第二种方法使用创建地图title
and pages
作为键并使用合并所有书籍的列表Collectors.flatMapping()
。之后,将条目映射回 Book 对象。
如果您无法使用Collectors.flatMapping()
使用 Collectors.mapping()` 代替:
List<Book> r = list.stream().collect(
Collectors.groupingBy(b -> Map.entry(b.getTitle(), b.getPages()), LinkedHashMap::new,
Collectors.mapping(Book::getList, Collectors.toList())))
.entrySet().stream()
.map(e -> new Book(e.getKey().getKey(), e.getKey().getValue(),
e.getValue().stream().flatMap(Collection::stream).collect(Collectors.toList())))
.collect(Collectors.toList());
如果您无法使用Map.entry()
use new AbstractMap.SimpleEntry<>()
反而。
两种情况的结果都是这样的:
Book[title='Core Java', pages=200, list=[Page 1, Page 2]]
Book[title='Learning Freemarker', pages=150, list=[Page 15]]
Book[title='Spring MVC', pages=300, list=[Page 16, Page 17]]