JDK1.8 Stream之toMap和groupingBy全參數的使用

如今有一個商品地址對象的集合List<ProductAddress> productAddresses,該集合中productId和addressId是一對多的關係app

 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>>spa

傳統方法

 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的集合code

傳統方法

 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的後兩個參數完成對象到具體字段的映射能夠優雅實現blog

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 } 
相關文章
相關標籤/搜索