Добавление ключа и значения в хэш-таблицу, которая внутри другой хэш-таблицы и вывод ключей и значений на печать

Есть такой кусок кода:

public class StepTracker {
HashMap<Integer, MonthData> monthToData = new HashMap<>();

public StepTracker() {
    for (int i = 0; i < 12; i++) {
        monthToData.put(i, new MonthData());

    }
}

static class MonthData {
    HashMap<Integer, Integer> dataToSteps = new HashMap<>();

    public MonthData() {
        for (int i = 0; i < 30; i++) {
            dataToSteps.put(i, 0);
        }
    }

    @Override
    public String toString() {

        return "1-й день: " + dataToSteps.get(0).toString() + ", " +
                "2-й день: " + dataToSteps.get(1).toString() + ", " +
                "3-й день: " + dataToSteps.get(2).toString() + ", " +
                "4-й день: " + dataToSteps.get(3).toString() + ", " +
                "5-й день: " + dataToSteps.get(4).toString() + ", " +
                "6-й день: " + dataToSteps.get(5).toString() + ", " +
                "7-й день: " + dataToSteps.get(6).toString() + ", " +
                "8-й день: " + dataToSteps.get(7).toString() + ", " +
                "9-й день: " + dataToSteps.get(8).toString() + ", " +
                "10-й день: " + dataToSteps.get(9).toString() + ", " +
                "11-й день: " + dataToSteps.get(10).toString() + ", " +
                "12-й день: " + dataToSteps.get(11).toString() + ", " +
                "13-й день: " + dataToSteps.get(12).toString() + ", " +
                "14-й день: " + dataToSteps.get(13).toString() + ", " +
                "15-й день: " + dataToSteps.get(14).toString() + ", " +
                "16-й день: " + dataToSteps.get(15).toString() + ", " +
                "17-й день: " + dataToSteps.get(16).toString() + ", " +
                "18-й день: " + dataToSteps.get(17).toString() + ", " +
                "19-й день: " + dataToSteps.get(18).toString() + ", " +
                "20-й день: " + dataToSteps.get(19).toString() + ", " +
                "21-й день: " + dataToSteps.get(20).toString() + ", " +
                "22-й день: " + dataToSteps.get(21).toString() + ", " +
                "23-й день: " + dataToSteps.get(22).toString() + ", " +
                "24-й день: " + dataToSteps.get(23).toString() + ", " +
                "25-й день: " + dataToSteps.get(24).toString() + ", " +
                "26-й день: " + dataToSteps.get(25).toString() + ", " +
                "27-й день: " + dataToSteps.get(26).toString() + ", " +
                "28-й день: " + dataToSteps.get(27).toString() + ", " +
                "29-й день: " + dataToSteps.get(28).toString() + ", " +
                "30-й день: " + dataToSteps.get(29).toString();
        }
    }
}

Внутри таблицы monthToData находится таблица dataToSteps. Также есть класс с методом, который принимает значения и записывает их в хэш-таблицу monthToData и в хэш-таблицу dataToSteps:

class InputUserMonthDataSteps {
    public void savingIndicatorsInTheTable(Integer month, Integer data, Integer steps) {
        MonthData monthData = new MonthData();
        StepTracker stepTracker = new StepTracker();

        monthData.dataToSteps.replace(data, steps);
        stepTracker.monthToData.replace(month, monthData);
        System.out.println("В " + (month + 1) + "-м месяце ваша статистика " + stepTracker.monthToData.get(month));
    }
}

Вот в чём дело. В метод savingIndicatorsInTheTable я передаю параметры, после он печатает статистику. Например, передаю параметры month = 1, data = 10, steps = 2155 и метод печатает:

В 1-м месяце ваша статистика 1-й день: 0, 2-й день: 0, 3-й день: 0, 4-й день: 0, 5-й день: 0, 6-й день: 0, 7-й день: 0, 8-й день: 0, 9-й день: 0, 10-й день: 2155, 11-й день: 0, 12-й день: 0, 13-й день: 0, 14-й день: 0, 15-й день: 0, 16-й день: 0, 17-й день: 0, 18-й день: 0, 19-й день: 0, 20-й день: 0, 21-й день: 0, 22-й день: 0, 23-й день: 0, 24-й день: 0, 25-й день: 0, 26-й день: 0, 27-й день: 0, 28-й день: 0, 29-й день: 0, 30-й день: 0

