6

Как обойти HashMap с помощью for each?

11

Описание проблемы:

У меня есть поле типа:

HashMap<String, HashMap> selects = new HashMap<String, HashMap>();

Для каждой записи HashMap<String, HashMap> мне нужно создать ComboBox, элементы которого представляют собой значения (которые сами являются HashMap) из HashMap<String, HashMap>.

Попытка реализовать это (но неработающая версия) выглядит следующим образом:

for (int i = 0; i < selects.size(); i++) {
    HashMap h = selects[i].getValue(); // Здесь ошибка, так как selects - это HashMap, а не массив
    ComboBox cb = new ComboBox();

    for (int y = 0; y < h.size(); i++) { // Здесь также ошибка, индекс увеличивается неправильно
        cb.items.add(h[y].getValue()); // Метод getValue должен быть вызван на конкретной записи, а не на индексе
    }
}

Проблема заключается в том, что в текущем коде я неправильно пытаюсь получить элементы из HashMap и создаю ComboBox. Я не уверен, как правильно итерироваться по HashMap и добавлять элементы в ComboBox. Подскажите, как это можно исправить?

5 ответ(ов)

14

Я понимаю, что мой ответ может прийти чуть позже, но я хотел бы поделиться своим решением, вдруг это поможет кому-то еще:

HashMap<String, HashMap> selects = new HashMap<String, HashMap>();

for (Map.Entry<String, HashMap> entry : selects.entrySet()) {
    String key = entry.getKey();
    HashMap value = entry.getValue();

    // Здесь выполняйте необходимые операции
    // В вашем случае, возможно, потребуется вложенный цикл.
}

Если у вас есть какие-либо дополнительные вопросы или вам нужна помощь с конкретными задачами, не стесняйтесь спрашивать!

0

Вы можете итерироваться по HashMap (и многим другим коллекциям) с помощью итератора. Например:

HashMap<T,U> map = new HashMap<T,U>();

...

Iterator it = map.values().iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

В этом примере мы создаем HashMap и затем используем итератор для обхода значений, хранящихся в этой карте. Метод values() возвращает коллекцию значений, и мы можем получить итератор для этой коллекции. В цикле while мы проверяем, есть ли еще элементы с помощью hasNext(), и выводим их с помощью next().

0

Метод Map.values() в Java возвращает коллекцию значений, которые хранятся в Map. В вашем примере, который использует вложенные HashMap, selects.values() возвращает коллекцию всех значений верхнего уровня, где каждое значение — это HashMap<SomeInnerKeyType, String>.

Ваш код перебирает все HashMap, которые находятся в selects, и для каждого из них создаёт новый ComboBox. Затем он добавляет все значения из вложенной HashMap в items этого ComboBox. Таким образом, вы получаете удобный способ загрузить данные из сложной структуры Map в визуальный элемент интерфейса.

Вот более подробное объяснение:

HashMap<String, HashMap<SomeInnerKeyType, String>> selects =
    new HashMap<String, HashMap<SomeInnerKeyType, String>>();

...

for(HashMap<SomeInnerKeyType, String> h : selects.values())
{
   ComboBox cb = new ComboBox(); // Создаём новый ComboBox для каждой вложенной HashMap
   for(String s : h.values()) // Перебираем значения текущей вложенной HashMap
   {
      cb.items.add(s); // Добавляем каждое значение в ComboBox
   }
}

Таким образом, вы можете использовать Map.values(), чтобы легко получить доступ ко всем значениям вашего Map, что упрощает манипуляции с данными внутри сложной структуры.

0

Да, я делаю примерно то же самое, что и cx42net, но не создаю явно объект Entry.

HashMap<String, HashMap> selects = new HashMap<String, HashMap>();
for (String key : selects.keySet())
{
    HashMap<innerKey, String> boxHolder = selects.get(key);
    ComboBox cb = new ComboBox();
    for (InnerKey innerKey : boxHolder.keySet())
    {
        cb.items.add(boxHolder.get(innerKey));
    }
}

Мне кажется, это наиболее интуитивно понятным способом, и, возможно, у меня есть предвзятость против итерации по значениям карты.

Использование keySet() позволяет вам сначала получить ключи, а затем извлекать значения по каждому ключу, что выглядит чисто и понятно. Это решение также хорошо читается, поскольку сразу очевидно, что вы работаете с ключами. Если бы вы использовали entrySet(), код стал бы немного сложнее, так как вам нужно было бы управлять объектами Entry. В результате ваш подход вполне оправдан, и если он хорошо работает в вашем контексте, то это отличное решение.

0

Для работы с HashMap и его методами, таким как entrySet, вы можете использовать следующий пример кода, который демонстрирует, как вывести содержимое коллекции и обновить баланс определённого элемента.

/**
 * Вывод данных: 
D: 99.22
A: 3434.34
C: 1378.00
B: 123.22
E: -19.08

Новый баланс B: 1123.22
 */

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MainClass {
    public static void main(String[] args) {
        HashMap<String, Double> hm = new HashMap<>();

        hm.put("A", 3434.34);
        hm.put("B", 123.22);
        hm.put("C", 1378.00);
        hm.put("D", 99.22);
        hm.put("E", -19.08);

        Set<Map.Entry<String, Double>> set = hm.entrySet();

        for (Map.Entry<String, Double> me : set) {
            System.out.print(me.getKey() + ": ");
            System.out.println(me.getValue());
        }

        System.out.println();

        double balance = hm.get("B");
        hm.put("B", balance + 1000);

        System.out.println("Новый баланс B: " + hm.get("B"));
    }
}

В этом коде мы создаем HashMap, добавляем в него пары "ключ-значение" (где ключ — это строка, а значение — это число с плавающей точкой), и затем используем метод entrySet() для получения коллекции объектов Map.Entry. Эта коллекция позволяет удобно итерироваться по всем парам ключ-значение в HashMap. Кроме того, напоследок обновляем баланс элемента с ключом "B" на 1000 и выводим новый баланс.

Если вам нужно больше информации, вы можете посмотреть полный пример здесь.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь