List的removeAll方法异常

最近在公司写东西,发现List的removeAll方法报错 Demo代码如下:

List ids1 = Arrays.asList(1L, 3L, 2L);
List ids2 = Collections.singletonList(2L);
List ids3 = new ArrayList<>();
ids3.add(1L);
ids3.add(2L);
List 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}.
  • This method also provides a convenient way to create a fixed-size

  • list initialized to contain several elements:
  • List stooges = Arrays.asList(“Larry”, “Moe”, “Curly”);
  • @param 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 List asList(T… a) {
    return new ArrayList<>(a);
    }
    private static class ArrayList extends AbstractList
    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[] 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 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 List singletonList(T o) {
    return new SingletonList<>(o);
    }
    private static class SingletonList
    extends AbstractList
    implements RandomAccess, Serializable {

private static final long serialVersionUID = 3093736618740652951L;

private final E element;

SingletonList(E obj) {element = obj;}

public Iterator 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 operator) {
throw new UnsupportedOperationException();
}
@Override
public void sort(Comparator<? super E> c) {
}
@Override
public Spliterator spliterator() {
return singletonSpliterator(element);
}
}
// 可以看出 这个list是一个只读的list 并未对外提供编辑方法
同样会调用AbstractCollection的removeAll方法

003是我new的ArrayList对象,会调用自己内部重写的removeAll方法,针对数组重写了删除方法,不会出问题,解决001、002的问题 最简单的办法可以用new ArrayList()包一层就ok了!

转载自:https://www.cnblogs.com/csnjava/p/14177600.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值