Но если я снова передам параметры, например, month = 1, data = 15, steps = 3015, то метод напечатает:

В 1-м месяце ваша статистика 1-й день: 0, 2-й день: 0, 3-й день: 0, 4-й день: 0, 5-й день: 0, 6-й день: 0, 7-й день: 0, 8-й день: 0, 9-й день: 0, 10-й день: 0, 11-й день: 0, 12-й день: 0, 13-й день: 0, 14-й день: 0, 15-й день: 3015, 16-й день: 0, 17-й день: 0, 18-й день: 0, 19-й день: 0, 20-й день: 0, 21-й день: 0, 22-й день: 0, 23-й день: 0, 24-й день: 0, 25-й день: 0, 26-й день: 0, 27-й день: 0, 28-й день: 0, 29-й день: 0, 30-й день: 0

То есть данные за 10-й день, которые вносились до этого, теперь перезаписаны и равны нулю (10-й день: 0), а данные за 15-й день внесены и напечатаны (15-й день: 3015).

Как мне сделать так, чтобы все данные которые я вношу записывались в хэш-таблицу и не перезаписывались на 0 при вводе новых данных?


Ответы (2 шт):

Автор решения: Nowhere Man

В методе savingIndicatorsInTheTable при каждом вызове создаются новые экземпляры классов MonthData и StepTracker, поэтому эта информация и обнуляется. Если нужно сохранять это состояние между вызовами, данные переменные нужно вынести на уровень выше:

class InputUserMonthDataSteps {
    private StepTracker stepTracker = new StepTracker();

    public void savingIndicatorsInTheTable(Integer month, Integer data, Integer steps) {
        stepTracker.monthToData
            .computeIfAbsent(month, m -> new MonthData()) // MonthData для месяца
            .dataToSteps.put(data, steps);
        System.out.println("В " + (month + 1) + "-м месяце ваша статистика " + stepTracker.monthToData.get(month));
    }
}

Однако следует отметить, что сама структура данных не соответствует обычному календарю и как минимум класс-обёртку MonthData можно спокойно заменить массивом целых чисел, или даже использовать "двумерный" массив:

class StepTracker {
    int[][] steps = {
        new int[31], new int[28], new int[31], new int[30],
        new int[31], new int[30], new int[31], new int[31],
        new int[30], new int[31], new int[30], new int[31]
    };

    public void savingIndicatorsInTheTable(int month, int data, int steps) {
        steps[month][data] = steps;
        
        printMonthStats(month);
    }

    public void printMonthStats(int month) {
        System.out.println("В " + (month + 1) + "-м месяце ваша статистика:");
        for (int i = 0, n = steps[month].length; i < n; i++) {
            System.out.println(i + 1 + "-й день: " + steps[month][i]);
        }
    }
}
→ Ссылка
Автор решения: Дмитрий

Я не знаю зачем вам это надои почему вы идете по такому пути, но даже в этом случае все на много проще:

public class StepTracker {

    private final List<List<Integer>> monthToData;

    public StepTracker() {
        monthToData = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            List<Integer> dataToSteps = new ArrayList<>();
            for (int j = 0; j < 30; j++) dataToSteps.add(0);
            monthToData.add(dataToSteps);
        }
    }

    public void savingIndicatorsInTheTable(Integer month, Integer data, Integer steps) {
        monthToData.get(month).add(data, steps);
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < monthToData.size(); i++) {
            List<Integer> dataToSteps = monthToData.get(i);
            for (int j = 0; j < dataToSteps.size(); j++) {
                sb.append((j + 1)).append("-й день: ").append(dataToSteps.get(j).toString()).append("\n");
            }
        }
        return sb.toString();
    }

}
→ Ссылка