【问题标题】:java adding sublists into the nested hash maps in for loopjava将子列表添加到for循环中的嵌套哈希映射中
【发布时间】:2017-04-18 10:34:17
【问题描述】:

我有一个名为 banksNumberOfOrders 的多维数组,它用一些整数值初始化。

我已经构建了嵌套的 hashmap,它有两个整数键,它们也是 banksNumberOfOrders 的行和列索引,并且有一个列表。

我通过嵌套的 for 循环将数量为 banksNumberOfOrders[i][j] 的随机值添加到列表中。并且,我还通过相同的嵌套 for 循环将此列表的子列表添加到嵌套的哈希图中。

我写的代码是这样的

Map<Integer, Map<Integer,List<Integer>>> paymentOrderAmounts = new HashMap<Integer, Map<Integer,List<Integer>>>(); 
List<Integer> amounts = new ArrayList<Integer>();

int count_begin = 0; //list size
for (int i=0; i<n; i++){
    for(int j=0; j<n; j++){
        if(i != j){
            for(int a=0; a<banksNumberOfOrders[i][j]; a++){         
                int amount = ThreadLocalRandom.current().nextInt(begin1, end1);
                amounts.add(amount);
            }   
            int count_end = count_begin+banksNumberOfOrders[i][j];          
            paymentOrderAmounts.put(i, new HashMap<Integer,List<Integer>>());
            paymentOrderAmounts.get(i).put(j, amounts.subList(count_begin, count_end));
            count_begin = count_end;
            System.out.println(i+" --> "+j+" "+paymentOrderAmounts.get(i).get(j)+" ");
        }   
    }       
    System.out.println();
}

此代码运行时没有错误并打印值。 但是当我尝试打印嵌套哈希图的值时,由于 sublist 的使用,我给出了 concurrentmodificationexception。 第二个导致错误的代码片段,例如

//traverse hashmap and print values
for(Map.Entry<Integer, Map<Integer,List<Integer>>> t:paymentOrderAmounts.entrySet()) {
           Integer key = t.getKey();
           for (Entry<Integer, List<Integer>> e : t.getValue().entrySet())
             System.out.println(key + "-->" + e.getKey()+" "+e.getValue());
        }

根据我的谷歌搜索,我看到我必须使用迭代器将元素添加到列表中以抛出错误,否则会发生错误。 但我不明白我已经在使用循环,如何在这个嵌套循环中使用迭代器?

【问题讨论】:

  • 您能否发布引发 ConcurrentModificationException 和完整堆栈跟踪的代码?
  • 我可以建议你使用某种表格(行、列、值),例如看番石榴表格:github.com/google/guava/wiki/NewCollectionTypesExplained#table
  • 据我了解,此表格式(行、列、值)但我需要(行、列、值)的结构
  • 使用列表作为值。
  • 我已经使用了你的建议,番石榴表(行、列、列表)但我再次无法摆脱 ConcurrentModificationException

标签: java arraylist multidimensional-array hashmap


【解决方案1】:
        Table<Integer, Integer, List> paymentAmounts = HashBasedTable.create();
        List<Integer> amounts = new ArrayList<Integer>();
        int count_begin = 0; //list size
        for (int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                if(i != j){
                    for(int a=0; a<banksNumberOfOrders[i][j]; a++){         
                        int amount = ThreadLocalRandom.current().nextInt(begin1, end1);
                        amounts.add(amount);
                    }   
                    int count_end = count_begin+banksNumberOfOrders[i][j];          
                    paymentAmounts.put(i,j,amounts.subList(count_begin, count_end));
                    count_begin = count_end;
                    System.out.println(i+" --> "+j+" "+paymentAmounts.get(i, j)+" ");
                }   
            }       
            System.out.println();
        }

        System.out.println(paymentAmounts.cellSet()); //gives error

【讨论】:

    【解决方案2】:

    要遍历地图,

    for(Integer outerKey: paymentOrderAmounts.keySet()) {
         Map<Integer, List<Integer> innerMap = paymentOrderAmounts.get(outerKey);
         for (Integer innerKey: innerMap.keySet()) {
             List<Integer> innnerList = innerMap(innerKey);
             for (Integer innerValue: innerList) { 
                 System.out.println(outerKey + "-->" + innerKey +" "+innerValue);
             }    
         }
    }
    

    可能会更好,因为它不会尝试获取同时更改的 EntrySet 并且一次只处理一个项目。

    【讨论】:

    • List innnerList = innerMap(innerKey);给出警告innerMap(Integer) 方法未定义
    【解决方案3】:

    如果您以多线程方式执行操作,使用java.util.concurrent.ConcurrentHashMap 而不是java.util.HashMap 可能很重要。另请参阅 java.util.concurrentConcurrentSkipListMap 作为替代方案,它将以较少随机的键顺序进行迭代。

    【讨论】:

    • not mutithread ,而且我不明白你的第二个建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 2018-04-21
    相关资源
    最近更新 更多