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()
, то итератор не имеет нескольких ключей!
Ответы
Ответ 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