我有这样的代码:
ArrayList<Map<String, String>> resultArray = resultList.stream() //
.map(parser::parseJson) //
.filter(ev -> ev.entrySet().containsAll(filter.entrySet())) //
.collect(Collectors.toCollection(ArrayList::new));
调用方resultList
是一个ArrayList,它是一个JSON数组。我想将每个元素解析为map,过滤map,并收集map的数组。
上一行代码没有编译错误。但是在运行时,它给出错误为:
Error:(51, 25) java: incompatible types: cannot infer type-variable(s)
R,A,capture#1 of ?,T,C,E (argument mismatch;
java.util.stream.Collector<java.util.Map<java.lang.String,java.lang.String>,capture#2 of
?,java.util.ArrayList<java.util.Map<java.lang.String,java.lang.String>>
> cannot be converted to java.util.stream.Collector<? super
java.util.Map,capture#2 of
?,java.util.ArrayList<java.util.Map<java.lang.String,java.lang.String>>
>)
我尝试了多种不同的方式,例如Collectors.toList()
,但是它不起作用。我仍然在寻找一种解决方案,可以解析每个String元素以进行映射并将它们全部收集为ArrayList。
更新:解析器来自com.json.parsers.JSONParser;
答案 0 :(得分:1)
根据(几乎是神秘的)错误消息,问题出在您的parseJson
实例的parser
方法中,该方法返回了原始的Map
,即没有映射的映射。 t指定其键和值的类型。
您需要该方法返回一个Map<String, String>
,或者至少返回一个泛型,以便它可以返回所需的类型。
编辑:我从未听说过您的JSON解析器。谷歌快速搜索显示它几乎没有被使用,似乎它是一个已归档的项目。我强烈建议您使用更好的JSON库,例如Jackson,Gson或JSON.simple。
一种快速而又肮脏的解决方案是,如果您确定实际上已将字符串作为所有键的值,则将返回的映射强制转换为Map<String, String>
(否则,您可能会感到恐惧) ClassCastException
。
为此,您应该将代码更改为:
List<Map<String, String>> resultArray = resultList.stream()
.map(json -> (Map<String, String>) parser.parseJson(json))
.filter(ev -> ev.entrySet().containsAll(filter.entrySet()))
.collect(Collectors.toCollection(ArrayList::new));
但是,再次提醒您,这不是很干净,您可能会在该演员表中引入更多错误。最好的解决方案是使用杰克逊:
ObjectMapper mapper = new ObjectMapper(); // Jackson JSON lib entry-point
List<Map<String, String>> resultArray = resultList.stream()
.map(json -> {
try {
return mapper.readValue(json, new TypeReference<Map<Striong, String>>() {});
} catch (IOException e) {
throw new UncheckedIOExpcetion(e);
}
})
.filter(ev -> ev.entrySet().containsAll(filter.entrySet()))
.collect(Collectors.toCollection(ArrayList::new));
建议:最好将map
操作中的整个try / catch块移到返回Map<String, String>
的私有方法。