Java HashMap对每个循环进行迭代,但所有值都是相同的,这是循环的最后一个值



我在使用Java HashMap API时遇到问题。我遍历循环,然后将键和值插入到HashMap中。在插入到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;

当在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);
}

如果shuffle的最后一个结果是{4,2,1,3},它将打印{4,2,1,2,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保持不变,并且在循环的每次迭代中都会覆盖您以前的(键,值(。

最后,@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;

最新更新