如今有一個商品地址對象的集合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 }
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 }
首先想到的是使用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 }