qwerty1423 qwerty1423 - 1 month ago 18
Java Question

Java 8 Stream API Collector - addAll not applicable for argument Object, addAll is undefined for type Object

My code is not compiling and I'm not quite sure why. Here is the code:

ArrayList<ClassificationData> classifications = productData
.stream()
.filter(p -> CollectionUtils.isNotEmpty(p.getClassifications()))
.flatMap(p -> p.getClassifications().stream())
.collect(groupingBy(ClassificationData::getName,
mapping(ClassificationData::getFeatures,
Collector.of(LinkedHashSet<FeatureData>::new,
(a,b) -> b.addAll(a),
(a,b) -> {
b.addAll(a);
return b;
})
)))
.entrySet()
.stream()
.map(e -> {
ClassificationData c = new ClassificationData();
c.setName(e.getKey());
c.setFeatures(e.getValue());
return c;
})
.collect(Collectors.toCollection(ArrayList::new));


And the errors:

(a,b) -> b.addAll(a),
The method addAll(Collection<? extends FeatureData>) in the type Collection<FeatureData> is not applicable for the arguments (Object)

b.addAll(a);
The method addAll(Object) is undefined for the type Object

c.setFeatures(e.getValue());
The method setFeatures(Collection<FeatureData>) in the type ClassificationData is not applicable for the arguments (Object)


I've also tried Set::add and Set::addAll with pretty much the same result.

EDIT:

I've ended up with this code. Please tell me if there is a cleaner way to do this, or is it ok?

ArrayList<ClassificationData> classifications = productData
.stream()
.filter(p -> CollectionUtils.isNotEmpty(p.getClassifications()))
.flatMap(p -> p.getClassifications().stream())
.collect(groupingBy(ClassificationData::getName,
mapping(ClassificationData::getFeatures,
toCollection(LinkedHashSet::new)
)))
.entrySet()
.stream()
.map(e -> {
ClassificationData c = new ClassificationData();
c.setCode(e.getKey());
c.setName(e.getKey());
c.setFeatures(e.getValue()
.stream()
.filter(CollectionUtils::isNotEmpty)
.flatMap(p -> p.stream())
.filter(distinctByKey(FeatureData::getName))
.collect(toCollection(ArrayList::new)));
return c;
})
.collect(toCollection(ArrayList::new));

Answer

I think you have the order of the arguments messed up in the first lambda; it should be

(set, a) -> set.add(a)

...though frankly it'd be better just to replace the entire Collector creation with

toCollection(LinkedHashSet::new)

Which is equivalent.

Comments