Подтвердить что ты не робот

Java collections - keyset() vs entrySet() на карте

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

String[] args = {"if","it","is","to","be","it","is","up","me","to","delegate"};

то на карте будут такие элементы, как [ if:1, it:2 .... ]

Set<String> keys = m.keySet();
System.out.println("keyset of the map : "+keys);

печатает все клавиши: "if","it","is","to","be","it","is","up","me","to","delegate"

Set<Map.Entry<String, Integer>> entrySet = m.entrySet();
Iterator<Map.Entry<String, Integer>> i = entrySet.iterator();
while(i.hasNext()){
    Map.Entry<String, Integer> element = i.next();
    System.out.println("Key: "+element.getKey()+" ,value: "+element.getValue());
}

выводит все пары значений ключей:

Использование набора записей печатает все значения:

Key: if ,value: 1
Key: it ,value: 2
Key: is ,value: 2
Key: to ,value: 2
Key: be ,value: 1
Key: up ,value: 1
Key: me ,value: 1
Key: delegate ,value: 1

Но блок кода ниже должен печатать точно тот же вывод, что и выше, но это не так:

Iterator<String> itr2 = keys.iterator();
while(itr2.hasNext()){
    //System.out.println(itr1.next()+" ");
    //System.out.println(m.get(itr1.next())+" ");
    System.out.println("Key: "+itr2.next()+" ,value: "+m.get(itr2.next()));
}

Он печатает:

Key: if ,value: 2
Key: is ,value: 2
Key: be ,value: 1
Key: me ,value: 1

Но если мы раскомментируем строку 1 в цикле while i.e

System.out.println(itr1.next()+" ");

и прокомментируйте строку

System.out.println("Key: "+itr2.next()+" ,value: "+m.get(itr2.next()));

Затем мы получаем все ключи: {"if","it","is","to","be","it","is","up","me","to","delegate"};

Если мы используем m.get() с itr2.next(), то итератор не имеет нескольких ключей!

4b9b3361

Ответ 1

Каждый вызов Iterator.next() переносит итератор на следующий элемент. Если вы хотите использовать текущий элемент в нескольких операторах или выражениях, вы должны сохранить его в локальной переменной. Или даже лучше, почему бы вам просто не использовать цикл for-each?

for (String key : map.keySet()) {
    System.out.println(key + ":" + map.get(key));
}

Кроме того, цикл над entrySet выполняется быстрее, потому что вы не запрашиваете карту дважды для каждого ключа. Кроме того, реализации Map.Entry обычно реализуют метод toString(), поэтому вам не нужно вручную печатать пару ключ-значение.

for (Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry);
}

Ответ 2

Каждый раз, когда вы вызываете itr2.next(), вы получаете отличное значение. Не то же самое значение. Вы должны вызывать это только один раз в цикле.

Iterator<String> itr2 = keys.iterator();
    while(itr2.hasNext()){
        String v = itr2.next();
        System.out.println("Key: "+v+" ,value: "+m.get(v));
    }

Ответ 3

Обход по большому карте entrySet() намного лучше, чем keySet(). Проверьте этот учебник, как они оптимизируют обход по большому объекту с помощью entrySet() и как это помогает при настройке производительности.

Ответ 4

An Iterator перемещается только вперед, если он читает его один раз, это делается. Ваш

m.get(itr2.next());

читает следующее значение itr2.next();, поэтому вам не хватает нескольких (на самом деле не несколько, и других) ключей.

Ответ 5

Чтобы упростить itr2.next(), обратите внимание, что каждый раз, когда вы выполняете itr2.next() указатель перемещается к следующему элементу, т. itr2.next() Здесь, если вы внимательно обратите внимание, то вывод будет в полном соответствии с написанной вами логикой.
Это может помочь вам лучше понять:

1-я итерация цикла While (указатель находится перед 1-м элементом):
Ключ: if, значение: 2 {itr2.next()=if; m.get(itr2.next()=it)=>2} {itr2.next()=if; m.get(itr2.next()=it)=>2}

2-я итерация цикла While (указатель перед 3-м элементом):
Ключ: есть, значение: 2 {itr2.next()=is; m.get(itr2.next()=to)=>2} {itr2.next()=is; m.get(itr2.next()=to)=>2}

3-я итерация цикла While (указатель перед 5-м элементом):
Ключ: be, значение: 1 {itr2.next()="be"; m.get(itr2.next()="up")=>"1"} {itr2.next()="be"; m.get(itr2.next()="up")=>"1"}

Четвёртая итерация цикла While (указатель перед седьмым элементом):
Ключ: я, значение: 1 {itr2.next()="me"; m.get(itr2.next()="delegate")=>"1"} {itr2.next()="me"; m.get(itr2.next()="delegate")=>"1"}

Ключ: если, значение: 1
Ключ: оно, значение: 2
Ключ: есть, значение: 2
Ключ: до, значение: 2
Ключ: быть, значение: 1
Ключ: вверх, значение: 1
Ключ: я, значение: 1
Ключ: делегат, значение: 1

Это печатает:

Ключ: если, значение: 2
Ключ: есть, значение: 2
Ключ: быть, значение: 1
Ключ: я, значение: 1