我有一个映射列表,其中某些键映射到字符串值。
类似于 List<Map<String,String>> aMapList;
目标:流式传输此映射列表并收集所有映射中单个键的值。
我是如何做到这一点的 ->
key = "somekey";
aMapList.stream().map(a -> a.get(key)).collect(Collectors.averagingInt());
问题: 如果没有这样的键,我会因为 a.get(key) 而由于而得到异常!因为求平均值将给出零值。我如何检查或让 lambda 忽略任何此类映射并继续前进。
我确实知道我可以在 a -> a.contains(key)
上添加过滤器然后继续。
编辑:我还可以添加更多过滤器或简单地检查一个过滤器上的多个条件。
可能的解决方案:
aMapList.stream().filter(a -> a.contains(key)).
map(a -> a.get(key)).collect(Collectors.averagingInt());
这个可以做得更漂亮吗? 不停止操作,直接跳过它们? 是否有一些更通用的方法来跳过异常或空值。 例如。我们可以扩展 lambda 并放置一个 try-catch block ,但我仍然需要返回一些内容,如果我希望执行相当于“继续”的操作,该怎么办?
例如。
(a -> {return a.get(key) }).
可以扩展为-->
(a -> {try{return a.get(key)}
catch(Exception e){return null} }).
上面仍然返回 null,而不是直接跳过。
我正在选择给出两个选项的最佳答案,但我不认为它们中的任何一个更漂亮。链接过滤器似乎是解决这个问题的方法。
最佳答案
如何使用Optional
包装结果:
List<Optional<String>> values = aMapList.stream()
.map(a -> Optional.ofNullable(a.get(key)))
.collect(Collectors.toList());
稍后的代码将知道可能存在空元素。
您提出的解决方案对于允许 null
值的 map 存在潜在错误。例如:
Map<String, String> aMap = new HashMap<>();
aMap.put("somekey", null);
aMapList.add(aMap);
aMapList.straem()
.filter(a -> a.contains("somekey")) // true returned for contains
.map(a -> a.get("somekey")) // null returned for get
.collect(Collectors.toList());
关于Java 映射 Lambda 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38886690/