首页 > 编程知识 正文

java arraylist remove方法,java list remove

时间:2023-05-05 05:08:43 阅读:184357 作者:2206

摘自:https://www.zhaochao.top/article/182

最近在公司写东西,发现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("刻苦的网络", "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

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。