温馨提示:阅读本文需要3-4分钟(少量代码)
今天,我们来解决一个问题:
通过Arrays.asList方法将数组转成集合后,能否修改集合个数?
人生一切难题,知识给你答案。
数组与集合都是用来存储对象的容器,两者之间可以进行相互转换,数组转集合可以通过Arrays.asList方法。
==Arrays.asList==
通过Arrays.asList方法将数组转成集合后,能否修改集合个数?针对这个问题,我们直接给出例子:
public class Demo {
public static void main(String[] args){
String[] strings={"A","B","C"};
List<String> stringList=Arrays.asList(strings);
stringList.set(0,"G");
System.out.println(strings[0]);
stringList.add("M");
}
}
运行结果:
G
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
...
通过上面的例子可以发现通过set()方法修改元素的值,原有数组相应位置的值也被修改了,说明修改值没有问题,接着通过调用add()方法直接抛出UnsupportedOperationException异常,说明不能进行修改元素个数的任何操作。
那为什么不能修改元素个数呢?进入Arrays.asList源码中查看:
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
发现直接创建了一个ArrayList对象,按照我们平时对ArrayList的理解,应该可以修改元素个数啊?原来这个ArrayList不是我们平时使用的那个ArrayList,它是Arrays的静态内部类ArrayList。
public class Arrays {
...
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) {
...
}
@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) {
...
}
@Override
public boolean contains(Object o) {
...
}
@Override
public Spliterator<E> spliterator() {
...
}
@Override
public void forEach(Consumer<? super E> action) {
...
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
...
}
@Override
public void sort(Comparator<? super E> c) {
...
}
}
...
}
Arrays的静态内部类ArrayList中,set方法本质还是对数组进行值的修改操作,并且静态内部类ArrayList内部没有实现类似add、remove、clear相关方法,所以调用修改元素个数的相关方法时会抛出UnsupportedOperationException异常。
还有一个问题,我们在上面案例中通过set方法修改了ArrayList集合的第一个元素的值,在我们访问原有数组的第一个位置时,值也被改变了,这是为什么呢?
public class Arrays {
...
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);
}
...
}
...
}
静态内部类ArrayList的成员变量a使用了final,用于存储集合的数组引用始终被强制指向原有数组。
因此,通过Arrays.asList方法将数组转换成集合后,避免修改元素的个数,否则会引发异常。
838794-506ddad529df4cd4.webp.jpg
网友评论