如何用Java 8 Lambda创建值为AddressWrapper的Map?
把Address列表转为街道名对应AddressWrapper的Map
没问题,你已经用Collectors.groupingBy完成了按街道名分组的第一步,现在只需要把每个分组的结果包装成AddressWrapper对象即可。这里有两种实用的实现方式:
方法一:先分组再转换(逻辑清晰,衔接原有代码)
先按你原来的代码完成分组,再通过流将分组后的Map<String, List<Address>>转换为目标Map<String, AddressWrapper>:
// 第一步:按街道名分组(和你原来的代码一致) Map<String, List<Address>> groupedAddresses = addressList.stream() .collect(Collectors.groupingBy(Address::getStreetName)); // 第二步:将每个分组包装为AddressWrapper Map<String, AddressWrapper> resultMap = groupedAddresses.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, // 保留街道名为键 entry -> { AddressWrapper wrapper = new AddressWrapper(); wrapper.setStreetName(entry.getKey()); wrapper.setAddressWrapperList(entry.getValue()); return wrapper; } ));
这种方式的优势是逻辑拆分明确,如果你需要保留中间的分组Map做其他操作,会很方便。
方法二:流式操作一步到位(更简洁)
可以直接在groupingBy中指定下游收集器,将分组后的List直接包装成AddressWrapper,无需中间Map:
Map<String, AddressWrapper> resultMap = addressList.stream() .collect(Collectors.groupingBy( Address::getStreetName, // 分组键:街道名 Collectors.collectingAndThen( Collectors.toList(), // 先收集同街道的Address为List addresses -> { AddressWrapper wrapper = new AddressWrapper(); // 因为分组是按街道名来的,所以列表中第一个元素的街道名就是分组键 wrapper.setStreetName(addresses.get(0).getStreetName()); wrapper.setAddressWrapperList(addresses); return wrapper; } ) ));
优化小技巧:给AddressWrapper添加构造函数
如果能给AddressWrapper添加一个带参构造函数:
public class AddressWrapper { // 原有字段和getter/setter不变 public AddressWrapper(String streetName, List<Address> addressWrapperList) { this.streetName = streetName; this.addressWrapperList = addressWrapperList; } }
那么包装代码可以大幅简化,比如方法一中的lambda可以写成:
entry -> new AddressWrapper(entry.getKey(), entry.getValue())
方法二中的lambda可以写成:
addresses -> new AddressWrapper(addresses.get(0).getStreetName(), addresses)
这样代码会更简洁易读~
内容的提问来源于stack exchange,提问作者jjones
相关产品推荐
相关产品推荐

