web-dev-qa-db-ja.com

javaコレクション-マップのkeyset()vs entrySet()

文字列配列要素は、文字列配列の要素がキーであり、Wordの頻度が値であるマップです。

_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
_

しかし、whileループの行1のコメントを解除すると、つまり

_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()とともに使用する場合、反復子にはキーがほとんどありません。

32
NINCOMPOOP

Iterator.next()を呼び出すたびに、反復子が次の要素に移動します。現在の要素を複数のステートメントまたは式で使用する場合は、ローカル変数に保存する必要があります。または、さらに良いことに、単にfor-eachループを使用してみませんか?

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

さらに、各キーに対してマップを2回クエリしないため、entrySetのループが高速になります。また、_Map.Entry_実装は通常toString()メソッドを実装するため、キーと値のペアを手動で印刷する必要はありません。

_for (Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry);
}
_
48
Natix

Itr2.next()を呼び出すたびに、明確な値を取得しています。同じ値ではありません。これはループ内で1回だけ呼び出す必要があります。

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

大きなマップentrySet()を横断することは、keySet()よりもはるかに優れています。 this チュートリアルで、entrySet()を使用してラージオブジェクトのトラバーサルを最適化する方法と、パフォーマンスチューニングに役立つ方法を確認してください。

2
RED.Skull

Iteratorは前方にのみ移動し、一度読み取った場合は完了します。きみの

_m.get(itr2.next());
_

itr2.next();の次の値を読み込んでいるので、いくつかのキー(実際にはいくつかではなく、他のすべてのキー)が欠落しています。

1
kosa

物事を簡単にするために、itr2.next()を実行するたびに、ポインタが次の要素に移動することに注意してください。
これはあなたがよりよく理解するのに役立つかもしれません:

Whileループの最初の反復(ポインターは最初の要素の前にあります):
キー:if、value:2 {itr2.next()=if; m.get(itr2.next()=it)=>2}

Whileループの2回目の反復(ポインターは3番目の要素の前にあります):
キー:は、値:2 {itr2.next()=is; m.get(itr2.next()=to)=>2}

Whileループの3番目の反復(ポインターは5番目の要素の前にあります):
キー:be、value:1 {itr2.next()="be"; m.get(itr2.next()="up")=>"1"}

Whileループの4番目の反復(ポインターは7番目の要素の前にあります):
キー:me、value:1 {itr2.next()="me"; m.get(itr2.next()="delegate")=>"1"}

キー:if、value:1
キー:it、value:2
キー:は、値:2
キー:〜、値:2
キー:be、値:1
キー:上、値:1
キー:me、値:1
キー:デリゲート、値:1

以下を印刷します。

キー:if、value:2
キー:は、値:2
キー:be、値:1
キー:me、値:1

0
curiousManish