流API收集方法编译器错误 - 无法将对象强制转换为列表

时间:2017-07-13 17:04:56

标签: 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());
  }

使用此方法参考:

  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"))));
  }

为什么他会看到对象?第二个地图中的方法参考会返回 MandantLinkCheckerEntry 。此外,我假设收集确实创建了一个列表,其中流式值为通用类型,但似乎他转换了流的类型(此处为Object,因为流启动器为Map<String, Object)。我该如何帮助他将其投入名单?

2 个答案:

答案 0 :(得分:5)

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

因此,后续的.map(MandantLinkCheckerEntry::convertMapToMandantCheckerEntry)会有一个未经检查的操作,将Map分配给Map<String, Object>,导致编译器在没有Generics的情况下继续执行此表达式,最后调用{{ 1}}原始类型.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()); } 绑定到convertMapToMandantCheckerEntry时会发生未经检查的操作,但不会与周围的Function<Map, MandantLinkCheckerEntry>方法调用绑定,因此可以编译流链而不会出错。

您总是不可避免地在某处进行未经检查的操作,因为在运行时无法检查从mapObject的转换的正确性。最干净的解决方案是让Map<String, Object>首先返回struct.toNestedMaps()

Map<String, Map<String, Object>>

答案 1 :(得分:2)

更改此行:

.map(Map.class::cast)

对此:

.map(o -> (Map<String, Object>) o)

当然,这个强制转换是完全不安全的,会产生警告,但至少,你会在流管道中保留泛型类型参数。