【问题标题】:How to add values in duplicated key Map in Java 8如何在 Java 8 中的重复键映射中添加值
【发布时间】:2021-05-10 10:42:13
【问题描述】:

我想在 Java 8 的重复键映射中添加值。

举个例子:

例如:如果 strArr 是 ["B:-1", "A:1", "B:3", "A:5"],那么我的程序应该返回字符串 A:6,B:2

我的最终输出字符串应该按字母顺序返回键。求和后排除值为0 的键。

输入:new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"}

输出:B:3,Y:1

输入:new String[] {"Z:0", "A:-1"}

输出:A:-1

尝试过的代码:

public static String Output(String[] strArr) {
       //strArr = new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"};
        Map<String, Double> kvs =
                Arrays.asList(strArr)
                    .stream()
                    .map(elem -> elem.split(":"))
                    .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1])));
        
        kvs.entrySet().forEach(entry->{
            System.out.println(entry.getKey() + " " + entry.getValue());  
         });
        
        return strArr[0];
      }

错误:

线程“主”java.lang.IllegalStateException 中的异常:重复键 -1.0

我该如何解决这个问题?

【问题讨论】:

  • 您在创建地图时向地图添加相同的键。只需将您的 Map 替换为 List&lt;Pair&gt;
  • 我怎样才能避免这种情况并解决这个问题
  • 您不能将重复的键添加到映射中。仅替换以前的值。
  • 你能建议我解决这个问题吗
  • 可以使用Map::compute修改当前值(key是否存在无关)。

标签: java collections


【解决方案1】:

也可以使用Collectors.groupingBy + Collectors.summingDouble通过收集到TreeMap来构建一个排序的kvs映射:

String [] strArr = new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"};
Map<String, Double> kvs = Arrays.stream(strArr)
        .map(elem -> elem.split(":"))
        .collect(Collectors.groupingBy(
            e -> e[0], 
            TreeMap::new, // sort by key
            Collectors.summingDouble(e -> Double.parseDouble(e[1]))
        ));
System.out.println(kvs);  // entries with 0 value yet to be removed
// output
// {B=3.0, X=0.0, Y=1.0}

如果只需要以上述格式打印地图,不包含 0 值,则可以这样做:

System.out.println(
    kvs.entrySet().stream()
        .filter(e -> e.getValue() != 0)
        .map(e -> new StringBuilder(e.getKey()).append(':').append(e.getValue().intValue()) )
        .collect(Collectors.joining(","))
);
// output
// B:3,Y:1

如果需要从 kvs 中删除 0 个值,则可以将 removeIf 应用于其条目集:

kvs.entrySet().removeIf(e -> e.getValue() == 0);
System.out.println(kvs);
// output
// {B=3.0, Y=1.0}

【讨论】:

    【解决方案2】:

    它对我有用,我使用 Integer 而不是 double 和 summaringInt() 函数来求和具有相同键的值:

            String[] strArr = new String[] { "X:-1", "Y:1", "X:-4", "B:3", "X:5" };
    
        Map<String, IntSummaryStatistics> collect = Arrays.asList(strArr)
            .stream()
            .map(elem -> elem.split(":"))
            .collect(Collectors.groupingBy(e -> e[0], Collectors.summarizingInt(e -> Integer.parseInt(e[1]))));
    
        System.out.println("Result:");
    
        collect.entrySet().stream()
            .filter(e -> e.getValue().getSum() != 0)
            .sorted(Map.Entry.comparingByKey())
            .forEach(e -> System.out.println("Key : " + e.getKey() + ", Value : " + e.getValue().getSum()));
    

    【讨论】:

    • Collectors.summingInt 也应该没问题
    【解决方案3】:

    你应该在第一个流中声明一个合并策略:

    .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1]), Double::sum));
    

    然后按零值过滤 Map:

      .filter(s-> s.getValue() != 0)
    

    用于按键排序:

       .sorted(Map.Entry.comparingByKey())
    

    结果代码:

       String [] strArr = new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"};
        Map<String, Double> kvs =
                Arrays.asList(strArr)
                        .stream()
                        .map(elem -> elem.split(":"))
                        .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1]), Double::sum));
    
        kvs.entrySet().stream()
                .filter(s-> s.getValue() != 0)
                .sorted(Map.Entry.comparingByKey())
                .forEach(entry->{
            System.out.println(entry.getKey() + " " + entry.getValue());w
        });
    

    【讨论】:

      猜你喜欢
      • 2014-06-06
      • 1970-01-01
      • 2017-04-08
      • 2021-09-13
      • 2012-02-11
      • 2014-07-22
      • 2023-03-15
      • 2019-04-15
      • 1970-01-01
      相关资源
      最近更新 更多