简体   繁体   English

Java Map Lambda异常

[英]Java Map Lambda Exception

I have a List of Maps with certain keys that map to String values. 我有一个带有某些键的映射列表,这些键映射到String值。

Something like List<Map<String,String>> aMapList; 类似于List<Map<String,String>> aMapList;

Objective : Stream over this List of maps and collect values of a single key in all Maps. 目标 :流式传输此地图列表,并收集所有地图中单个键的值。

How I'm doing this -> 我怎么做->

key = "somekey";
aMapList.stream().map(a -> a.get(key)).collect(Collectors.averagingInt());

The Problem: I get exceptions due to a.get(key) if there is no such key! 问题:如果没有这样的密钥,我会由于 a.get(key) 获得异常! because averaging this will give a null. 因为将其取平均值将为空。 How do I check or make lambda ignore any such maps and move on. 如何检查或使lambda忽略任何此类地图并继续前进。

I do know that I can add a filter on a -> a.contains(key) and then proceed. 我确实知道我可以在a -> a.contains(key)上添加一个过滤器,然后继续。 Edit : I can also add more filters or simple check multiple conditions on one filter. 编辑:我还可以添加更多过滤器,也可以在一个过滤器上简单检查多个条件。 Possible Solution: 可能的解决方案:

    aMapList.stream().filter(a -> a.contains(key)).
         map(a -> a.get(key)).collect(Collectors.averagingInt());

Can this be made prettier? 可以更漂亮吗? Instead of halting the operation, simply skip over them? 除了停止操作,还可以跳过它们吗? Is there some more generic way to skip over exceptions or nulls. 是否有一些更通用的方法可以跳过异常或空值。 For eg. 例如。 We can expand the lambda and put a try-catch block, but I still need to return something, what if I wish to do an equivalent of "continue". 我们可以扩展lambda并放置一个try-catch块,但是我仍然需要返回一些内容,如果我想做一个等效的“ continue”,该怎么办。

Eg. 例如。

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

Can be expanded to --> 可以扩展到->

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

The above still returns a null, instead of just skipping over. 上面的代码仍然返回null,而不仅仅是跳过。

I'm selecting the best answer for giving two options, But I do not find any of them prettier. 我正在为给出两个选项选择最佳答案,但是我发现其中没有一个更漂亮。 Chaining filters seems to be the solution to this. 链接过滤器似乎是解决此问题的方法。

How about wrapping the result with Optional : 如何使用Optional包装结果:

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

Later code will know to expect possible empty elements. 以后的代码将知道可能会出现空元素。


The solution you propose has a potential bug for maps that allow null values. 您建议的解决方案对于允许null值的映射可能存在错误。 For example: 例如:

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

Based on the Map documentation , and on your comment under your question, you're not actually getting an exception from a.get(key) . 根据地图文档以及您对问题的评论,您实际上并没有从a.get(key)那里获得异常。 Rather, that expression produces a null value, and you're having problems later when you run into these null values. 相反,该表达式会产生一个空值,并且稍后遇到这些空值时会遇到问题。 So simply filtering out these null values right away should work just fine: 因此,只需立即过滤掉这些空值就可以了:

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

This is prettier, simpler, and performs better than the workaround in your question. 这比问题中的解决方法更漂亮,更简单,并且性能更好。

I should mention that I usually prefer the Optional<> type when dealing with null values, but this filtering approach works better in this case since you specifically said you wanted to ignore elements where the key doesn't exist in a map list. 我应该提到的是,在处理空值时,我通常更喜欢使用Optional<>类型,但是这种过滤方法在这种情况下效果更好,因为您明确表示要忽略映射列表中不存在该键的元素。

The simplest I could come up with was: 我能想到的最简单的是:

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

By formatting the lambda in this fashion, it is easier to see the distinct steps that the code processes. 通过以这种方式格式化lambda,可以更轻松地看到代码处理的各个步骤。

尽管我认为这并不是一种更漂亮的方法,但是您可以这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM