Java-Stream - 将一个对象列表收集成一个Set字符串,应用Collector groupingBy。

3
考虑到下面的类`Order`和`Item`以及一组订单列表,请翻译以下内容:

给定以下类OrderItem,以及一组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));

如何将一个订单列表(list of orders)应用 groupingBy 后转换为包含商品名称的集合?是否需要将其转换为 Map<String, Set<Item>> 或更好的 Map<String, Set<String>> 形式?

2个回答

6

你已经非常接近了。

由于你需要从 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())));

0

Collectors.groupingBy(Order::getCustomerName, Collectors.toSet())在这种情况下应该是有效的。这里的第二个参数是由groupingBy内部使用的收集器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接