JAVA 集合取交集 retainAll 删除元素 removeIf

集合取交集 Collection.retainAll()

两个集合取交集的操作,详见代码:

// 两个集合取交集
	public static void main(String[] args) {
		List<String> listA = new ArrayList<>();
		listA.add("A");
		listA.add("B");
		listA.add("C");
		List<String> listB = new ArrayList<>();
		listB.add("C");
		listB.add("B");
		listB.add("E");
		listA.retainAll(listB);
		listA.forEach(System.out::println);
	}

输出结果:
在这里插入图片描述

按条件删除集合中的某些元素 Collection.retainAll()

错误示范:

// 错误示范
	public static void main(String[] args) {
		List<String> listA = new ArrayList<>();
		listA.add("A");
		listA.add("B");
		listA.add("C");
		List<String> listB = new ArrayList<>();
		listB.add("C");
		listB.add("B");
		listB.add("E");
		listA.forEach(a -> {
			listB.forEach(b -> {
				if (a.equals(b)) {
					listA.remove(a);
				}
			});
		});
		listA.remove("b");
		listA.forEach(System.out::println);
	}

遍历过程中执行remove方法
在这里插入图片描述
定位到ArrayList里面
在这里插入图片描述
报错原因:remove方法里面执行了fastRemove,而fastRemove里面执行了modCount++,导致modCount变了

//remove方法里面执行了fastRemove
public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
//fastRemove里面执行了modCount++,导致modCount变了
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }
    

解决方案一:迭代器遍历

//迭代器遍历
 	public static void main(String[] args) {
		List<String> listA = new ArrayList<>();
		listA.add("A");
		listA.add("B");
		listA.add("C");
		List<String> listB = new ArrayList<>();
		listB.add("C");
		listB.add("B");
		listB.add("E");
		for (Iterator<String> it = listA.iterator(); it.hasNext();) {
			String o = it.next();
			listB.forEach(b -> {
				if (o.equals(b)) {
					it.remove();
				}
			});
		}
		listA.forEach(System.out::println);
	}
    

输出结果:
在这里插入图片描述

解决方案二:使用Collection的removeIf方法

removeIf方法源码如下,其实也是用了迭代器
tip:jdk1.8及以后可用,之前的版本没有滴

    /**
     * Removes all of the elements of this collection that satisfy the given
     * predicate.  Errors or runtime exceptions thrown during iteration or by
     * the predicate are relayed to the caller.
     *
     * @implSpec
     * The default implementation traverses all elements of the collection using
     * its {@link #iterator}.  Each matching element is removed using
     * {@link Iterator#remove()}.  If the collection's iterator does not
     * support removal then an {@code UnsupportedOperationException} will be
     * thrown on the first matching element.
     *
     * @param filter a predicate which returns {@code true} for elements to be
     *        removed
     * @return {@code true} if any elements were removed
     * @throws NullPointerException if the specified filter is null
     * @throws UnsupportedOperationException if elements cannot be removed
     *         from this collection.  Implementations may throw this exception if a
     *         matching element cannot be removed or if, in general, removal is not
     *         supported.
     * @since 1.8
     */
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

具体使用示例:

	public static void main(String[] args) {
		List<String> listA = new ArrayList<>();
		listA.add("A");
		listA.add("B");
		listA.add("C");
		List<String> listB = new ArrayList<>();
		listB.add("C");
		listB.add("B");
		listB.add("E");
		listA.removeIf(listB::contains);
		listA.forEach(System.out::println);
	}

输出结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值