Hatena::ブログ(Diary)

argius note RSSフィード

開発しています

2007-06-14

[]MapのiterationはentrySet().iterator()を使う 02:55 MapのiterationはentrySet().iterator()を使うを含むブックマーク MapのiterationはentrySet().iterator()を使うのブックマークコメント

FindBugsで気づいたんですが、下記のようなコードはパフォーマンス的によろしくないのでした。

Map map = new HashMap();
// ...
for (Iterator it = map.keySet().iterator(); it.hasNext();) {
    Object key = it.next();
    Object value = map.get(key);
}

これは、こう書くべきでした。

Map map = new HashMap();
// ...
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
    Map.Entry entry = (Map.Entry)it.next();
    Object key = entry.getKey();
    Object value = entry.getValue();
}

何も考えずにkeySet()のほうを使ってたんですが、言い訳させていただくと、おそらくPerlのイディオムをそのまま置き換えたためと思われます。ちなみに、Perlのhash-iterationは次のようにします。

my %hash = (a => "A",
            b => "B");
for my $key (keys %hash) {
  printf qq{%s="%s"\n}, $key, $hash{$key};
}

追記:Perlもeachを使えば出来るとコメントいただきました。普通にPerlのマニュアルにサンプルコードがありましたね...

while (my ($key,$value) = each %ENV) {
  print "$key=$value\n";
}

smegheadsmeghead 2007/06/15 11:00 Perlでは、eachを使えば同じ事ができますね。速度のことはわからないですが。

argiusargius 2007/06/15 14:48 言い訳しているものの、Javaの方はHashMapの構造「要素をインナークラスMap.Entryの配列で保持している」ことは知っていたので、気付いてはいたはずなんですよね。
いずれにしても、よく考えずに使ってたってことですね。反省です...
ありがとうございました。

トラックバック - http://d.hatena.ne.jp/argius/20070614/1181843715