【问题标题】:Summation of two map values java两个地图值的总和java
【发布时间】:2015-12-22 16:29:38
【问题描述】:

如何总结两个不同地图中的所有值?

Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> totalValOne= new ArrayList<String>();
List<String> totalValTwo= new ArrayList<String>();
map1.put("totalPriceSet1", totalValOne);     
map2.put("totalPriceSet2", totalValTwo);

我得到了所有的价值

String PriceValues1 = "";
for (int i = 0; i < map1.size(); i++) {
    System.out.println(map1.size());
    for (List<String> value : map1.values()) {

        for (String tot : value) {
            PriceValues1 = tot;
            System.out.println("values.....  "+ tot);
        }
    }
    //--------

String PriceValues2 = "";
for (int i = 0; i < map2.size(); i++) {
    System.out.println(map2.size());
    for (List<String> value : map2.values()) {

        for (String tot : value) {
            PriceValues2 = tot;
            System.out.println("values.....  "+ tot);
        }
    }

我正在尝试将两个地图的值一一相加。

例如:

totalPriceSet1 {1,2,3,4}
totalPriceSet2 {2,3,4,5}

我希望两者的总和为,

Sum {3,5,7,9}

【问题讨论】:

  • 有什么理由将值存储为字符串而不是整数?
  • 是的,因为我为所有值附加了$ 符号。
  • @sam 您应该查看Money as explained by Martin Fowler 的一个模式,这是一个相关的post on stackoverflow
  • @sam 您始终可以将值存储为整数,进行数字处理,然后当您需要显示/附加 $ 符号时,您可以简单地使用 Integer.toString(num) 或 '"$" + 数字'

标签: java dictionary


【解决方案1】:

请注意,如果值在 HashMap 中,则顺序实际上是随机的。 LinkedHashMapTreeMap 有明确定义的顺序。

如果地图大小不同怎么办?我在这里假设您也只需要单个值。

最好的方法是并行迭代这两个映射。这样就不会复制任何内容,并且每张地图只迭代一次。

private static List<Integer> sumMapValues(Map<?, Integer> map1, Map<?, Integer> map2) {
    Iterator<Integer> iter1 = map1.values().iterator();
    Iterator<Integer> iter2 = map2.values().iterator();
    List<Integer> sum = new ArrayList<>();
    while (iter1.hasNext() || iter2.hasNext()) {
        if (! iter2.hasNext())
            sum.add(iter1.next());
        else if (! iter1.hasNext())
            sum.add(iter2.next());
        else
            sum.add(iter1.next() + iter2.next());
    }
    return sum;
}

测试

Map<String, Integer> map1 = new LinkedHashMap<>();
map1.put("a", 1);
map1.put("b", 2);
map1.put("c", 3);
map1.put("d", 4);
Map<String, Integer> map2 = new LinkedHashMap<>();
map2.put("x", 2);
map2.put("y", 3);
map2.put("z", 4);
System.out.println(map1);
System.out.println(map2);
System.out.println(sumMapValues(map1, map2));

输出

{a=1, b=2, c=3, d=4}
{x=2, y=3, z=4}
[3, 5, 7, 4]

【讨论】:

  • 我无法添加值,因为我将其视为Map&lt;String,List&lt;Integer&gt;&gt;
【解决方案2】:

你可以做的是:

 public static void main( String[] args ){
        Map<String, Integer> map = new TreeMap<>();
        map.put( "total1", 2 );
        map.put( "total2", 3 );

        Map<String, Integer> map2 = new TreeMap<>();
        map2.put( "otherTotal1", 1 );
        map2.put( "otherTotal2", 2 );

        System.out.println( sumMaps( map, map2 ) );
    }

    private static List<Integer> sumMaps( Map<String, Integer>... maps ){
        List<Integer> result = new ArrayList<>();
        for( Map<String, Integer> map : maps ){
            List<Integer> list = new ArrayList<Integer>( map.values() );

            for( int i = 0; i < list.size(); i++ ){
                if( indexExists( result, i ) ){
                    // sums up existing and new value
                    Integer oldValue = result.get( i );
                    Integer newValue = oldValue + list.get( i );
                    result.remove( i );
                    result.add( i, newValue );
                }
                else{
                    // no existing value
                    result.add( list.get( i ) );
                }
            }
        }

        return result;
    }

    private static boolean indexExists( List<Integer> list, int index ){
        return index >= 0 && index < list.size();
    }

我用Map&lt;String,Integer&gt; 制作了你可以更改它String -&gt; String 或任何你想要的。

输出:

[3, 5]

【讨论】:

  • 使用HashMap 并不能保证排序,实际上恰恰相反,所以结果很容易得到[4, 4][5, 3]
  • 我无法添加值,因为我将其视为Map&lt;String,List&lt;Integer&gt;&gt;
【解决方案3】:

我所做的是,

    private static List<Integer> sumValue(Map<String, List<Integer>> map1,
                                 Map<String, List<Integer>> map2) 
{
        List<Integer> priceValues1Int = new ArrayList<Integer>();
        List<Integer> priceValues2Int = new ArrayList<Integer>();
        List<Integer> sum = new ArrayList<Integer>();
        for (List<Integer> integer : map1.values()) {
            priceValues1Int = integer;
        }
        for (List<Integer> integer2 : map2.values()) {
            priceValues2Int = integer2;
        }
        for(int i=0; i<priceValues1Int .size(); i++){
            int sum1 =  priceValues1Int .get(i)+priceValues2Int .get(i);
            sum.add(sum1);
        }
    return sum;
}

【讨论】:

    【解决方案4】:

    问题在于列表,而不是地图。合并两个列表,例如:

    public static void main(String... args) {
    
        // Example
        List<Integer> listA = new ArrayList<>();
        listA.add(1);
        listA.add(2);
        listA.add(3);
        listA.add(4);
    
        Map<String, List<Integer>> map1 = new HashMap<>();
    
        map1.put("totalPriceSet1", listA);
    
        List<Integer> listB = new ArrayList<>();
        listB.add(2);
        listB.add(3);
        listB.add(4);
        listB.add(5);
    
        Map<String, List<Integer>> map2 = new HashMap<>();
        map2.put("totalPriceSet2", listB);
    
        // Sum
        List<Integer> sum = sum(map1.get("totalPriceSet1"), map2.get("totalPriceSet2"));
    
        // Put in third map if you want
        Map<String, List<Integer>> map3 = new HashMap<>();
        map3.put("sum", sum);
    
        // Output
        System.out.println(map3.get("sum").stream().map(Object::toString).collect(Collectors.joining(",", "{", "}")));
    
    }
    
    public static List<Integer> sum(List<Integer> listA, List<Integer> listB) {
        List<Integer> result = new ArrayList<>();
    
        Iterator<Integer> iteratorA = listA.iterator();
        Iterator<Integer> iteratorB = listB.iterator();
    
        while (iteratorA.hasNext() && iteratorB.hasNext()) {
            result.add(iteratorA.next() + iteratorB.next());
        }
    
        return result;
    }
    

    【讨论】:

    • 该 Java 8 版本的性能非常糟糕,对元素进行顺序搜索以找到它的索引,如果您有多个相同值的元素,您会得到错误的索引,从而得到错误的总和。 --- 经典版本假定 List,其中索引查找是可以的,但问题是专门关于 Map 值的,所以这里离题了。
    • @Andreas :我删除了 java 8 版本,但不认为问题出在 map 上,提问者从不使用密钥。也就是说,问题出在map的值上,map的值是collections
    • 正确,但Collection 不是ListCollection 甚至没有 get-by-index 方法,尽管所有列表都有,但像 LinkedList 这样的列表必须按顺序搜索索引。对数组支持的列表以外的任何内容执行按索引获取对性能非常不利,并且对于这个特定问题来说是不必要的。
    • 问题在于Collection 中一个一个元素的总和(基于它们的索引)。如果此Collection 不保证排序,则此问题是不确定的并且没有任何意义,因此该问题与Collection 无关,而是List(或任何其他排序集合)。我的第一句话。
    • 对于按索引获取性能方面,我更改了我的示例并使用Iterator。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多