2016-08-11 110 views
2

我有一个地图列表与映射到字符串值的某些键。爪哇地图Lambda异常

喜欢的东西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块,但是我仍然需要返回一些东西,如果我希望做一个“继续”的等价物。

例如,

(a -> {return a.get(key) }). 

可扩展到 - >

(a -> {try{return a.get(key)} 
catch(Exception e){return null} }). 

以上仍然会返回一个空的,而不是仅仅跳过。

我选择了给出两个选项的最佳答案,但我没有发现它们中的任何一个更漂亮。链式过滤器似乎是解决这个问题的方法。

+1

你为什么会遇到异常?你不应该得到空吗? –

+0

我知道一个解决方案。我只是问我能否以更短的方式做到这一点。太多的滤镜看起来很丑,让人感到困惑。 – Pranay

+0

@ cricket_007,因为未来的操作会抛出异常。我会得到null,但随后它会中断并抛出异常。 – Pranay

回答

2

如何与Optional包裹结果:

List<Optional<String>> values = aMapList.stream() 
      .map(a -> Optional.ofNullable(a.get(key))) 
      .collect(Collectors.toList()); 

后来代码就知道了预期可能的空元素。


您提出解决方案有地图,让null值的潜在错误。例如:基于Map documentation

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()); 
+0

我忘了在过滤器中添加我也可以过滤空值。对于那个很抱歉。我的意思是,我可以通过链接筛选器筛选出任何数量的东西,因此也可以筛选出null。我想知道是否有某种方法可以做到“try {},catch {ignore}”。如果任何这种情况被忽略,我们将进入清单。 – Pranay

0

我能想出的最简单的是:

aMapList.stream() 
     .filter(map -> map.containsKey(key)) 
     .map(map -> map.get(key)) 
     .collect(Collectors.toList()); 

通过以这种方式格式化拉姆达,很容易看到不同的步骤,该代码的进程。

+0

我已经建议这是一个可能的解决方案。我想问的是,如果有一些方法可以让我的lambda继续工作,即使有一些异常。 – Pranay

+0

我建议使lambda更容易阅读和理解的格式。我认为这个lambda(就像你说的基本上和你一样)是最简单的解决方案。 – Jason

0

虽然我认为这不完全是一个漂亮的方法,你可以这样做:

aMapList.stream().map(a -> a.containsKey(key) ? a.get(key) : null).collect(Collectors.toList()); 
+1

'a.get(key)'返回null,所以检查它是否包含似乎毫无意义 –

+0

除了板球说什么,我宁愿添加另一个过滤器:) – Pranay

2

,并在你的问题在你的评论,你实际上没有从a.get(key)得到一个例外。相反,该表达式会生成一个空值,并且在您遇到这些空值时会遇到问题。所以,简单地过滤掉这些空值就应该只是罚款:

aMapList.stream() 
    .map(a -> a.get(key)) 
    .filter(v -> v != null) 
    .collect(Collectors.toList()); 

这是更漂亮,更简单,性能比你的问题解决方法更好。

我应该提到,在处理空值时,我通常更喜欢Optional<>类型,但是这种过滤方法在这种情况下效果更好,因为您明确说过要忽略密钥不存在于地图列表中的元素。

+0

应该是'v!= null'。 –

+1

@LukeLee'v!= null'在地图有一个带有null值的键时也有潜在的错误。 –

+0

目前我更担心没有得到正确的结果为普通的情况。 –