添加新密钥值对时,Hashmap条目正在替换

时间:2015-02-05 08:14:39

标签: java list hashmap

我必须使用loop将一些列表数据添加到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 = [帐户2],2 = [帐户2]}而不是{1 = [帐户1],2 = [帐户2]}

2 个答案:

答案 0 :(得分:2)

brkVwMap.put(key,finalList);

您添加到地图的值为finalList,初始化为:

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

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

你注释掉的那条线更有意义。 如果您要使用finalList的内容初始化dataCoa,但地图的不同键仍然具有不同的值,则应写入:

finalList = new ArrayList<COAAccount>(dataCoa);

答案 1 :(得分:0)

使用finalList=dataCoa;创建浅层副本,因此使用finalList(即HashMap中的每个值)指向的每个引用都指向相同的List dataCoa ,并且每当更改a时都会更改dataCoa finalList中的值。

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

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;

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