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