Java 8流图自定义函数并转换为Map
Java 8 stream map custom function and convert it to Map
我有以下对象:
public class Book {
private Long id;
private Long bookId;
private String bookName;
private String owner;
}
来自以下 table 的代表:
基本上,一本书可以由多个所有者拥有,即所有者“a”拥有书 1 和 2。
我有一个基本功能,当传递一个书籍对象时,将在一个列表中给出它的所有者。
private List<String> getBookToOwner(Book book) {
List<String> a = new ArrayList<>();
if (book.getOwner() != null && !book.getOwner().isEmpty()) {
a.addAll(Arrays.asList(book.getOwner().split("/")));
}
return a;
}
我想用它来应用于每本书,检索它们的所有者并创建以下地图。
Map<String, List<Long>> ownerToBookMap;
像这样:
如何在这里使用流?
//books is List<Book>
Map<String, List<Long>> ownerToBookMap = books.stream().map(
// apply the above function to get its owners, flatten it and finally collect it to get the above Map object
// Need some help here..
);
我使用 reduce
而不是 map
。
Map<String, List<Long>> ownerToBookMap = books.stream().reduce(
HashMap::new,
(acc,b) -> {
getBookToOwner(b).stream().forEach( o -> {
if (!acc.containsKey(o))
acc.put(o, new ArrayList<Long>());
acc.get(o).put(b.bookId);
});
return acc;
}
).get();
将所有者平面映射为一个,创建条目,键为 单个 owner
,值为 bookId
。然后按键 (owner
) 对结构进行分组。最后使用 Collectors::mapping
获取 bookId
的 List
而不是实际条目:
List<Book> books = ...
Map<String, List<Long>> booksByOwner = books.stream()
.flatMap(book -> Arrays.stream(book.getOwner().split("/"))
.map(owner -> new AbstractMap.SimpleEntry<>(owner, book.getBookId())))
.collect(Collectors.groupingBy(
AbstractMap.SimpleEntry::getKey,
Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList())));
您可以从书中获取所有者列表,然后使用 flatMap
将所有者和地图拼合为 bookId
和 owner
对。然后使用 groupingBy
按 owner
分组并收集 owner
的 bookId
列表。
Map<String, List<Long>> ownerToBookMap =
books.stream()
.flatMap(b -> getBookToOwner(b)
.stream()
.map(o -> new AbstractMap.SimpleEntry<>(o, b.getBookId())))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
我有以下对象:
public class Book {
private Long id;
private Long bookId;
private String bookName;
private String owner;
}
来自以下 table 的代表:
基本上,一本书可以由多个所有者拥有,即所有者“a”拥有书 1 和 2。
我有一个基本功能,当传递一个书籍对象时,将在一个列表中给出它的所有者。
private List<String> getBookToOwner(Book book) {
List<String> a = new ArrayList<>();
if (book.getOwner() != null && !book.getOwner().isEmpty()) {
a.addAll(Arrays.asList(book.getOwner().split("/")));
}
return a;
}
我想用它来应用于每本书,检索它们的所有者并创建以下地图。
Map<String, List<Long>> ownerToBookMap;
像这样:
如何在这里使用流?
//books is List<Book>
Map<String, List<Long>> ownerToBookMap = books.stream().map(
// apply the above function to get its owners, flatten it and finally collect it to get the above Map object
// Need some help here..
);
我使用 reduce
而不是 map
。
Map<String, List<Long>> ownerToBookMap = books.stream().reduce(
HashMap::new,
(acc,b) -> {
getBookToOwner(b).stream().forEach( o -> {
if (!acc.containsKey(o))
acc.put(o, new ArrayList<Long>());
acc.get(o).put(b.bookId);
});
return acc;
}
).get();
将所有者平面映射为一个,创建条目,键为 单个 owner
,值为 bookId
。然后按键 (owner
) 对结构进行分组。最后使用 Collectors::mapping
获取 bookId
的 List
而不是实际条目:
List<Book> books = ...
Map<String, List<Long>> booksByOwner = books.stream()
.flatMap(book -> Arrays.stream(book.getOwner().split("/"))
.map(owner -> new AbstractMap.SimpleEntry<>(owner, book.getBookId())))
.collect(Collectors.groupingBy(
AbstractMap.SimpleEntry::getKey,
Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList())));
您可以从书中获取所有者列表,然后使用 flatMap
将所有者和地图拼合为 bookId
和 owner
对。然后使用 groupingBy
按 owner
分组并收集 owner
的 bookId
列表。
Map<String, List<Long>> ownerToBookMap =
books.stream()
.flatMap(b -> getBookToOwner(b)
.stream()
.map(o -> new AbstractMap.SimpleEntry<>(o, b.getBookId())))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));