使用流有条件地填充地图 - Java 8

A.R*_*K.S 4 java lambda intellij-idea java-8 java-stream

我正在尝试将此(简化)代码翻译为使用Java-8流:

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();
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的:

files = reader.lines().parallel().collect((content != null)?
                (Collectors.toConcurrentMap(line->"notnull"+line, line->line+"notnull")) :                                              
                (Collectors.toConcurrentMap(line->line+"null", line->line+"null")));
Run Code Online (Sandbox Code Playgroud)

但是上面给出了所有line->line+"..."on intelliJ 的"循环推理"消息.什么是循环推理?这个逻辑中有错误吗?

我在SO上注意到了一些类似的问题.但他们建议使用接口(Map)而不是其实现.但files这里被宣布为Map.

更新:添加更多上下文,content是一个包含目录名称的String.files是一个包含多个文件路径的地图.需要进入files映射的文件路径取决于content是否填充了目录名.

Tag*_*eev 7

另一种解决方法是为收集器引入中间变量:

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);       
Run Code Online (Sandbox Code Playgroud)

此解决方案(与@JanXMarek提供的解决方案不同)不分配中间数组,也不检查content每个输入行.

循环推理是类型推断过程中的情况,当确定内部子表达的类型时,必须确定外部子表达的类型,但是在不知道内部子表达的类型的情况下不能确定.Java-8中的类型推断可以推断出在Stream<String>.collect(Collectors.toConcurrentMap(line->line+"null", line->line+"null"))收集器类型的情况下Collector<String, ?, ConcurrentMap<String, String>>.通常,当子表达式类型(这里我们说的是toConcurrentMap(...)子表达式)无法显式确定时,如果外部上下文是方法调用,强制转换或赋值,则可以使用外部上下文来减少它.然而,外部上下文是?:具有其自己的复杂类型推理规则的运算符,因此这变得太多,您应该帮助类型推断系统在某处指定显式类型.