Java HashMap повторяется для каждого цикла, но все значения одинаковы, являясь последним значением цикла - PullRequest
0 голосов
/ 17 ноября 2018

У меня проблема с использованием 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;

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Наконец, ответ решается @ 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;
0 голосов
/ 17 ноября 2018

Когда последний элемент повторяется при печати после цикла 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 остается неизменным, и вы перезаписываете свой предыдущий (ключ, значение) каждую итерацию цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...