问题描述
我正在使用Java 8。
我有以下对象:
public class Book {
private Long id;
private Long bookId;
private String bookName;
private String owner;
}
基本上,一本书可以由多个所有者拥有,即所有者“ a”拥有第一和第二本书。
我有一个基本功能,当传递书对象时,它将在列表中给出其所有者。
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..
);
解决方法
您可以从书中获得所有者列表,然后展平所有者并使用bookId
映射成owner
和flatMap
对。然后使用owner
按groupingBy
分组,并收集bookId
中owner
的列表。
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())));
,
我使用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();
,
将所有者平面映射为一个,将键创建为单个 date_counter = 5
pre_date = df.Date[0]
epic_week = 9
df["epic_week"] = 0
for index,rows in df.iterrows():
if rows["Date"] != pre_date:
date_counter += 1
pre_date = rows["Date"]
if date_counter > 7:
date_counter = 1
epic_week += 1
rows["epic_week"] = epic_week
,将值创建为owner
。然后通过键(bookId
)对结构进行分组。最后使用owner
来获得Collectors::mapping
中的List
而不是实际的条目:
bookId