I am calling a library method that returns a raw Stream
. I know the type of the elements in the stream and want to collect into a collection with the declared element type. What is the nice, or the not so appalling way of doing it?
Minimal reproducible example
For the sake of a reproducible example suppose I want to call this method:
@SuppressWarnings("rawtypes")
static Stream getStream() {
return Stream.of("Example");
}
I had hoped that this would work, and I have not understood why it doesn’t:
List<String> stringList = getStream().map(s -> (String) s).collect(Collectors.toList());
I get Type mismatch: cannot convert from Object to List. Why?
Workaround
An unchecked cast works. To narrow down the bit that needs to be marked as deliberately unchecked, we may do
@SuppressWarnings("unchecked")
Stream<String> stringStream = getStream();
List<String> stringList = stringStream.collect(Collectors.toList());
On both Java 8 and Java 11 the returned list is a java.util.ArrayList
, and it contains the expected String
element.
What my search turned up or not
I tried my search engine searching for terms like java collect raw stream. It didn’t lead me to anything helpful. There’s a closed Java bug (link at the bottom) mentioning that once you operate on raw types, everything gets raw. But this fully raw version doesn’t work either:
List stringList = getStream().collect(Collectors.toList());
I am still getting Type mismatch: cannot convert from Object to List. How come?
We are coding for Java 8 (a little while still).
I know this question has something opinion-based about it. I am still hoping that you can provide me with some facts that will help me write code that will generally be considered nicer.
Background: Hibernate 5
The method I want to call is org.hibernate.query.Query.getResultStream()
on a raw Query
(a Query
lacking type parameter). I want to get the stream because I have special requirements for the type of collection I am collecting into. In my production code I am using Collectors.toCollection()
(not Collectors.toLlist()
as in the example in this question). BTW while writing this question I found a way to persuade Hibernate to return a typed stream. I still found the question interesting enough to post.
Link
- Problem with casting inside lambdas for java.util.stream.Stream.map method in the Java bug database