Java踩坑之List的removeAll方法
最近在公司写东西,发现List的removeAll方法报错 Demo代码如下:
- List<Long> ids1 = Arrays.asList(1L, 3L, 2L);
- List<Long> ids2 = Collections.singletonList(2L);
- List<Long> ids3 = new ArrayList<>();
- ids3.add(1L);
- ids3.add(2L);
- List<Long> ids = new ArrayList<>();
- ids.add(2L);
- System.out.println("==== 001");
- ids1.removeAll(ids); // 这一步会报错
- System.out.println("==== 002");
- ids2.removeAll(ids); // 这一步也会报错
- System.out.println("==== 003");
- ids3.removeAll(ids);
001报错的原因是:Arrays.asList 返回的List是自己内部实现的ArrayList 而不是util下的ArrayList对象
- /**
- * Returns a fixed-size list backed by the specified array. (Changes to //明确指出 返回的是固定大小的list
- * the returned list "write through" to the array.) This method acts
- * as bridge between array-based and collection-based APIs, in
- * combination with {@link Collection#toArray}. The returned list is
- * serializable and implements {@link RandomAccess}.
- *
- * <p>This method also provides a convenient way to create a fixed-size
- * list initialized to contain several elements:
- * <pre>
- * List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
- * </pre>
- *
- * @param <T> the class of the objects in the array
- * @param a the array by which the list will be backed
- * @return a list view of the specified array
- */
- @SafeVarargs
- @SuppressWarnings("varargs")
- public static <T> List<T> asList(T... a) {
- return new ArrayList<>(a);
- }
- private static class ArrayList<E> extends AbstractList<E>
- implements RandomAccess, java.io.Serializable
- {
- private static final long serialVersionUID = -2764017481108945198L;
- private final E[] a;
- ArrayList(E[] array) {
- a = Objects.requireNonNull(array);
- }
- @Override
- public int size() {
- return a.length;
- }
- @Override
- public Object[] toArray() {
- return a.clone();
- }
- @Override
- @SuppressWarnings("unchecked")
- public <T> T[] toArray(T[] a) {
- int size = size();
- if (a.length < size)
- return Arrays.copyOf(this.a, size,
- (Class<? extends T[]>) a.getClass());
- System.arraycopy(this.a, 0, a, 0, size);
- if (a.length > size)
- a[size] = null;
- return a;
- }
- @Override
- public E get(int index) {
- return a[index];
- }
- @Override
- public E set(int index, E element) {
- E oldValue = a[index];
- a[index] = element;
- return oldValue;
- }
- @Override
- public int indexOf(Object o) {
- E[] a = this.a;
- if (o == null) {
- for (int i = 0; i < a.length; i++)
- if (a[i] == null)
- return i;
- } else {
- for (int i = 0; i < a.length; i++)
- if (o.equals(a[i]))
- return i;
- }
- return -1;
- }
- ...... //看的出来,这个list是可以修改的 但是要通过set方法
- }
所以调用removeAll方法的时候 会调用AbstractList的父类AbstractCollection的removeAll方法:
- public boolean removeAll(Collection<?> c) {
- Objects.requireNonNull(c);
- boolean modified = false;
- Iterator<?> it = iterator();
- while (it.hasNext()) {
- if (c.contains(it.next())) {
- it.remove();
- modified = true;
- }
- }
- return modified;
- }
ArrayList是数组 在循环的时候删除元素 一定会出现问题
002报错的原因是与001类似:Collections.singletonList的返回值SingletonSet也是自己的内部类
- /**
- * Returns an immutable list containing only the specified object. // 返回不可变的list
- * The returned list is serializable.
- *
- * @param <T> the class of the objects in the list
- * @param o the sole object to be stored in the returned list.
- * @return an immutable list containing only the specified object.
- * @since 1.3
- */
- public static <T> List<T> singletonList(T o) {
- return new SingletonList<>(o);
- }
- private static class SingletonList<E>
- extends AbstractList<E>
- implements RandomAccess, Serializable {
- private static final long serialVersionUID = 3093736618740652951L;
- private final E element;
- SingletonList(E obj) {element = obj;}
- public Iterator<E> iterator() {
- return singletonIterator(element);
- }
- public int size() {return 1;}
- public boolean contains(Object obj) {return eq(obj, element);}
- public E get(int index) {
- if (index != 0)
- throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
- return element;
- }
- // Override default methods for Collection
- @Override
- public void forEach(Consumer<? super E> action) {
- action.accept(element);
- }
- @Override
- public boolean removeIf(Predicate<? super E> filter) {
- throw new UnsupportedOperationException();
- }
- @Override
- public void replaceAll(UnaryOperator<E> operator) {
- throw new UnsupportedOperationException();
- }
- @Override
- public void sort(Comparator<? super E> c) {
- }
- @Override
- public Spliterator<E> spliterator() {
- return singletonSpliterator(element);
- }
- }
- // 可以看出 这个list是一个只读的list 并未对外提供编辑方法
同样会调用AbstractCollection的removeAll方法
003是我new的ArrayList对象,会调用自己内部重写的removeAll方法,针对数组重写了删除方法,不会出问题,解决001、002的问题 最简单的办法可以用new ArrayList()包一层就ok了!
究其原因还是自己对源码的研究不足!
更多技术资源请访问:https://www.zhaochao.top/articles
Java踩坑之List的removeAll方法的更多相关文章
- java踩坑记
1.String 相等 稍微有点经验的程序员都会用equals比较而不是用 ==,但用equals就真的安全了吗,看下面的代码 user.getName().equals("xiaoming ...
- 『OGG 02』Win7 配置 Oracle GoldenGate Adapter Java 踩坑指南
上一文章 <__Win7 配置OGG(Oracle GoldenGate).docx>定下了 两个目标: 目标1: 给安装的Oracle_11g 创建 两个用户 admin 和 root ...
- Java踩坑之路
陆陆续续学Java也快一年多了,从开始的一窍不通到现在的初窥门径,我努力过,迷茫过,痛过,乐过,反思过,沉淀过.趁着新年,我希望能把这些东西记下来,就当是我一路走来的脚印. 一.初识网站应用 记得第一 ...
- JAVA踩坑录
以前踩了很多坑,大多忘了.现在踩了坑,想起了一定记下来. 1. 字符串分割,这种工具类,首次使用一定要先看一眼,不然跳坑 commons-lang StringUtils.split分割时会去掉空串: ...
- java踩坑
1. java判断两个字符串是否相等用equals 2. java只传递指针遇到的坑: 1 import java.util.*; 2 3 public class mapTest { 4 publi ...
- Java踩坑记系列之Arrays.AsList
java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意: 一. ...
- mongo java 踩坑记
为什么会有这么多坑 1. Java会把 id:String = "合法ObjectId" 好心好意的 转为 _id:ObjectId 类型. 2. 为了避免第1点, 我定义了 ...
- Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)
在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_date等 UDAF( ...
- Android踩坑随笔Fragment中onActivityResult方法不被调用
最近项目里要做头像功能,参考了这篇博客(GitHub - zhudfly/SelectAvatarApplication: 一个选择并显示头像圆形控件,可以通过拍照或者选择相册中的图片来设置图片),但 ...
随机推荐
- BATJ经典软件测试面试题我连答案都告诉你了,如果你不想月薪上万,那你别看!
单项选择题:共20小题,每小题1 分,满分20分:请将答案填入题后括号中. 1. 在软件生命周期的哪一个阶段,软件缺陷修复费用最低(A) A.需求分析(编制产品说明书) B.设计 C.编码 ...
- shiro的使用与JWT整合
一.shiro入门 两大框架对比:安全框架Shiro和SpringSecurity的比较 了解shiro 什么是Shiro Apache Shiro是一个Java的安全(权限)框架.| Shiro可以 ...
- Linux环境yum,安装MySQL
Linux 使用yum命令安装mysql [安装步骤] 1.先检查系统是否安装有mysql [root@localhost ~]#yum list installed mysql* [root@loc ...
- Skywalking-13:Skywalking模块加载机制
模块加载机制 基本概述 Module 是 Skywalking 在 OAP 提供的一种管理功能特性的机制.通过 Module 机制,可以方便的定义模块,并且可以提供多种实现,在配置文件中任意选择实现. ...
- Three 之 Animation 初印象
Animation 初印象 动画效果 播放动画需要基本元素 AnimationMixer 一个对象所有动作的管理者 用于场景中特定对象的动画的播放器.一个对象可能有多个动作,Mixer 是用来管理所有 ...
- SAE助力南瓜电影7天内全面Severless
作者:李刚(寻如),阿里云解决方案架构师 南瓜电影APP是国内领先的专注于影视精品化运营的垂直类视频产品,在移动互联网.IPTV.OTT等客户端,面向广大中产阶级精英群体,提供有异于院线及其他视频平台 ...
- bzoj2038 小z的袜子 (莫队)
题目大意 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编 ...
- C#与java TCP通道加密通信
背景说明 公司收费系统需要与银行做实时代收对接,业务协议使用我们收费系统的标准.但是银行要求在业务协议的基础上,使用银行的加密规则. 采用MD5计算报文摘要,保证数据的完整性 采用RSA256对摘要进 ...
- Stream中的Pipeline理解
使用Stream已经快3年了,但是从未真正深入研究过Stream的底层实现. 今天开始把最近学到的Stream原理记录一下. 本篇文章简单描述一下自己对pipeline的理解. 基于下面一段代码: p ...
- Jmeter之BeanShell 断言
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15436864.html 博客主页:https://www.cnblogs.com/testero ...