给定下列Order
和Item
类以及Order
s的列表
@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
后将订单列表转换为项目名称集合?
你很接近了。
因为你需要转换流元素而不是但是从顺序中提取项的集合,您需要一个不同的收集器-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内部使用的收集器。