Reputation: 83
I'm trying to convert a List
to Map
without duplicates using a stream but I can't achieve it.
I can do it using a simple loop like this:
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());
}
}
but when I try to use a stream, my mind crash.
I have to say the PropertyOwnerCommunityAddress
contains two object more: Community
and Address
and the goal of all of this is for each community save the addresses in a key:value
pair without duplicate the Community
object.
Anyone can help me? Thank you!
Upvotes: 7
Views: 1242
Reputation: 19926
As you can have multiple Address
es per Community
you can't use the toMap()
collector, but you need to use groupingBy()
:
Map<Community, List<Address>> map = propertyOwnerCommunityAddresses.stream()
.collect(Collectors.groupingBy(
PropertyOwnerCommunityAddress::getCommunity,
Collectors.mapping(
PropertyOwnerCommunityAddress::getAddress,
Collectors.toList())
)
);
Depending on your personal preference, this can look messy and maybe more complicated than the simple for-loop, which can also be optimized:
for(PropertyOwnerCommunityAddress poco : propertyOwnerCommunityAddresses) {
hashMap.computeIfAbsent(poco.getCommunity(), c -> new ArrayList<>()).add(poco.getAddress());
}
Depending if you only want to have unique addresses you may want to use Set
, so change the Collectors.toList()
to Collectors.toSet()
or when you stay with your for-loop change the definition of hashMap
to Map<Community, Set<Address>>
and in the loop exchange new ArrayList<>()
with new HashSet<>()
Upvotes: 7
Reputation: 54168
You have to use
groupingBy
to get the Community
as keymapping
to get the Address
as listMap<Community, List<Address>> hashMap = propertyOwnerCommunityAddresses.stream()
.collect(Collectors.groupingBy(PropertyOwnerCommunityAddress::getCommunity,
Collectors.mapping(PropertyOwnerCommunityAddress::getAddress, Collectors.toList())));
Upvotes: 3