↓のように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()
を使用したほうがいいという警告は正しかったのである。