【问题标题】:Iterate Array of Map<String,Object> and return Map<Long,Long> using Java 8使用 Java 8 迭代 Map<String,Object> 数组并返回 Map<Long,Long>
【发布时间】:2021-03-18 07:32:57
【问题描述】:

我有一个地图数组。我需要在其中进行一些计算并返回另一个 Map,并将相同的键计数添加到结果中的值中。 我已经尝试过以下一种。但是由于它是并行运行的,所以它不会添加它。

请帮忙改进

我可以在正常的 for 循环中实现这一点。

public Map<Long,Long> solve(Map<String,Stats>... map){
        Map<Long,Long> resultCount = new HashMap<Long,Long>();
        if(map != null){
       
            resultCount = Arrays.stream(map).filter(Objects::nonNull).map(map -> getUserCountMap(map))
            .collect(HashMap::new, Map::putAll, Map::putAll);
  
    }
        return resultCount;
    }
    
   public Map<Long,Long>  getUserCountMap(Map<String, Stats> map) {
       Map<Long,Long> resultCount = new HashMap<Long,Long>();
       
       map.forEach((k,v)->{
           try {
                
               String key = (String) k;
               Stats userValue = (Stats) v;
               Long userId = new Long(key);
               System.out.println("key :::"+key+":::"+resultCount.getOrDefault(userId, 0l));
               Optional<Long> count = userValue.getCount();
               System.out.println(count.get());
               count.ifPresent(aLong -> resultCount.put(userId, (resultCount.getOrDefault(userId, 0l) + aLong)));
               System.out.println(resultCount);

           } catch (Exception e) {
           } 
       }
       );
       
       System.out.println("ret "+resultCount);
           return resultCount;
       
   }

任何了解 Java 8 Streams API 和各种中间和终端操作的好文档

【问题讨论】:

    标签: java lambda java-8 java-stream


    【解决方案1】:

    您没有使用正确的收集器。

    您可以将Collectors.toMap 与合并函数一起使用,该函数将添加相同键的值。

    但首先我建议您将Stream&lt;Map&lt;&gt;&gt; 转换为所有Maps 的所有条目的Stream&lt;Map.Entry&lt;&gt;&gt;

      resultCount = 
          Arrays.stream(map)
                .filter(Objects::nonNull)
                .flatMap(map -> getUserCountMap(map).entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey,
                                          Map.Entry::getValue,
                                          (v1,v2)->v1+v2));
    

    尝试摆脱 getUserCountMap:

      resultCount = 
          Arrays.stream(map)
                .filter(Objects::nonNull)
                .flatMap(map -> map.entrySet().stream())
                .map(e -> new SimpleEntry<Long,Long>(Long.valueOf(e.getKey()),e.getValue().getCount().orElse(0L)))
                .collect(Collectors.toMap(Map.Entry::getKey,
                                          Map.Entry::getValue,
                                          (v1,v2)->v1+v2));
    

    我不确定后者是否完全等同于您的 getUserCountMap 逻辑。

    【讨论】:

    • 哇!谢谢。有没有办法在流本身内部实现 getUserCountMap 逻辑而不是作为单独的函数
    猜你喜欢
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多