1

次のように、クラスを拡張し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()メソッドが呼び出されます。HashMapremove()

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()か?

4

0 に答える 0