コレクション内の直接removeオブジェクトとremove角標の違い

1727 ワード

今日はActivityの管理クラスについて書きましたが、内部StackとActivityの関連付けを削除する際に本来書いてあるのは、入ってきたActivityを直接削除してEventBusのコードを見てみると、EventBusが登録をキャンセルした際に内部は次のようなコードで実現されていることがわかりました
/** Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber. */
private void unsubscribeByEventType(Object subscriber, Class> eventType) {
    List subscriptions = subscriptionsByEventType.get(eventType);
    if (subscriptions != null) {
        int size = subscriptions.size();
        for (int i = 0; i < size; i++) {
            Subscription subscription = subscriptions.get(i);
            if (subscription.subscriber == subscriber) {
                subscription.active = false;
                subscriptions.remove(i);
                i--;
                size--;
            }
        }
    }
}

次に、集合クラスの内部実装removeオブジェクトメソッドを見てみましょう.
public synchronized boolean removeElement(Object obj) {
    modCount++;
    int i = indexOf(obj);
    if (i >= 0) {
        removeElementAt(i);
        return true;
    }
    return false;
}

indexOfで入力オブジェクトのコーナーマークを取得する
    public synchronized int indexOf(Object o, int index) {
        if (o == null) {
            for (int i = index ; i < elementCount ; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = index ; i < elementCount ; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }


呼び出されても、最後に入力されたオブジェクトのコーナーマークを巡回して削除します.巡回する以上、外部を巡回して同様のEventBusの書き方で削除しながら集合とコーナーマークを減算すると、巡回中にオブジェクトを除去する可能性のある空のポインタなどの問題を回避できます.