当前位置:   article > 正文

java array arraylist_说一说java.util.Arrays$ArrayList

java.util.arrays$arraylist

java.util.Arrays$ArrayList(下文:Arrays$ArrayList)是java.util.Arrays的私有静态内部类,他实现的接口,继承的父类几乎和java.util.ArrayList(下文:ArrayList)相同,既然是私有的,那么平常应该是我们少关注的地方。本文尝试对比一两个他们之间的不同点。

使用场景对比

构造拥有三个字符串的List,

ArrayList

List lb = new ArrayList<>(3);

lb.add("a");

lb.add("b");

lb.add("c");

Arrays$ArrayList

List la = Arrays.asList("a", "b", "c");

//源码

public static List asList(T... a) {

return new ArrayList<>(a);

}

两者都满足了需求,后者看起来比前者简洁,除此之外两者还有什么不同呢。

增加删除操作对比

支持的操作,

lb.add("d")

lb.remove("d")

不支持的操作,这将会抛出异常java.lang.UnsupportedOperationException

la.add("d")

la.remove("d")

可见Arrays$ArrayList不允许增加也不允许删除。

具体的add方法

在Arrays$ArrayList类,

首先并没有override父类的add方法,所以这个方法来自他的父类AbstractList;

看AbstractList中的add方法

public boolean add(E e) {

add(size(), e);

return true;

}

public void add(int index, E element) {

throw new UnsupportedOperationException();

}

最终调用的方法抛出了异常UnsupportedOperationException。

相比较ArrayList

public boolean add(E e) {

ensureCapacityInternal(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

public void add(int index, E element) {

rangeCheckForAdd(index);

ensureCapacityInternal(size + 1); // Increments modCount!!

System.arraycopy(elementData, index, elementData, index + 1,

size - index);

elementData[index] = element;

size++;

}

这两个方法都在ArrayList中实现了,或者扩容然后在尾部插入,或者扩容、移动数组元素,然后插入到指定的下标位置。

具体的remove方法

Arrays$ArrayList的remove(Object)方法继承自AbstractList的父类AbstractCollection,其中

public boolean remove(Object o) {

Iterator it = iterator();

if (o==null) {

while (it.hasNext()) {

if (it.next()==null) {

it.remove();

return true;

}

}

} else {

while (it.hasNext()) {

if (o.equals(it.next())) {

it.remove();

return true;

}

}

}

return false;

}

这里使用了迭代器的方式进行删除,看这个方法的注释

e31ac8a3b5bcefc2de97ba0ee167009e.png

如果这个迭代器没有实现remove方法的话,那么这整个方法也将要抛出UnsupportedOperationException异常的。

在AbstractCollection中iterator是一个抽象方法,之于Arrays$ArrayList,这个方法实现的位置还是在AbstractList,

public Iterator iterator() {

return new Itr();

}

private class Itr implements Iterator {

//...省略

public void remove() {

if (lastRet < 0)

throw new IllegalStateException();

checkForComodification();

try {

AbstractList.this.remove(lastRet);

if (lastRet < cursor)

cursor--;

lastRet = -1;

expectedModCount = modCount;

} catch (IndexOutOfBoundsException e) {

throw new ConcurrentModificationException();

}

}

}

到这里我们发现AbstractList实现了AbstractCollection的iterator方法,而且返回的迭代器也实现了remove方法,不是上文提到的注释那种情况。但是为什么删除动作还是不允许的呢?

具体这个迭代器的remove方法,

AbstractList.this.remove(lastRet);

可见迭代器最终也是调用容器类的remove方法的,那么Arrays$ArrayList没有实现remove方法,而AbstractList的remove方法,如下

public E remove(int index) {

throw new UnsupportedOperationException();

}

因此,即使在AbstractList中使用迭代器进行删除操作,但由于Arrays$ArrayList没有实现remove且继承的remove抛出UnsupportedOperationException异常,最终在Arrays$ArrayList是不允许删除操作的。

值得注意的是,AbstractList的迭代器是否要调用remove(int)方法是由要删除的目标是否数组的元素决定的,如果不存在这样的元素,则下面的代码并不会出现异常,

List la = Arrays.asList("a", "b", "c");

la.remove("e");

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/525128
推荐阅读
相关标签
  

闽ICP备14008679号