Java Stream:HashMap 的对象列表,没有重复

Joa*_*rte 7 java java-stream

我正在尝试使用流将 a 转换ListMap没有重复项,但我无法实现。

我可以使用这样的简单循环来做到这一点:

List<PropertyOwnerCommunityAddress> propertyOwnerCommunityAddresses = getPropertyOwnerAsList();

Map<Community, List<Address>> hashMap = new LinkedHashMap<>();

for (PropertyOwnerCommunityAddress poco : propertyOwnerCommunityAddresses) {

    if (!hashMap.containsKey(poco.getCommunity())) {
        List<Address> list = new ArrayList<>();
        list.add(poco.getAddress());
        hashMap.put(poco.getCommunity(), list);
    } else {
        hashMap.get(poco.getCommunity()).add(poco.getAddress());
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用流时,我的思绪崩溃了。

我不得不说PropertyOwnerCommunityAddress更多包含两个对象:Community并且Address所有这一切的目标是为每个社区保存一key:value对地址而不重复Community对象。

任何人都可以帮助我吗?谢谢!

Lin*_*ica 7

由于您可以有多个Addresses,因此Community您不能使用toMap()收集器,但您需要使用groupingBy()

Map<Community, List<Address>> map = propertyOwnerCommunityAddresses.stream()
    .collect(Collectors.groupingBy(
        PropertyOwnerCommunityAddress::getCommunity,
        Collectors.mapping(
            PropertyOwnerCommunityAddress::getAddress, 
            Collectors.toList())
        )
    );
Run Code Online (Sandbox Code Playgroud)

根据您的个人喜好,这可能看起来很混乱,而且可能比简单的 for 循环更复杂,也可以对其进行优化:

for(PropertyOwnerCommunityAddress poco : propertyOwnerCommunityAddresses) {
    hashMap.computeIfAbsent(poco.getCommunity(), c -> new ArrayList<>()).add(poco.getAddress());
}
Run Code Online (Sandbox Code Playgroud)

取决于您是否只想拥有您可能想要使用的唯一地址Set,因此更改Collectors.toList()toCollectors.toSet()或当您继续使用 for 循环时更改hashMapto的定义Map<Community, Set<Address>>并在循环中new ArrayList<>()new HashSet<>()