流API收集方法编译错误 - 对象无法强制转换为List

xet*_*a11 2 java java-stream

我看不出我的流api逻辑有什么问题.它告诉我以下内容

[ERROR] mystuff/MandantContentFetcher.java:[67,23]不兼容的类型:java.lang.Object无法转换为java.util.List

这是我的流方法:

static List<MandantLinkCheckerEntry> createMandantLinkCheckerEntries(Struct struct) {
    Map<String, Object> linkCheckerMandants = struct.toNestedMaps();
    return linkCheckerMandants.values().parallelStream()
            .map(Map.class::cast)
            .map(MandantLinkCheckerEntry::convertMapToMandantCheckerEntry)
            .collect(Collectors.toList());
  }
Run Code Online (Sandbox Code Playgroud)

它使用此方法参考:

  private static MandantLinkCheckerEntry convertMapToMandantCheckerEntry(Map<String, Object> entryToConvert) {
    return new MandantLinkCheckerEntry(String.valueOf(entryToConvert.get("mandant.path")),
            String.valueOf(entryToConvert.get("mail.to")),
            Boolean.valueOf(String.valueOf(entryToConvert.get("active"))));
  }
Run Code Online (Sandbox Code Playgroud)

他为什么看到一个物体?第二个映射中的方法引用确实返回MandantLinkCheckerEntry.另外我假设collect确实创建了一个List,其中流的值是泛型类型,但似乎他转换了流的类型(这里的Object是Stream启动器Map<String, Object).我该如何帮助他将其投入到列表中?

Hol*_*ger 5

问题是,类文字不能引用泛型类型,因此Map.class求值为a Class<Map>,与原始类型相关联Map,这就是调用cast它时得到的内容.

因此,随后的.map(MandantLinkCheckerEntry::convertMapToMandantCheckerEntry)带有一个unchecked操作分配MapMap<String, Object>这使编译器在所有情况下继续泛型这个表达,用的呼叫结束了.collect(Collectors.toList());对原始类型Stream,其擦除回报Object.

当你使用

static List<MandantLinkCheckerEntry> createMandantLinkCheckerEntries(Struct struct) {
    Map<String, Object> linkCheckerMandants = struct.toNestedMaps();
    return linkCheckerMandants.values().parallelStream()
            .map(Map.class::cast)
            .map((Function<Map,MandantLinkCheckerEntry>)MandantLinkCheckerEntry::convertMapToMandantCheckerEntry)
            .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

取而代之的是,未选中的操作结合的方法时发生convertMapToMandantCheckerEntryFunction<Map, MandantLinkCheckerEntry>,但不与周围map的方法调用,所以该流链能够没有错误被编译.

你将永远不可避免地有一个未经检查的操作的地方,作为转换从正确性ObjectMap<String, Object>不能在运行时进行检查.最干净的解决方案是首先struct.toNestedMaps()返回a Map<String, Map<String, Object>>:

static List<MandantLinkCheckerEntry> createMandantLinkCheckerEntries(Struct struct) {
    Map<String, Map<String, Object>> linkCheckerMandants = struct.toNestedMaps();
    return linkCheckerMandants.values().parallelStream()
            .map(MandantLinkCheckerEntry::convertMapToMandantCheckerEntry)
            .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)