平時工作中,總會遇到一些數據結構的封裝調用,例如(1)List 基礎數據類型的集合去重;(2)再或者根據對象的某個屬性,多個屬性去重;(3)List 集合轉換為 Map 集合或者 Set集合等等;今天有時間總結一下Java8中常用的集合轉換!
基礎數據

@Data @AllArgsConstructor @NoArgsConstructor @ToString static class Product { private Integer num; private String productName; private BigDecimal price; private String description; } private static List<Product> BASE_DATAS = Lists.newArrayList( new Product(1, "蝦條", new BigDecimal(3.5), "非常好吃"), new Product(2, "蝦條", new BigDecimal(3.5), "非常好吃"), new Product(3, "果凍", new BigDecimal(5.5), "甜甜的"), new Product(4, "果凍", new BigDecimal(5.5), "甜甜的1"), new Product(5, "果凍", new BigDecimal(6.0), "甜甜的"), new Product(6, "瓜子", new BigDecimal(6.0), "脆脆的"), new Product(7, "瓜子", new BigDecimal(6.0), "脆脆的") );
一、List 對象集合根據某個屬性去重
/** * 根據對象的某個屬性去重 */ private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Map<Object, Boolean> seen = new ConcurrentHashMap<>(); return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } // 根據 Product 類中的一個屬性去重 List<Product> productNames = BASE_DATAS.stream().filter(distinctByKey(Product::getProductName)).collect(Collectors.toList());
productNames.forEach(System.out::println);
結果:
CollectorsUtil.Product(num=1, productName=蝦條, price=3.5, description=非常好吃) CollectorsUtil.Product(num=3, productName=果凍, price=5.5, description=甜甜的) CollectorsUtil.Product(num=6, productName=瓜子, price=6, description=脆脆的)
二、List 對象集合根據多個屬性去重
// 根據 Product 中多個屬性去重 List<Product> products = BASE_DATAS.stream() .collect(Collectors.collectingAndThen( Collectors.toCollection( () -> new TreeSet<>(Comparator.comparing( tc -> tc.getProductName() + ";" + tc.getDescription()))), ArrayList::new)); // 需要設置多個去重的字段信息 products.forEach(System.out::println);
結果:
CollectorsUtil.Product(num=3, productName=果凍, price=5.5, description=甜甜的) CollectorsUtil.Product(num=4, productName=果凍, price=5.5, description=甜甜的1) CollectorsUtil.Product(num=6, productName=瓜子, price=6, description=脆脆的) CollectorsUtil.Product(num=1, productName=蝦條, price=3.5, description=非常好吃)
三、List 轉換為 Map 集合
1)List 封裝為 Map 集合,key = 某個屬性 value = List<對象>
// 根據 Product 中的 ProductName 封裝 Map 集合【key => productName value => List<Product>】 Map<String, List<Product>> productNameMap = BASE_DATAS.stream().collect(Collectors.groupingBy(Product::getProductName)); for (String key : productNameMap.keySet()) { System.out.println(key); List<Product> products1 = productNameMap.get(key); products1.forEach(System.out::println); }
結果:
果凍 CollectorsUtil.Product(num=3, productName=果凍, price=5.5, description=甜甜的) CollectorsUtil.Product(num=4, productName=果凍, price=5.5, description=甜甜的1) CollectorsUtil.Product(num=5, productName=果凍, price=6, description=甜甜的) 蝦條 CollectorsUtil.Product(num=1, productName=蝦條, price=3.5, description=非常好吃) CollectorsUtil.Product(num=2, productName=蝦條, price=3.5, description=非常好吃) 瓜子 CollectorsUtil.Product(num=6, productName=瓜子, price=6, description=脆脆的) CollectorsUtil.Product(num=7, productName=瓜子, price=6, description=脆脆的)
2)List 封裝為 Map 集合,key = 某個屬性 value = 某個屬性【前提條件:key = 某個屬性,這個屬性的值要唯一,否則會拋異常 java.lang.IllegalStateException: Duplicate key ......】
// 根據 Product 中的 num 封裝 Map 集合【key => num value => product】 Map<Integer, Product> productNumMap = BASE_DATAS.stream().collect(Collectors.toMap(Product::getNum, Function.identity())); for (Integer key : productNumMap.keySet()) { System.out.println("key = " + key + ", value = " + productNumMap.get(key)); }
結果:
key = 1, value = CollectorsUtil.Product(num=1, productName=蝦條, price=3.5, description=非常好吃) key = 2, value = CollectorsUtil.Product(num=2, productName=蝦條, price=3.5, description=非常好吃) key = 3, value = CollectorsUtil.Product(num=3, productName=果凍, price=5.5, description=甜甜的) key = 4, value = CollectorsUtil.Product(num=4, productName=果凍, price=5.5, description=甜甜的1) key = 5, value = CollectorsUtil.Product(num=5, productName=果凍, price=6, description=甜甜的) key = 6, value = CollectorsUtil.Product(num=6, productName=瓜子, price=6, description=脆脆的) key = 7, value = CollectorsUtil.Product(num=7, productName=瓜子, price=6, description=脆脆的)
四、List 轉換為 Set 集合
// 根據 Product 中商品名稱去重,展示商品名稱 Set<String> productNames = BASE_DATAS.stream().map(Product::getProductName).collect(Collectors.toSet()); for (String productName : productNames) { System.out.println(productName); }
結果:
蝦條
果凍
瓜子
List 中對象某個屬性去重后,按照字符 - 拼接
// 根據 Product 中商品名稱,使用 - 連接符連接 String productName = BASE_DATAS.stream().map(Product::getProductName).distinct().collect(Collectors.joining("-")); System.out.println(productName); 結果:蝦條-果凍-瓜子
每天進步一點點。。。。