当前位置: 首页 > 工具软件 > ASList > 使用案例 >

java lists.aslist_java Arrays.asList()

太叔烨霖
2023-12-01

在Java中比如想把一个数组转成集合,通常习惯使用Arrays.asList,但是要小心,数组通过Arrays.asList转成集合后,是不能调用集合的add,remove方法的.不然会抛异常UnsupportedOperationException,

Demo

Integer[] array = {1, 2};

List list = Arrays.asList(array);

list.remove(1);

控制台结果

Exception in thread "main" java.lang.UnsupportedOperationException

at java.util.AbstractList.remove(AbstractList.java:161)

at com.study.webfluxstudy.ArrayListTest.main(ArrayListTest.java:19)

如果新人第一次碰到这个问题可能会感觉很奇怪,add,remove方法不应该是集合的标配吗,怎么会不支持呢?分析下底层源码就知道了

/**

* Returns a fixed-size list backed by the specified array.

*/

@SafeVarargs

@SuppressWarnings("varargs")

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

return new ArrayList<>(a);

}

Returns a fixed-size list backed by the specified array.很关键的一句话,asList返回的list是固定大小的,那也就是说生成后的集合就不能再添加删除了,也就是不能add,remove了.注释虽然是这么说,但是如果看方法体中的代码,return new ArrayList<>(a),是不是更奇怪了.ArrayList大家在项目中常用的集合类,add,remove没问题啊.是什么原因呢?

阅读源码其实就能发现此ArrayList不是彼ArrayList.

asList静态方法中的ArrayList是Lists中的一个私有静态类,而不是java.util.ArrayList

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;

}

@Override

public boolean contains(Object o) {

return indexOf(o) != -1;

}

@Override

public Spliterator spliterator() {

return Spliterators.spliterator(a, Spliterator.ORDERED);

}

@Override

public void forEach(Consumer super E> action) {

Objects.requireNonNull(action);

for (E e : a) {

action.accept(e);

}

}

@Override

public void replaceAll(UnaryOperator operator) {

Objects.requireNonNull(operator);

E[] a = this.a;

for (int i = 0; i < a.length; i++) {

a[i] = operator.apply(a[i]);

}

}

@Override

public void sort(Comparator super E> c) {

Arrays.sort(a, c);

}

}

public static int hashCode(long a[]) {

if (a == null)

return 0;

int result = 1;

for (long element : a) {

int elementHash = (int)(element ^ (element >>> 32));

result = 31 * result + elementHash;

}

return result;

}

通过上面的源码可以看到起没有提供add,remove方法的实现,那调用add,remove其实是调用父类的方法

AbstractList

public void add(int index, E element) {

throw new UnsupportedOperationException();

}

public E remove(int index) {

throw new UnsupportedOperationException();

}

所以也就能解释为什么Demo演示代码调用add方法,在控制台会抛出UnsupportedOperationException异常了

如果让Arrays.asList()返回的集合支持add,remove方法

如果想实现这个目的需要借助java.util.ArrayList帮忙

public ArrayList(Collection extends E> c) {

elementData = c.toArray();

if ((size = elementData.length) != 0) {

// c.toArray might (incorrectly) not return Object[] (see 6260652)

if (elementData.getClass() != Object[].class)

elementData = Arrays.copyOf(elementData, size, Object[].class);

} else {

// replace with empty array.

this.elementData = EMPTY_ELEMENTDATA;

}

}

调整后的Demo

Integer[] array = {1, 2};

// 通过Arrays转换成的List,保留了原本的类型

List list = Arrays.asList(array);

System.out.println(list);

ArrayList objects = new ArrayList(list);

objects.add(3);

System.out.println(objects);

控制台输出

[1, 2]

[1, 2, 3]

 类似资料:

相关阅读

相关文章

相关问答