I have two lists of objects dbAssets
and assetVOS
.
I want common elements (and difference) by some property (getSecName()
in my case) using streams.
I've tried the following:
dbAssets.stream().map(SomeClass::getSecName)
.filter(dbAssetName -> assetVOS.stream()
.map(SomeClass::getSecName)
.anyMatch(assetVOSName -> dbAssetName.equals(assetVOSName)))
.collect(Collectors.toList());
But I'm getting the following error:
Incompatible types. Required
List<SomeClass>
but 'collect' was inferred to R: no instance(s) of type variable(s) exist so thatString
conforms toSomeClass
inference variable T has incompatible bounds: equality constraints:SomeClass
lower boundsString
CodePudding user response:
Since you are mapping your SomeClass
instances into String
s, your stream pipeline produces a List<String>
, not a List<SomeClass>
.
To get a List<SomeClass>
, try something like this:
List<SomeClass> output =
dbAssets.stream()
.filter(obj -> assetVOS.stream()
.map(SomeClass::getSecName)
.anyMatch(assetVOSName -> obj.getSecName ().equals(assetVOSName)))
.collect(Collectors.toList());
CodePudding user response:
I want common elements (and difference)
If you want both: a list of elements with the second name is property which present in the assetVOS
list and a list of those elements which names are not are not present, you can use collector partitioningBy()
to do that in one iteration over the dbAssets
list.
And instead of iterating over the list assetVOS
multiple times to check if it contains an element with a particular name, we can store all the names from the assetVOS
into a set, and then perform the checks against the set in a constant time.
That how it might look like:
List<SomeClass> dbAssets = // initializing the list
List<SomeClass> assetVOS = // initializing the list
Set<String> names = assetVOS.stream()
.map(SomeClass::getSecName)
.collect(Collectors.toSet());
Map<Boolean, List<SomeClass>> presentInAssetVOS = dbAssets.stream()
.collect(Collectors.partitioningBy(
user -> names.contains(user.getSecName())
));
List<SomeClass> isPresentInAssetVOS = presentInAssetVOS.get(true);
List<SomeClass> notPresentInAssetVOS = presentInAssetVOS.get(false);