I'm trying to translate this (simplified) code to use Java-8 streams:
Map<String, String> files = new ConcurrentHashMap<String, String>();
while(((line = reader.readLine()) != null) {
if(content != null)
files.put("not null"+line, "not null"+line);
else
files.put("its null"+line, "its null"+line);
}
reader.close();
Here is what I've tried:
files = reader.lines().parallel().collect((content != null)?
(Collectors.toConcurrentMap(line->"notnull"+line, line->line+"notnull")) :
(Collectors.toConcurrentMap(line->line+"null", line->line+"null")));
But the above gives a "cyclic inference" message for all the line->line+"..."
on intelliJ. What is cyclic inference? Is there an error in this logic?
I noted some similar issues on SO. But they suggest to use interface(Map) instead of its implementations. But files
here is declared as a Map
.
Update: Adding more context, content
is a String that holds the name of a directory. files
is a map that holds multiple file paths. What file paths need to go into the files
map depends on content
directory-name is populated or not.
Another way to fix this is to introduce the intermediate variable for collector:
Collector<String, ?, ConcurrentMap<String, String>> collector = (content != null) ?
(Collectors.toConcurrentMap(line->"notnull"+line, line->line+"notnull")) :
(Collectors.toConcurrentMap(line->line+"null", line->line+"null"));
Map<String, String> files = reader.lines().parallel().collect(collector);
This solution (unlike one presented by @JanXMarek) does not allocate intermediate arrays and does not check the content
for every input line.
The cyclic inference is the situation in the type inference procedure when to determine the type of inner subexpression, the type of outer subexpression must be determined, but it cannot be determined without knowing the type of inner subexpression. Type inference in Java-8 can infer that in case of Stream<String>.collect(Collectors.toConcurrentMap(line->line+"null", line->line+"null"))
the type of Collector is Collector<String, ?, ConcurrentMap<String, String>>
. Normally when subexpression type (here we're speaking about toConcurrentMap(...)
subexpression) cannot be explicitly determined, it can be reduced using the outer context if the outer context is method invocation, cast or assignment. Here however the outer context is ?:
operator which has its own complex type inference rules, so this becomes too much and you should help the type inference system specifying the explicit type somewhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With