Use JDK 11.0.3
. I have the following code snippet:
Set<String> allNumbersSet = customerInfoService.getCustomerPhoneNumbers(bankCustomerId);
additionalInformation
.map(info -> info.get(BANK_PE_CUSTOMER_ID_KEY))
.filter(StringUtils::isNotEmpty)
.ifPresent(id -> allNumbersSet.addAll(customerInfoService.getCustomerPhoneNumbers(id))); // fails here
Where get phone numbers is just Collectors.toSet()
:
@Override
public Set<String> getCustomerPhoneNumbers(String customerId) {
return backOfficeInfoClient.getCustByHashNo(customerId).getPropertyLOVs()
.flatMap(property -> property.getValues().values().stream())
.collect(Collectors.toSet());
}
However, it fails with:
java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)
at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.addAll(ImmutableCollections.java:76)
at service.impl.UserManagementServiceImpl.lambda$validateNewLogin$3(UserManagementServiceImpl.java:69)
If I update like the following:
var allNumbersSet = new HashSet(customerInfoService.getCustomerPhoneNumbers(bankCustomerId));
It works fine now.
What is wrong with the above code usage? Could you explain why this exactly appears?
CodePudding user response:
According to the Javadoc of Collectors.toSet()
:
There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned.
So, if you need a mutable set, you should create one yourself, to be sure that it is mutable.
You can either do that with the copy constructor that you have (new HashSet<>(...)
- don't forget the <>
), or you can use
Collectors.toCollection(HashSet::new)
as the collector, as described in the linked Javadoc.
However, note that a more Stream-y way of doing this would be to concat two streams:
Set<String> someNumbersSet = customerInfoService.getCustomerPhoneNumbers(bankCustomerId);
Set<String> allNumbersSet =
Stream.concat(
someNumbersSet.stream(),
additionalInformation
.map(info -> info.get(BANK_PE_CUSTOMER_ID_KEY))
.filter(StringUtils::isNotEmpty)
.map(customerInfoService::getCustomerPhoneNumbers)
.stream()
.flatMap(Collection::stream))
.collect(Collectors.toSet());