首先用了函数式的接口,作为过滤器。
    remove 时需要考虑删除是 内存移位等问题

    removeif 是这样解决的

    1. 使用与list元素个数等长的 BitSet
    2. 使用过滤器,过滤出需要删除的元素,同时在 bitSet 相应的位打上1
    3. 此时知道没被删除的 元素个数 notDelNum
    4. 从0开始循环, 将list元素的基于位图为 0的元素位置 重新排列位置
    5. 将大于notDelNum的元素全部去掉

    ·

    1. public boolean removeIf(Predicate<? super E> filter) {
    2. Objects.requireNonNull(filter);
    3. // figure out which elements are to be removed
    4. // any exception thrown from the filter predicate at this stage
    5. // will leave the collection unmodified
    6. int removeCount = 0;
    7. final BitSet removeSet = new BitSet(size);
    8. final int expectedModCount = modCount;
    9. final int size = this.size;
    10. for (int i=0; modCount == expectedModCount && i < size; i++) {
    11. @SuppressWarnings("unchecked")
    12. final E element = (E) elementData[i];
    13. if (filter.test(element)) {
    14. removeSet.set(i);
    15. removeCount++;
    16. }
    17. }
    18. if (modCount != expectedModCount) {
    19. throw new ConcurrentModificationException();
    20. }
    21. // shift surviving elements left over the spaces left by removed elements
    22. final boolean anyToRemove = removeCount > 0;
    23. if (anyToRemove) {
    24. final int newSize = size - removeCount;
    25. for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
    26. i = removeSet.nextClearBit(i);
    27. elementData[j] = elementData[i];
    28. }
    29. for (int k=newSize; k < size; k++) {
    30. elementData[k] = null; // Let gc do its work
    31. }
    32. this.size = newSize;
    33. if (modCount != expectedModCount) {
    34. throw new ConcurrentModificationException();
    35. }
    36. modCount++;
    37. }
    38. return anyToRemove;
    39. }

    ArrayList 的 removeif - 图1