[英]Java-Stream - How Collecor groupingBy() to split a Map into multiple Submaps
[英]Java-Stream - Collect a List of objects into a Set of Strings after applying Collector groupingBy
給定以下類Order
和Item
以及Order
的列表。
@Getter
@AllArgsConstructor
@ToString
public class Order {
String customerName;
List<Item> items;
}
@Getter
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class Item {
long id;
String name;
}
我需要創建一個地圖Map<String,Set<String>> itemsByCustomerName
,其中鍵是Order
中的客戶名稱以及屬於客戶名稱的所有Item
的一組名稱。
輸入示例:
List<Order> orders = List.of(
new Order("John", List.of(new Item(1, "A"), new Item(2, "B"), new Item(3, "C"))),
new Order("Alex", List.of(new Item(1, "A"), new Item(8, "H"), new Item(11, "K"))),
new Order("John", List.of(new Item(1, "A"), new Item(6, "F"), new Item(7, "G"))),
new Order("Alex", List.of(new Item(1, "A"), new Item(8, "H"), new Item(12, "L"))),
new Order("Dave", List.of(new Item(24,"X"), new Item(25,"Y"), new Item(26, "Z"))));
所需的輸出將是
{Alex=[A, H, K, L], John=[A, B, C, F, G], Dave=[X, Y, Z]}
我已經嘗試了很多方法,包括我在下面的最后一次嘗試,但是得到了編譯錯誤
Map<String, Set<String>> itemsByCustomerName =
orders.stream().collect(groupingBy(
Order::getCustomerName,
mapping(order -> order.getItems().stream().map(Item::getName), toSet())));
錯誤:
Required type:
Map<String, Set<String>>
Provided:
Map<String, Set<Object>>
no instance(s) of type variable(s) R exist so that Stream<R> conforms to String inference variable T
has incompatible bounds: equality constraints: String lower bounds: Stream<R81591>
我怎樣才能得到而不只是按名稱的訂單地圖:
Map<String, List<Order>> ordersByName =
orders.stream().collect(groupingBy(Order::getCustomerName));
到帶有一組項目名稱的Map<String, Set<Item>>
或更好的Map<String, Set<String>>
?
所以,我的問題是:如何在應用groupingBy
后將訂單列表轉換為一組項目名稱?
你非常親近。
由於您不需要將流元素轉換為單個對象,而是從order中提取項目集合,因此您需要一個不同的收集器- flatMapping()
而不是mapping()
。
Map<String, Set<String>> itemsByCustomerName =
orders.stream().collect(Collectors.groupingBy(
Order::getCustomerName,
Collectors.flatMapping(order -> order.getItems().stream().map(Item::getName),
Collectors.toSet())));
Collectors.groupingBy(Order::getCustomerName, Collectors.toSet())
在這種情況下應該可以工作。 這里的第二個參數是groupingBy內部使用的收集器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.