Java-Stream -在应用Collector groupingBy后将对象列表收集到一个string集合中.<



给定下列OrderItem类以及Orders的列表

@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内部使用的收集器。