No es una cosa profunda, las trampas a las que Arrays.asList y ArrayList.subList deben prestar atención

prefacio

Las colecciones son cosas que se usan casi todos los días en el trabajo diario, y también son cosas que se han volcado en ensayos estereotipados, como Lista y Mapa.Sin duda son muy importantes y prácticos, pero es más fácil pisar el pozo. si no prestas atención a los detalles. Los más comunes son Arrays.asList y ArrayList.subList que se organizarán hoy. No es algo profundo, solo resuélvelo todos los días.

La forma de escritura más utilizada.

 List<Integer> list = new ArrayList<>();
 list.add(10);
 list.add(20);

Notas sobre el uso de Arrays.asList

La mayoría de las razones para pisar el foso

La imagen es conveniente, a veces para una pequeña cantidad de elementos, me pregunto si hay un método listo para usar, está bien, Stud

List<Integer> statusList = Arrays.asList(1, 2);

Lo siento, no hay nada de malo en esto. Después de un período de tiempo después de conectarse, debe agregar n elementos, ver que haya un conjunto, fácil, está bien, continúe con la base original, el código se vuelve así

List<Integer> statusList = Arrays.asList(1, 2);
statusList.add(3);

Después de conectarse, ¡boom! Verifique el problema, pero sigue siendo un pato muerto. El código es tan simple, no debe ser un error en este lugar, eche un vistazo al informe de error:

alt

Análisis de causa

Haga clic y eche un vistazo al código fuente del método estático asList proporcionado por la clase Arrays:

altSi observa más de cerca, encontrará que este ArrayList no es el ArrayList que usamos a menudo, porque el ArrayList que usamos generalmente se encuentra en el paquete java.util:

altPero el ArrayList aquí es una clase interna de la clase Arrays, continúe observando sus clases heredadas,

altTambién hereda la clase AbstractList y reescribe muchos métodos, como el método contains que usamos anteriormente, pero no reescribe el método add, por lo que lanzaremos java.lang.UnsupportedOperationException cuando llamemos al método add.

En el "Manual de desarrollo Java de Alibaba" Taishan Edition, se explica este punto de atención:

Al usar la clase de herramienta Arrays.asList() para convertir una matriz en una colección, no puede usar sus métodos relacionados con la modificación de la colección, y sus métodos agregar/eliminar/borrar arrojarán una excepción UnsupportedOperationException.

alt

resumen

Puede usar Arrays.asList en ocasiones simples, como declarar rápidamente una colección para determinar si un cierto valor está dentro del rango permitido, pero no llame a su método de modificación. Si realmente desea usarlo, primero verifique si hay un método de re-correspondencia.

使用ArrayList的subList的注意事项

先看个Demo

List<String> bookList = new ArrayList<>();
bookList.add("天道");
bookList.add("倚天屠龙记");
bookList.add("阿甘正传");
bookList.add("你好,明天");
bookList.add("我是谁");

List<String> subBookList = bookList.subList(3, 5);
System.out.println(bookList);
System.out.println(subBookList);

执行结果如下:

alt

从运行结果可以看出,subList返回的是bookList中索引从fromIndex(包含)到toIndex(不包含)的元素集合。

使用起来很简单,主要有以下几点要注意,否则会造成程序错误或者异常:

  • 修改原集合元素的值,会影响子集合
  • 修改原集合的结构,会引起ConcurrentModificationException异常
  • 修改子集合元素的值,会影响原集合
  • 修改子集合的结构,会影响原集合 以上几点在《阿里巴巴Java开发手册》泰山版中是这样描述的:
alt

修改原集合的值,会影响子集合

如下验证:

alt

可以看出,虽然我们只是修改了原集合bookList的值,但是影响到了子集合subBookList

修改原集合的结构,会引起ConcurrentModificationException异常

alt 温馨提醒:其实装好相关的插件,会自然提示可能出现的异常,可以整一下

修改子集合的值,会影响原集合

alt

修改子集合的结构,会影响原集合

alt

原因分析

看下subList方法的注释,了解下它的用途:

alt
  • 简单理解:返回指定的{@code fromIndex}(包含)和{@code toIndex}(排除)之间的列表部分的视图。 看下它的源码:
public List<E> subList(int fromIndex, int toIndex) {
    
    
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}

它调用了SubList类的构造函数,该构造函数的源码如下图所示:

alt

可以看出,SubList类是ArrayList的内部类,该构造函数中也并没有重新创建一个新的ArrayList,所以修改原集合或者子集合的元素的值,是会相互影响的。

写在最后

好了,明白了是什么原因了吧。不要图方便,不看清他的原理。这里是"安前码后",一个分享实用内容的号,觉得用心整理的,帮忙给个三连。更多内容持续输出中。

本文由 mdnice 多平台发布

Supongo que te gusta

Origin blog.csdn.net/weixin_42329623/article/details/130396223
Recomendado
Clasificación