Java8 中根据对象属性去重-集合之间转换
平时工作中,总会遇到一些数据结构的封装调用,例如(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); 结果:虾条-果冻-瓜子
每天进步一点点。。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架