【问题标题】:Hashmap entries are replacing when adding new key value pair添加新的键值对时,Hashmap 条目正在替换
【发布时间】:2015-02-05 08:14:38
【问题描述】:

我必须使用循环向 hashmap 添加一些列表数据。当我使用不同的键将第二个列表添加到 hashmap 时,hashmap 中的第一个列表也被第二个列表替换。为什么会发生这种情况?请帮助我解决这个问题。下面是我的代码

private List<COAAccount> dataCoa=new ArrayList<COAAccount>();
private List<COAAccount> finalList=new ArrayList<COAAccount>();
private Map<Integer,List<COAAccount>> brkDBMap;
private Map<Integer,List<COAAccount>> brkVwMap=new HashMap<Integer, List<COAAccount>>();

我已将一些值加载到 brkDBMap。然后,

Iterator itDB = brkDBMap.entrySet().iterator();
while (itDB.hasNext()) {
                Map.Entry pairs = (Map.Entry)itDB.next();
                int key=(int) pairs.getKey();
                List<COAAccount> valueList=(List<COAAccount>) pairs.getValue();
                if(brkVwMap.containsKey(key)) {
                    System.out.println("****EXIST******");
                }else{
                    //finalList=new ArrayList<COAAccount>();
                    finalList = new ArrayList<COAAccount>(dataCoa);

                    Iterator<COAAccount> itertrMap=valueList.iterator();
                    while(itertrMap.hasNext()){
                        int s=-1;
                        COAAccount importCoa=new COAAccount();
                        importCoa=restTemplate.postForObject("http://localhost:8080/SaveIt/stock/getCopyBudget", itertrMap.next(),COAAccount.class);

                        switch (importCoa.getAccPerId()) {
                            case 0: s =9;
                                    break;
                            case 1: s=10;
                                    break;
                            case 2: s=11;
                                    break;
                            case 3: s=0;
                                    break;
                            case 4: s=1;
                                    break;
                            case 5: s=2;
                                    break;
                            case 6: s=3;
                                    break;
                            case 7: s=4;
                                    break;
                            case 8: s=5;
                                    break;
                            case 9: s=6;
                                    break;
                            case 10:s=7;
                                    break;
                            case 11:s=8;
                                    break;
                            default:
                                    break;
                        }
                        COAAccount impCAcct=new COAAccount();
                        impCAcct=finalList.get(s);
                        impCAcct.setBudBrk(importCoa.getiD(), importCoa.getBudID(), importCoa.getAccPerId(), importCoa.getBudgetAmount(), importCoa.getDescAdd());

                        finalList.set(s, impCAcct);
                    }
                    brkVwMap.put(key,finalList);

                }


            }

这里 brkDBMap 和 brkVwMap 是 hashmap。我需要将列表添加到 brkVwMap。如果我想将键 1 和 2 的值“Account1”和“Account2”分别插入到 brkVwMap,那么在添加“Account2”后,地图变为{1=[Account2], 2=[Account2]} 而不是 {1=[Account1], 2=[Account2]}

【问题讨论】:

  • 键是相同的还是不同的?
  • 键不同。首先我用键 1 加值。然后我用键 2 加值,但这会导致 1 的值字段也发生变化
  • 对于初学者,请使用泛型并格式化您的代码。
  • @KJEjava48 itDB里面的内容是什么?
  • map.computeIfAbsent(key, k-&gt; new ArrayList&lt;&gt;()).add(value); 怎么样?

标签: java list hashmap


【解决方案1】:
brkVwMap.put(key,finalList);

你添加到你的地图的值是finalList,它被初始化:

//finalList=new ArrayList<COAAccount>();
finalList=dataCoa;

您没有显示 dataCoa 的初始化位置,但我怀疑它已初始化一次,因此您的地图中的所有值都是相同的。

您注释掉的行更有意义。 如果你想用dataCoa的内容初始化finalList,但是map的不同key仍然有不同的值,你应该写:

finalList = new ArrayList<COAAccount>(dataCoa);

【讨论】:

  • 我已经初始化了 dataCoa,它也包含一些值。我没有在这段代码中显示它
  • @KJEjava48 我确定您已对其进行了初始化,但由于您使用与映射中多个键的值相同的对象,因此更改一个键的值会更改所有其他键的值.
  • 还是同样的问题
  • 我认为在这一步之后替换发生 impCAcct.setBudBrk(importCoa.getiD(), importCoa.getBudID(), importCoa.getAccPerId(), importCoa.getBudgetAmount(), importCoa.getDescAdd() );
【解决方案2】:

使用finalList=dataCoa;,您创建了一个浅拷贝,因此您使用 finalList 的每个引用(即 HashMap 中的每个值)都指向同一个列表 dataCoa,并且每当更改最终列表。

作为一个例子,你可以使用这样的东西:

List<String> a = new ArrayList<String>();
a.add("a");

List<String> b = a;
b.add("b");

List<String> c = new ArrayList<String>(a);
c.add("c");

System.out.println(a);
System.out.println(b);
System.out.println(c);

这样,b 与 a 是同一个列表,而 c 是深拷贝,其中所有元素都被复制到一个新列表中,并且更改不会反映在 a 和 b 上。 结果输出为:

[a, b]
[a, b]
[a, b, c]

所以 Eran 说你的代码是对的

//finalList=new ArrayList<COAAccount>();
finalList=dataCoa;

应该是:

finalList=new ArrayList<COAAccount>(dataCoa);
//finalList=dataCoa;

当然必须注释/删除第二行,否则你会用之前出现问题的相同引用覆盖新列表;)

【讨论】:

    猜你喜欢
    • 2021-04-05
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多