Java集合数据处理技巧:使用StreamAPI实现多种操作
- 游戏开发
- 2025-08-22 23:30:02

在 Java 开发中,对集合数据进行处理是非常常见的需求,例如去重、排序、分组、求和等。Java 8 引入的 Stream API 为我们提供了一种简洁、高效的方式来处理集合数据。本文将详细介绍如何使用 Stream API 实现多种集合数据处理操作,并给出相应的代码示例。
1. List 根据某个属性去重在处理 List 数据时,有时需要根据对象的某个属性进行去重。可以使用 TreeSet 和 Stream 来实现这一功能。以下是示例代码:
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.TreeSet; import java.util.stream.Collectors; // 定义 SKU 类 class SKU { private String gid; public SKU(String gid) { this.gid = gid; } public String getGid() { return gid; } } public class ListDistinctByProperty { public static void main(String[] args) { List<SKU> skuList = new ArrayList<>(); skuList.add(new SKU("1")); skuList.add(new SKU("2")); skuList.add(new SKU("1")); ArrayList<SKU> skus = skuList.stream().collect( Collectors.collectingAndThen( Collectors.toCollection( () -> new TreeSet<>(Comparator paring(SKU::getGid)) ), ArrayList::new ) ); skus.forEach(sku -> System.out.println(sku.getGid())); } }在上述代码中,首先创建了一个 SKU 类,包含 gid 属性。然后使用 Stream 对 skuList 进行处理,通过 Collectors.toCollection 将其转换为 TreeSet,利用 TreeSet 的特性根据 gid 去重,最后再将 TreeSet 转换为 ArrayList。
2. 指定字段排序 2.1 升序排序可以使用 Stream 的 sorted 方法和 Comparator paring 来实现指定字段的升序排序。以下是示例代码:
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; // 定义 Order 类 class Order { private long createTime; public Order(long createTime) { this.createTime = createTime; } public long getCreateTime() { return createTime; } } public class ListSortAsc { public static void main(String[] args) { List<Order> orderList = new ArrayList<>(); orderList.add(new Order(3)); orderList.add(new Order(1)); orderList.add(new Order(2)); List<Order> sortedList = orderList.stream() .sorted(Comparator paring(Order::getCreateTime)) .collect(Collectors.toList()); sortedList.forEach(order -> System.out.println(order.getCreateTime())); } } 2.2 降序排序如果需要降序排序,只需在 Comparator paring 后调用 reversed 方法。以下是示例代码:
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; // 定义 Order 类 class Order { private long createTime; public Order(long createTime) { this.createTime = createTime; } public long getCreateTime() { return createTime; } } public class ListSortDesc { public static void main(String[] args) { List<Order> orderList = new ArrayList<>(); orderList.add(new Order(3)); orderList.add(new Order(1)); orderList.add(new Order(2)); List<Order> sortedList = orderList.stream() .sorted(Comparator paring(Order::getCreateTime).reversed()) .collect(Collectors.toList()); sortedList.forEach(order -> System.out.println(order.getCreateTime())); } } 2.3 null 排前面如果需要将 null 值排在前面,可以使用 Comparator.nullsFirst 方法。以下是示例代码:
import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.stream.Collectors; // 定义 LuckyBoysVo 类 class LuckyBoysVo { private Date usageTime; public LuckyBoysVo(Date usageTime) { this.usageTime = usageTime; } public Date getUsageTime() { return usageTime; } } public class ListSortNullFirst { public static void main(String[] args) { List<LuckyBoysVo> luckyBoysList = new ArrayList<>(); luckyBoysList.add(new LuckyBoysVo(new Date(2000))); luckyBoysList.add(new LuckyBoysVo(null)); luckyBoysList.add(new LuckyBoysVo(new Date(1000))); List<LuckyBoysVo> luckyBoysVoList = luckyBoysList.stream() .sorted(Comparator paring(LuckyBoysVo::getUsageTime, Comparator.nullsFirst(Date::compareTo))) .collect(Collectors.toList()); luckyBoysVoList.forEach(vo -> System.out.println(vo.getUsageTime())); } } 3. 指定字段相同,指定值计算和可以使用 Collectors.groupingBy 方法对数据进行分组,然后使用 reduce 方法计算相同字段对应的值的和。以下是示例代码:
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; // 定义 ExportAgentVo 类 class ExportAgentVo { private String dealCode; private String agentId; private String goodsId; private String goodName; private int count; private String name; private String address; public ExportAgentVo(String dealCode, String agentId, String goodsId, String goodName, int count, String name, String address) { this.dealCode = dealCode; this.agentId = agentId; this.goodsId = goodsId; this.goodName = goodName; this.count = count; this.name = name; this.address = address; } public String getDealCode() { return dealCode; } public String getAgentId() { return agentId; } public String getGoodsId() { return goodsId; } public String getGoodName() { return goodName; } public int getCount() { return count; } public String getName() { return name; } public String getAddress() { return address; } } public class ListSumByField { public static void main(String[] args) { List<ExportAgentVo> exportAgentVoList = new ArrayList<>(); exportAgentVoList.add(new ExportAgentVo("1", "A", "G1", "Good1", 10, "Name1", "Addr1")); exportAgentVoList.add(new ExportAgentVo("2", "A", "G1", "Good1", 20, "Name1", "Addr1")); List<ExportAgentVo> exportAgentVoListResult = new ArrayList<>(); exportAgentVoList.stream() .collect(Collectors.groupingBy(o -> (o.getGoodsId() + o.getAgentId()), Collectors.toList())) .forEach((id, transfer) -> { transfer.stream() .reduce((a, b) -> new ExportAgentVo(a.getDealCode(), a.getAgentId(), a.getGoodsId(), a.getGoodName(), a.getCount() + b.getCount(), a.getName(), a.getAddress()) ) .ifPresent(exportAgentVoListResult::add); }); exportAgentVoListResult.forEach(vo -> System.out.println(vo.getCount())); } } 4. 指定字段相同,计算相同个数可以使用 Collectors.groupingBy 和 Collectors.counting 方法来计算指定字段相同的个数。以下是示例代码:
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 定义 TkDetailMaskLayerMapping 类 class TkDetailMaskLayerMapping { private String maskId; public TkDetailMaskLayerMapping(String maskId) { this.maskId = maskId; } public String getMaskId() { return maskId; } } public class ListCountByField { public static void main(String[] args) { List<TkDetailMaskLayerMapping> list = new ArrayList<>(); list.add(new TkDetailMaskLayerMapping("M1")); list.add(new TkDetailMaskLayerMapping("M1")); list.add(new TkDetailMaskLayerMapping("M2")); Map<String, Long> map = list.stream() .collect(Collectors.groupingBy(TkDetailMaskLayerMapping::getMaskId, Collectors.counting())); map.forEach((key, value) -> System.out.println(key + ": " + value)); } } 5. 指定字段分组可以使用 Collectors.groupingBy 方法对 List 进行指定字段分组。以下是示例代码:
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 定义 ExportAgentVo 类 class ExportAgentVo { private String agentId; public ExportAgentVo(String agentId) { this.agentId = agentId; } public String getAgentId() { return agentId; } } public class ListGroupByField { public static void main(String[] args) { List<ExportAgentVo> exportAgentVoListResult = new ArrayList<>(); exportAgentVoListResult.add(new ExportAgentVo("A1")); exportAgentVoListResult.add(new ExportAgentVo("A2")); exportAgentVoListResult.add(new ExportAgentVo("A1")); Map<String, List<ExportAgentVo>> exportAgentVoMap = exportAgentVoListResult.stream() .collect(Collectors.groupingBy(ExportAgentVo::getAgentId)); exportAgentVoMap.forEach((key, value) -> System.out.println(key + ": " + value.size())); } } 6. 分组并求和可以使用 Collectors.groupingBy 和 Collectors.summingInt 方法对数据进行分组并求和。以下是示例代码:
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 定义 ExportGoodsProcurementDetailVo 类 class ExportGoodsProcurementDetailVo { private String supplierName; private String agentId; private String goodsId; private int count; public ExportGoodsProcurementDetailVo(String supplierName, String agentId, String goodsId, int count) { this.supplierName = supplierName; this.agentId = agentId; this.goodsId = goodsId; this.count = count; } public String getSupplierName() { return supplierName; } public String getAgentId() { return agentId; } public String getGoodsId() { return goodsId; } public int getCount() { return count; } } public class ListGroupAndSum { public static void main(String[] args) { List<ExportGoodsProcurementDetailVo> goodsProcurementDetailVos = new ArrayList<>(); goodsProcurementDetailVos.add(new ExportGoodsProcurementDetailVo("S1", "A1", "G1", 10)); goodsProcurementDetailVos.add(new ExportGoodsProcurementDetailVo("S1", "A1", "G1", 20)); ExportGoodsProcurementDetailVo exportGoodsProcurementDetailVo = new ExportGoodsProcurementDetailVo("S1", "A1", "", 0); ExportGoodsProcurementDetailVo exportGoBeerVo = new ExportGoodsProcurementDetailVo("", "A1", "", 0); Map<String, Integer> goodCountMap = goodsProcurementDetailVos.stream() .filter(a -> a.getSupplierName().equals(exportGoodsProcurementDetailVo.getSupplierName()) && a.getAgentId().equals(exportGoBeerVo.getAgentId())) .collect(Collectors.groupingBy(ExportGoodsProcurementDetailVo::getGoodsId, Collectors.summingInt(ExportGoodsProcurementDetailVo::getCount))); goodCountMap.forEach((key, value) -> System.out.println(key + ": " + value)); } } 7. List 转 Map可以使用 Collectors.toMap 方法将 List 转换为 Map。需要注意的是,如果集合对象有重复的 key,会报错 Duplicate key,可以使用 (k1, k2) -> k1 来处理重复 key 的情况。以下是示例代码:
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 定义 CustomerDetailResp 类 class CustomerDetailResp { private String dept; private String members; public CustomerDetailResp(String dept, String members) { this.dept = dept; this.members = members; } public String getDept() { return dept; } public String getMembers() { return members; } } // 定义 Apple 类 class Apple { private int id; public Apple(int id) { this.id = id; } public int getId() { return id; } } public class ListToMap { public static void main(String[] args) { List<CustomerDetailResp> result = new ArrayList<>(); result.add(new CustomerDetailResp("D1", "M1")); result.add(new CustomerDetailResp("D2", "M2")); Map<String, String> map1 = result.stream().collect(Collectors.toMap(CustomerDetailResp::getDept, CustomerDetailResp::getMembers)); Map<String, CustomerDetailResp> map2 = result.stream().collect(Collectors.toMap(CustomerDetailResp::getDept, CustomerDetailResp -> CustomerDetailResp)); List<Apple> appleList = new ArrayList<>(); appleList.add(new Apple(1)); appleList.add(new Apple(1)); Map<Integer, Apple> appleMap = appleList.stream().collect(Collectors.toMap(Apple::getId, a -> a, (k1, k2) -> k1)); } } 8. List 转 String可以使用 Google Guava 库的 Joiner 类将 List 转换为 String。以下是示例代码:
import com.google mon.base.Joiner; import java.util.ArrayList; import java.util.List; public class ListToString { public static void main(String[] args) { List<String> itemNoList = new ArrayList<>(); itemNoList.add("1"); itemNoList.add("2"); itemNoList.add("3"); String join = Joiner.on(',').join(itemNoList); System.out.println(join); } } 9. String 转 List可以使用 Arrays.stream 和 Collectors.toList 方法将 String 转换为 List。以下是示例代码:
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StringToList { public static void main(String[] args) { String sales = "1,2,3,2"; List<String> saleList = Arrays.stream(sales.split(",")).distinct().collect(Collectors.toList()); saleList.forEach(System.out::println); } }通过以上示例,我们可以看到 Java 8 的 Stream API 为集合数据处理提供了非常强大和便捷的功能。合理使用这些功能可以大大提高代码的可读性和开发效率。本文示例已涵盖日常开发中90%的集合处理场景,建议根据具体业务需求灵活组合使用。对于更复杂的操作,可结合Collectors.joining、mapping等收集器实现。
Java集合数据处理技巧:使用StreamAPI实现多种操作由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java集合数据处理技巧:使用StreamAPI实现多种操作”