2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MapのkeySet , valuesを使うべきではない

Last updated at Posted at 2019-07-31

↓のようにkeyしか使用しないコードでもfindbugsでentrySet()を使えと警告がでた。

for(var key : map.keySet()){
    // map.get(key)などやらず、純粋にkeyしか使用しない処理
}

keyとvalue 両方使用するならentrySet()のほうが効率が良いのと解釈していたので、片方のみ使用する場合は効率に関係ないのでは?
むしろ、Entry<K,V>はkeyとvalue両方持つので不要な片方のリソースが無駄ではないのかと思い、裏取りのため内部実装を見てみる。

AbstractMap.java
public Set<K> keySet() {
        Set<K> ks = keySet;
        if (ks == null) {
            ks = new AbstractSet<K>() {
                public Iterator<K> iterator() {
                    return new Iterator<K>() {
                        private Iterator<Entry<K,V>> i = entrySet().iterator();
                        
                        // 略

                    };
                }
            };
            keySet = ks;
        }
        return ks;
    }

keySetが無ければ作り出してフィールドに保持するようになっているが、Iterator<K>の初期化にentrySet().iterator()を呼び出していることがわかる。
結局のところkeySet()values()ではentrySet()を通してごにょる様子。

つまり、keyまたはvalueの片方のみであっても思考停止でentrySet()を使用したほうがいいという警告は正しかったのである。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?