Issue
I have a simple snippet as below. I referred this
List<Document> list = new LinkedList<Document>();
FindIterable<Document> itr = collection.find(findQuery)
.forEach((Document doc) -> list.add(doc));
return list;
It compiles without any issues.
- I guess that we are telling compiler that
doc
is of typeDocument
. Why is it needed?
But If I do the below, it throws ambiguous error. I referred this But couldn't relate and understand exactly.
collection.find(findQuery).forEach(list::add);
Could anyone please explain why second statement is not working?
is there any better way of writing the first one [working one]?
Java version: 1.8.0_231
import statements:
import java.util.List;
import java.util.Optional;
import com.mongodb.client.FindIterable;
import org.bson.Document;
Solution
FindIterable
inherits two forEach
methods:
You could rewrite your paramter with either
Consumer<Document> consumer = documents::add;
Block<Document> block = list::add;
And either will work. These too will work:
.forEach((Consumer<Document>) doc -> list.add(doc))
.forEach((Consumer<Document>) list::add);
However, when you call forEach(list::add)
or forEach(doc -> list.add(doc))
, the compiler is unable to pick which overload will determine the method reference's target type (because the expression is compatible with both in that context).
Now, I'm not 100% sure why .forEach((Document doc) -> list.add(doc))
successfully selects/links the signature of Consumer<Document>
instead of the one with Block<? super Document>
, I'm surmizing it has to do with the generic bounds (but I'm still reading on this).
The choice for you should be easy because the Block<? super Document>
version is deprecated.
Answered By - ernest_k