集合中直接remove对象和remove角标的区别

今天写了一下 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 的写法 在移除的同时 将集合和角标减一 这样还可以 避免在遍历中移除对象 有可能导致的空指针等问题

你可能感兴趣的:(集合中直接remove对象和remove角标的区别)