次のように、クラスを拡張しHashMap
てカスタムremove()
メソッドを実装しようとしました。
@SuppressWarnings("serial")
private final class EntryHashMap<K, E> extends HashMap<K, E> {
@Override
public E remove(Object key) {
rowKeyMap.remove(key);
colKeyMap.remove(key);
return super.remove(key);
}
}
が直接呼び出された場合はすべてうまく機能 remove()
しますが、イテレータを使用してエントリを削除すると、上記のオーバーライドされたメソッドの代わりに のremove()
メソッドが呼び出されます。HashMap
remove()
public boolean selectiveRemove(Object key) {
boolean result = false;
Iterator<Entry<K, E>> it = entrySet().iterator();
while( it.hasNext() ) {
Entry<K, E> entry = it.next();
K rowKey = entry.getKey();
if( Utils.equals(key, rowKey) ) {
it.remove(); // <<<<< this does not invoke the new `remove()`
result = true;
}
}
return result;
}
エントリ イテレータのソース コードを見ると、次のように表示されます。HashMap
private abstract class HashIterator {
. . .
public boolean hasNext() {
. . .
}
HashMapEntry<K, V> nextEntry() {
. . .
}
public void remove() {
if (lastEntryReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
HashMap.this.remove(lastEntryReturned.key); // <<< Hard coded call to HashMap's remove()
lastEntryReturned = null;
expectedModCount = modCount;
}
}
private final class EntryIterator extends HashIterator
implements Iterator<Entry<K, V>> {
public Entry<K, V> next() { return nextEntry(); }
}
拡張HashMap
クラスはすべてのプライベート フィールドにアクセスできるわけではないため、イテレータを変更するだけではいけません。独自のイテレータがそのイテレータをオーバーライドするようにするには、多くのコードを書き直す必要があります。
remove()
呼び出されたすべての状況で呼び出されるように完全にオーバーライドする方法はありますHashMap.remove()
か?