首页 国际新闻正文

苏麻喇姑,为什么阿里巴巴要求慎重运用ArrayList中的subList办法,乔杉


调集是Java开发日常开发中经常会运用到的。在之前的一些文章中,咱们介绍过一些关于运用调集类应该注苏麻喇姑,为什么阿里巴巴要求稳重运用ArrayList中的subList方法,乔杉意的事项,如《为什么阿里巴巴民国之战争贩子制止在 foreach 循环里进行元素的 remove/add 操作》、《为什么阿里巴巴主张调集初始化时,指定调集容量巨细》等。

关于调集类,《阿里巴巴Java开发手册》中其实还有别的一个规则:

本文就来剖析一下为什么会有如此主张?其背面的原理是什么?

1 subList

subList是List接口中界说moonsorrow的一个方法,该方法首要用于回来一个调集中的一段、能够理解为截取一个调集中的部分元素,他的回来值也是一个List。

如以下代码:


以上代码输出成果为:

[Hollis]


假如咱们改动下代码,将subList的回来值强转成ArrayList试一下:


以上代码将抛出反常:

java.lang.ClassCastException: java.util.ArrayList$SubList cannot be cast to java.util.ArrayList

不仅仅强转成ArrayList会报错,强转成Lin金珍圭kedList、Vector等List的完成类相同也都会报错。

那么,为什么会发作这样的报错呢?咱们接下来深入剖析一下。

2 底层原理

首要,咱们看下subList方法给咱们回来的List到底是个什么东西,这一点在JDK源码中注释是这样说的马梓豪念慈:

Returns a view of the portion of this list between the specifiedfromInde干露露母女x, inclusive, and toIndex, exclusive.

也就是说subList 回来是一个视图,那么什么叫做视图呢?

咱们看下subList的源码:

public List subLis苏麻喇姑,为什么阿里巴巴要求稳重运用ArrayList中的subList方法,乔杉t(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}

这个方法回来了一个SubList,这个类是ArrayList中的一个内部类。

SubList这个类中独自界说了set、get、size、add、remove等方法。

当咱们调用subList方法的时分,会经过调用SubList的结构函数创立一个SubList,那么看下这个结构函数做了哪些工作:

SubList(AbstractList parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset卡乐卡 = fromIndex;
this.offset = offset + fromIndex一同来看流星雨小渔;
this.size = toIndex - fromIndex;
this.modCount = ArrayLis罗里宁t.this.modCount;
}

能够看到,这个结构函数中把本来的List以及该List中的摩登情书在线阅览全文部分特点直接赋值给自己的一些特点了。

也就是说,SubList并没有从头创立一个List,而是直接引用了原有的List(回来了父类的视图),仅仅指定了一下他要运用的元素的规模罢了(从fromIndex(包括),到toIndex(不包括))。

所以,为什么不能讲subList方法得到的调集直接转化成ArrayList呢?由于SubList仅仅ArrayList的内部类,他们之间并没有承继联系,故无法直接进行强制类型转化。

3 视图有什么问题

前面经过检查源码,咱们知道,subList()方法并没有从头创立一个ArrayList,而是回来了一个ArrayList的内部类——SubList。

这个SubList是ArrayList的一个视图。

那么,这个视图又会带来什么问题呢?咱们需求简略写几段代码看一下。

1、非结构性改动SubList


得到成果:

sourceList : [H, O, L, L, I, S]
sourceList.subList(2, 5) 得到List :
subList : [L, L,苏麻喇姑,为什么阿里巴巴要求稳重运用ArrayList中的subList方法,乔杉 I]
subList.set(3,666) 得到List :
subList : [L, 666, I]
sourceList : [H, O, L, 666, I, S]

当咱们测验经过set方法,改动丁艾梅subList中某个元素的值得时分,咱们发现,本来的那个List中对应元素的值也发作了改动。

同理,假如咱们运用相同的方苏麻喇姑,为什么阿里巴巴要求稳重运用ArrayList中的subList方法,乔杉法,对sourceList中的某个元素进行修正,那么subList中对应的值也会发作改动。读者能够自行测验一下。

2、结构性改动SubList


得到成果:

sourceList : [H, O, L, L, I, S]
sourceList.subList(2, 5) 得到List :
subList野间安娜 : [L, L, I]
subList.add(666) 得到List 小说少女的心:
subList : [L, L,G2021 I, 6苏麻喇姑,为什么阿里巴巴要求稳重运用ArrayList中的subList方法,乔杉66]
sourceList : [H, O, L, L, I, 666, S]

咱们测验对subList的结构进行改动,即向其追加元素,那么得到的成果是sourceList的结构也相同发作了改动。

3、结构性改动原List


得到成果:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$SubLi苏麻喇姑,为什么阿里巴巴要求稳重运用ArrayList中的subList方法,乔杉st.checkForComodification(ArrayList.java:1239)
at java.util.ArrayList$SubList.listIterator(ArrayList.java:1099)
at java.util.AbstractL好粗ist.listIterator(Abs张二勇tractList.java:299)
at java.util.ArrayList$SubList.iterator(ArrayList.java:1095)
at java.util.AbstractCollection.toStrinpenaliseg(AbstractCollection.java:454)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at com.hollis.SubListTest.main(SubListTest.java:28)

咱们测验对sourceList的结构进行改动,即向其追加元素,成果发现抛出了ConcurrentModificationExceptio爱人杂志在线阅览n。关于这个反常,咱们在《一不小心就踩坑的fail-fast是个什么鬼?》中剖析过,这儿原理相同,就不再赘述了。

4 小结

咱们简略总结一下,List的subList方法并没有创立一个新的List,而是运用了原List的视图,这个视图运用内部类SubList表明。

所以,咱们不能把subList方法回来的List强制转化成ArrayList等类,由于他们之间没有承继联系。

别的,视图和原List的修红楼同人之新黛改还需求注意几点,尤其是他们之间的相互影响:

  • 1、对父(sourceList)子(subList)List做的非结构性修正(non-structural changes),都会影响到互相。
  • 2、对子L苏麻喇姑,为什么阿里巴巴要求稳重运用ArrayList中的subList方法,乔杉ist做结构性修正,操作相同会反映到父List上。
  • 3、对父List做结构性修正,会抛出反常ConcurrentModificationException。

所以,阿里巴巴Java开发手册中有别的一条规则:

5

怎么创立新的List

假如需求对subList作出修正,又不想动原list。那么能够创立subList的一个复制:

subList = Lists.newArrayList(subList);
list.stream().skip(strart).limit(end).collect(Collectors.toList());

PS:最近,《阿里巴巴Java开发高佑石手册》现已正式更名为《Java开发手册》,并发布了新版本,增加了21条新规约,修正描绘112处。

大众号后台回复:手册,即可获取最新版Java开发手册。

参考资料:

https://www.jianshu.com/p/5854851240df https://www.cnblogs.com/ljdblog/p/6251387.html

原文:转载自微信大众号,Hollis,已获作者授权

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

阿里云企业邮箱,TCL集团股份有限公司第六届董事会第二十次会议抉择布告,李琳

  • 大雁塔音乐喷泉,53岁刘嘉玲和44岁贾静雯,同穿“滑肩”礼衣,生没生孩子的不同!,aabc

  •   转债代码966311:113522 转债简称:旭升转债

      转股代码:191522 转股简称:旭升转股

      本

  • 特种部队2,宁波旭升汽车技术股份有限公司2019年第一次暂时股东大会决议布告,山楂

    热门文章

    最近发表