Java - Невозможно получить доступ к HashMap в HashMap - PullRequest
0 голосов
/ 25 ноября 2018

Я проверил переполнение стека, но не могу найти решение своей проблемы!

У меня есть класс, который перебирает символы и преобразует текстовый файл данных в хэш-карту, и у меня возникла следующая проблема.

Прежде чем я добавлю HashMap пар ключ-значение: значение в HashMap HashMaps, он работает нормально, и я могу получить доступ к этим данным:

в ConfigHandler.Java:

Временная карта:

Map<String, String> tempHashMap = new HashMap<>();

Код (в читаемом формате):

this.containers.put(this.currentHashMapKey, tempHashMap);
this.currentHashMapKey = "";
//CHECK KEY, VALUE PAIRS
for(Map.Entry<String, String> entry: tempHashMap.entrySet())
{
    String key = entry.getKey();
    String value = entry.getValue();

    System.out.println(key + ":" + value);
}
tempHashMap.clear()

Однако, как только он был добавлен в 'Super-HashMap,«хотя я могу получить доступ к объекту с помощью его ключа, HashMap, который я получаю, пуст.

(обратите внимание, что это также не работает, когда непосредственно в классе ConfigHandler)

В ConfigHandler.java:

public Map<String, Map<String, String>> getContainerList()
{
    return this.containers;
}

public Map<String, String> getContainer(String name)
{
    return (Map<String, String>)this.containers.get(name);
}

В статическом методе {} другого класса (и в целом ряде try / catch):

staticReader.read(readerChars);
oreChanceConfig = new ConfigHandler(readerChars, false);

Map<String, String> chances = oreChanceConfig.getContainer("Chances");

if (oreChanceConfig.getContainerList().containsKey("Chances"))
{
    if (chances.containsKey("Saltpeter")) //It should contain this key, but doesn't
    {
        System.out.println("It actually Works"); //Does not get printed
    } else {
        System.out.println("Key Value Pairs:"); //this gets printed
        //the following loop prints nothing
        for (Map.Entry<String, String> entry : chances.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();

            System.out.println(key + ":" + value);
        }
    }
}

HashMap кода инициализации HashMaps:

private Map<String, Map<String, String>> containers = new HashMap<String, Map<String, String>>();

Ответы [ 2 ]

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

Попробуйте заменить это:

Map<String, String> chances = oreChanceConfig.getContainer("Chances");
if (oreChanceConfig.getContainerList().containsKey("Chances")) {
......
}

На это:

Map<String, String> chances = oreChanceConfig.getContainerList().get("Chances");
if (chances != null) {
......
}

Надеюсь, это поможет!

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

Я не уверен, что действительно понимаю ваше описание того, что вы делаете, но это выделяется:

    this.containers.put(this.currentHashMapKey, tempHashMap);
    // ...
    tempHashMap.clear();

Когда вы звоните clear(), вы удаляете все записи из tempHashMap.Поскольку это объект карты, который вы добавили в качестве значения на карту containers, вы также очищаете его там .

Одним из возможных решений является создание нового tempHashMapна каждой итерации ... и не вызывайте clear() после добавления его в containers.


Объяснение:

Я думал, что это создало копиюHashMap, когда вы добавили его.

Вы, кажется, думаете, что

    this.containers.put(this.currentHashMapKey, tempHashMap);

создаст копию tempHashMap.

Это НЕ так.

Фактически, то, что вы делаете, сохраняет ссылку на вашей «временной карте хеша» в качестве значения записи на карте container.В самом деле, если вы затем повторно используете временную карту, вы получите множество ссылок на этот один объект карты в вашей карте containers.

Операция Map::put(key, value) не копирует / клонирует / что бы то ни было key объект или value объект.Он просто хранит ссылки в записи карты.Если вы затем мутируете эти объекты:

  • , изменяющий value, изменяет то, что видно через карту
  • , изменяющий key, нарушает отображение (!).

Не перезаписывает ли он предыдущий HashMap всякий раз, когда я создаю новый?

Нет, не будет.Он создает новый один.Учтите это:

    Map<String, String> tempHashMap = new HashMap<>();
    tempHashMap.put("key", "value");
    tempHashMap = new HashMap<>();

Третий оператор создает новый объект HashMap и назначает ссылку на переменную tempHashMap.Это заменяет исходное значение ссылки в переменной, но не влияет на первый объект HashMap.Если у вас все еще была ссылка на исходный объект, вы все равно можете найти «ключ» и получить соответствующее «значение».

Это базовая семантика Java-определения.Присвоение объектов (либо с помощью =, либо путем передачи параметра) ТОЛЬКО назначает ссылки.Это НЕ перезаписывает фактическое состояние объекта.

Это отличается от C и C ++, где назначение объектов (или структур) и назначение указателей на объекты / структуры являются принципиально различными операциями.

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