一、前言

通常会需要使用到对象和Map互相转换的开发场景,下面这篇文章主要给大家介绍了关于java对象list使用stream根据某一个属性转换成map的3种方式,需要的朋友可以参考下。

二、将List转换为Map,键为某个属性,值为对象本身

List<User> userList = ... //Person对象的List
Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getName, Function.identity()));

将User对象的List转换成Map。key为name属性,值为User对象。

三、将List转换为Map,键为对象本身,值为某个属性

List<User> userList = ... //Person对象的List
Map<User, String> userMap = list.stream().collect(Collectors.toMap(Function.identity(), User::getName));

将User对象的List转换成Map。key为User对象,值为name属性。

四、将List转换为Map,键为某个属性,值为某个属性

List<User> userList = ... //Person对象的List
Map<String, Integer> map = list.stream().collect(Collectors.toMap(User::getName, User::getAge));

将User对象的List转换成Map。key为name属性,值为age属性。

五、总结

无论使用哪种方式,都可以使用Java 8的Stream API将List转换为Map,并根据某个属性作为键或值。需要注意的是,在将List转换为Map时,键必须是唯一的,否则将会抛出异常。

六、注意

1、key 可能存在重复的问题,这个时候 重复 key 保留旧值(或新值)

Map<Long, User> userMap = list.stream()
             .collect(Collectors.toMap(User::getId,Function.identity(),
             (oldV, newV) -> oldV)); // 保留旧值

2、空指针安全

如果 getId 可能为 null,先 .filter(Objects::nonNull) 再收集,或者使用 Collectors.groupingBy 容忍 null key。

3、一对多(一个key 对应多个元素),按 key 分组

class OrderDetail {
    private Long orderId;   // 订单号(作为分组 key)
    private String sku;
    private Integer qty;
    // 省略构造/getter


    public Long getOrderId() {
        return orderId;
    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    public OrderDetail(Long orderId, String sku, Integer qty) {
        this.orderId = orderId;
        this.sku = sku;
        this.qty = qty;
    }

    @Override
    public String toString() {
        return "OrderDetail{" +
                "orderId=" + orderId +
                ", sku='" + sku + '\'' +
                ", qty=" + qty +
                '}';
    }

    public static void main(String[] args) {
        List<OrderDetail> detailList = Arrays.asList(
                new OrderDetail(1L, "A001", 2),
                new OrderDetail(1L, "A002", 1),
                new OrderDetail(2L, "B101", 3),
                new OrderDetail(2L, "B102", 4)
        );

       // 一对多分组:key = orderId,value = 属于该订单的所有明细列表
        Map<Long, List<OrderDetail>> orderDetailMap =
                detailList.stream()
                        .collect(Collectors.groupingBy(OrderDetail::getOrderId));

        System.out.println(orderDetailMap);

        // 使用示例
        List<OrderDetail> order1Details = orderDetailMap.get(1L); // 包含两条明细
        System.out.println(order1Details);
    }
}


输出结果:

{1=[OrderDetail{orderId=1, sku='A001', qty=2}, OrderDetail{orderId=1, sku='A002', qty=1}], 2=[OrderDetail{orderId=2, sku='B101', qty=3}, OrderDetail{orderId=2, sku='B102', qty=4}]}

[OrderDetail{orderId=1, sku='A001', qty=2}, OrderDetail{orderId=1, sku='A002', qty=1}]


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