まず、イテレータが2つのオブジェクトのタプルを返すように思っているようです。
Javaでは、これを実行する唯一の方法は、別のオブジェクトにそれらをラップすることです。 (書いている時点では、そうです。)イテレータは、キーと値以外のオブジェクトを返さなければなりません。そのオブジェクトは、next()
への呼び出しが返される前に、ある時点で作成されなければなりません。
put()
にこのエントリオブジェクトを作成します。このことを念頭に置いて、制約付き は取るには3つのもっともらしいパスがあります。
entrySet()
の最初の繰り返しでエントリオブジェクトを作成します(後でキャッシュします)。
entrySet()
のすべての反復で新しいエントリオブジェクトを作成します。
組み込みのEnumMap
は、実装が最も簡単であり、エントリを反復処理する必要がない場合に最も経済的な解決策であるという理由で、オプション3になりました。欠点は、複数回反復する必要がある場合は、他のソリューションより多くのオブジェクトを作成することです。
オプション1は実装が簡単ですが、アクセスするつもりがない場合でも、マップにエントリを追加するたびに明白なオーバーヘッドがあります。
最後に、オプション2では、コードの複雑さがわずかに増加し、反復処理と要素の追加を繰り返す際にいくつかのエッジケースが発生しますが、理論的には最高のメモリプロファイルが得られます。
複数の繰り返しのメモリオーバーヘッドがアプリケーションで問題であることが判明した場合は、オプション2を簡単に実装できますが、ほとんどの場合、その違いが目立つのではないでしょうか。
p.s.:あなたが慣用的な解決法から逸脱し、わずかに狂った領域に入る場合は、同じMap.Entry
インスタンスをすべてのエントリに再利用することができます。これは明らかにMap.Entry
から期待されるものと矛盾しますが、メモリ割り当てのオーバーヘッドが最小限に抑えられ、簡単な反復シナリオでそれを取り除くことができます。あなたがより速い最終製品で終わるかどうかは誰でも推測されます、あなたはそれを測定する必要があります。
あなた自身の解決策は何が悪いですか? – RealSkeptic
'for(V value:map.values())foo(value);'はどうでしょうか?値を取得する以外の目的でキーを使用しているようではありません。 – VGR
@VGRフェアポイント。私はキーも必要です。 – hawk