Transform and filter a Java Map with streams

前端 未结 6 1693
既然无缘
既然无缘 2021-01-31 02:40

I have a Java Map that I\'d like to transform and filter. As a trivial example, suppose I want to convert all values to Integers then remove the odd entries.

Map         


        
6条回答
  •  一生所求
    2021-01-31 03:20

    One way to solve the problem with much lesser overhead is to move the mapping and filtering down to the collector.

    Map output = input.entrySet().stream().collect(
        HashMap::new,
        (map,e)->{ int i=Integer.parseInt(e.getValue()); if(i%2==0) map.put(e.getKey(), i); },
        Map::putAll);
    

    This does not require the creation of intermediate Map.Entry instances and even better, will postpone the boxing of int values to the point when the values are actually added to the Map, which implies that values rejected by the filter are not boxed at all.

    Compared to what Collectors.toMap(…) does, the operation is also simplified by using Map.put rather than Map.merge as we know beforehand that we don’t have to handle key collisions here.

    However, as long as you don’t want to utilize parallel execution you may also consider the ordinary loop

    HashMap output=new HashMap<>();
    for(Map.Entry e: input.entrySet()) {
        int i = Integer.parseInt(e.getValue());
        if(i%2==0) output.put(e.getKey(), i);
    }
    

    or the internal iteration variant:

    HashMap output=new HashMap<>();
    input.forEach((k,v)->{ int i = Integer.parseInt(v); if(i%2==0) output.put(k, i); });
    

    the latter being quite compact and at least on par with all other variants regarding single threaded performance.

提交回复
热议问题