zoukankan      html  css  js  c++  java
  • JDK1.8 Stream之toMap和groupingBy全参数的使用

    现在有一个商品地址对象的集合List<ProductAddress> productAddresses,该集合中productId和addressId是一对多的关系

     1 @Data
     2 @AllArgsConstructor
     3 class ProductAddress {
     4     private int productId;
     5 
     6     private int addressId;
     7 
     8     private static List<ProductAddress> productAddresses;
     9 
    10     static {
    11         productAddresses = new ArrayList<>();
    12         productAddresses.add(new ProductAddress(1001, 1));
    13         productAddresses.add(new ProductAddress(1001, 2));
    14         productAddresses.add(new ProductAddress(1001, 3));
    15         productAddresses.add(new ProductAddress(1002, 3));
    16         productAddresses.add(new ProductAddress(1002, 4));
    17         productAddresses.add(new ProductAddress(1003, 5));
    18     }
    19 }

    需求

    以productId分组变成一个Map<Integer,List<ProductAddress>>

    传统方法

     1 public static void main(String[] args) {
     2     Map<Integer, List<ProductAddress>> map = new HashMap<>();
     3     for (ProductAddress productAddress : productAddresses) {
     4         if (map.get(productAddress.getProductId()) == null) {
     5             map.put(productAddress.getProductId(), new ArrayList<>(Arrays.asList(productAddress)));
     6         } else {
     7             map.get(productAddress.getProductId()).add(productAddress);
     8         }
     9     }
    10     System.out.println(JSONObject.toJSON(map));
    11 }

    lambda表达式实现

    1 public static void main(String[] args) {
    2     Map<Integer, List<ProductAddress>> map = productAddresses.stream().collect(Collectors.groupingBy(ProductAddress::getProductId));
    3     System.out.println(JSONObject.toJSON(map));
    4 }

    新的需求

    以productId分组变成一个Map<Integer,List<Integer>>,value是其对应的addressId的集合

    传统方法

     1 public static void main(String[] args) {
     2     Map<Integer, List<Integer>> map = new HashMap<>();
     3     for (ProductAddress productAddress : productAddresses) {
     4         if (map.get(productAddress.getProductId()) == null) {
     5             map.put(productAddress.getProductId(), new ArrayList<>(Arrays.asList(productAddress.getAddressId())));
     6         } else {
     7             map.get(productAddress.getProductId()).add(productAddress.getAddressId());
     8         }
     9     }
    10     System.out.println(JSONObject.toJSON(map));
    11 }

    lambda表达式实现

    首先想到的是使用toMap把value转成list并使用toMap提供的key冲突解决办法。

     1 public static void main(String[] args) {
     2     Map<Integer, List<Integer>> map = productAddresses.stream()
     3             .collect(Collectors.groupingBy(ProductAddress::getProductId, HashMap::new,
     4                     Collectors.mapping(ProductAddress::getAddressId, Collectors.toList())));
     5     productAddresses.stream().collect(Collectors.toMap(ProductAddress::getProductId, v -> new ArrayList(Arrays.asList(v.getAddressId())), (existValue, newValue) -> {
     6         existValue.addAll(newValue);
     7         return existValue;
     8     }));
     9     System.out.println(map);
    10 }

    但感觉这个写法看起来怪怪的,琢磨groupingBy发现,使用groupingBy的后两个参数完成对象到具体字段的映射可以优雅实现

    1 public static void main(String[] args) {
    2     Map<Integer, List<Integer>> map = productAddresses.stream()
    3             .collect(Collectors.groupingBy(ProductAddress::getProductId, HashMap::new,
    4                     Collectors.mapping(ProductAddress::getAddressId, Collectors.toList())));
    5     System.out.println(map);
    6 } 
  • 相关阅读:
    图片滤镜高斯模糊
    context.Request.Files为NULL问题 在实现图片上传功能的时候出现在ashx等处理页面出现context.Request.Files为NULL异常,有几点需要注意:
    C#中使用代码动态改变配置文件信息
    缓存
    使用iframe实现图片上传预览效果
    loading 加载
    sql 查询每月的销售金额
    GridView数据格式化
    把图片转换成二进制--把二进制转换成图片
    asp.net js 倒计时总秒数量 和 排序
  • 原文地址:https://www.cnblogs.com/caizhiqin/p/9438876.html
Copyright © 2011-2022 走看看