我在使用Java HashMap API时遇到问题。我遍历循环,然后将键和值插入HashMap。在插入到hashmap之前,我还会检查所有值是否正确存在。之后,我打印了哈希图,最后打印了相同的值。但是所有值都是上述循环的最后一个值。下面是代码:-
Map<String,Map<String,StockReOrderLevel>> stockReorderLevels = new HashMap<>();
List<StockReOrderLevel> defaultStockItemList = db.findDefaultStockItem();
List<String> orderedItemCodes=new ArrayList<>();
Map<String, StockReOrderLevel> itemMap = new HashMap<>();
defaultStockItemList.forEach(item-> {
orderedItemCodes.add(item.getCode());
itemMap.put(item.getCode(), item);
});
outletList.forEach(outletCode->{
Map<String, StockReOrderLevel> clone = (Map<String, StockReOrderLevel>) ((HashMap<String, StockReOrderLevel>) itemMap).clone();
List<OutletItem> lastStockTakenForOutlet = db.findLastStockTakenForOutlet(outletCode);
if(lastStockTakenForOutlet!=null && !lastStockTakenForOutlet.isEmpty()){
lastStockTakenForOutlet.forEach(outletItem -> {
if (clone.containsKey(outletItem.getItemCode())) {
StockReOrderLevel stockReOrderLevel = clone.get(outletItem.getItemCode());
stockReOrderLevel.setReorderlevel(outletItem.getReorderLevel());
clone.put(outletItem.getItemCode(),stockReOrderLevel);
}
});
//get database values
Map<String,Object> paramMap=new HashMap<>();
paramMap.put("outletCode",outletCode);
paramMap.put("takenDate",lastStockTakenForOutlet.get(0).getTakenDate());
List<ItemLevel> reOrderedLevelOutletItems=db.findTotalOrderdBottlesByOutlet(paramMap);
//change the clone again
if(reOrderedLevelOutletItems!=null && !reOrderedLevelOutletItems.isEmpty()){
reOrderedLevelOutletItems.forEach(itemLevel -> {
if (clone.containsKey(itemLevel.getItemCode())) {
StockReOrderLevel stockReOrderLevel = clone.get(itemLevel.getItemCode());
stockReOrderLevel.setReorderlevel(stockReOrderLevel.getReorderlevel()+itemLevel.getAmount());
clone.put(itemLevel.getItemCode(),stockReOrderLevel);
}
});
}
}
//convert map and it gives the map correctly
Map<String,StockReOrderLevel> idlOrdered= getIndexedItemOrder(orderedItemCodes,clone);
//i printed values before add to parent map in here
stockReorderLevels.put(outletCode, idlOrdered);
});
return stockReorderLevels;
答案 0 :(得分:1)
在for循环之后打印时,当您得到重复的最后一个元素时,几乎可以肯定是由于未声明新变量(因此也没有新的内存)。例如:
List <Integer[]> arrayOuter = new ArrayList <> ();
Integer[] array = new Integer[] {1, 2, 3, 4};
for (int i = 0; i < 4; i++) {
//shuffle array
Collections.shuffle(Arrays.asList(array));
//add array to arraylist
arrayOuter.add(array);
}
如果洗牌的最后结果是{4,2,1,3},它将打印{4,2,1,3} 4次,因为我声明数组被插入一次,因此所有元素都指向一个数组(每个迭代覆盖先前的迭代)。正确的方法是在循环的每次迭代中声明一个新数组,如下所示:
List <Integer[]> arrayOuter = new ArrayList <> ();
for (int i = 0; i < 4; i++) {
Integer[] array = new Integer[] {1, 2, 3, 4};
//shuffle array
Collections.shuffle(Arrays.asList(array));
//add array to arraylist
arrayOuter.add(array);
}
我能想到的另一个罪魁祸首是您的键,outletCode保持不变,并且您在循环的每次迭代中都覆盖了先前的(键,值)。
答案 1 :(得分:0)
最后,答案由@ThomasKläger解决。我将defaultStockItem插入循环中,编辑的代码在这里。
Map<String,Map<String,StockReOrderLevel>> stockReorderLevels = new HashMap<>();
outletList.forEach(outletCode->{
List<StockReOrderLevel> defaultStockItemList = db.findDefaultStockItem();
List<String> orderedItemCodes=new ArrayList<>();
Map<String, StockReOrderLevel> itemMap = new HashMap<>();
defaultStockItemList.forEach(item-> {
orderedItemCodes.add(item.getCode());
itemMap.put(item.getCode(), item);
});
Map<String, StockReOrderLevel> clone = (Map<String, StockReOrderLevel>) ((HashMap<String, StockReOrderLevel>) itemMap).clone();
List<OutletItem> lastStockTakenForOutlet = db.findLastStockTakenForOutlet(outletCode);
if(lastStockTakenForOutlet!=null && !lastStockTakenForOutlet.isEmpty()){
lastStockTakenForOutlet.forEach(outletItem -> {
if (clone.containsKey(outletItem.getItemCode())) {
StockReOrderLevel stockReOrderLevel = clone.get(outletItem.getItemCode());
stockReOrderLevel.setReorderlevel(outletItem.getReorderLevel());
clone.put(outletItem.getItemCode(),stockReOrderLevel);
}
});
//get database values
Map<String,Object> paramMap=new HashMap<>();
paramMap.put("outletCode",outletCode);
paramMap.put("takenDate",lastStockTakenForOutlet.get(0).getTakenDate());
List<ItemLevel> reOrderedLevelOutletItems=db.findTotalOrderdBottlesByOutlet(paramMap);
//change the clone again
if(reOrderedLevelOutletItems!=null && !reOrderedLevelOutletItems.isEmpty()){
reOrderedLevelOutletItems.forEach(itemLevel -> {
if (clone.containsKey(itemLevel.getItemCode())) {
StockReOrderLevel stockReOrderLevel = clone.get(itemLevel.getItemCode());
stockReOrderLevel.setReorderlevel(stockReOrderLevel.getReorderlevel()+itemLevel.getAmount());
clone.put(itemLevel.getItemCode(),stockReOrderLevel);
}
});
}
}
//convert map and it gives the map correctly
Map<String,StockReOrderLevel> idlOrdered= getIndexedItemOrder(orderedItemCodes,clone);
//i printed values before add to parent map in here
stockReorderLevels.put(outletCode, idlOrdered);
});
return stockReorderLevels;