Java HashMap遍历每个循环,但是所有值都是相同的,是循环的最后一个值

时间:2018-11-17 04:14:57

标签: java java-8 hashmap

我在使用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;

2 个答案:

答案 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;