ArrayList的sublist方法
返回的是创建的List的内部类SubList的对象
public List<E> subList (int fromIndex, int toIndex) {
subListRangeCheck (fromIndex, toIndex, this .size);
return new ArrayList.SubList (this , fromIndex, toIndex);
}
SubList
本质时List对象的一个视图,没有生成新的List
创建一个内部类SubList,返回的是List类型的集合,而不是ArrayList
这个toIndex,决定的只是从起始index后所截取的长度
private static class SubList <E> extends AbstractList <E> implements RandomAccess {
}
public List<E> subList (int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList (this , 0 , fromIndex, toIndex);
}
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this .parent = parent;
this .parentOffset = fromIndex;
this .offset = offset + fromIndex;
this .size = toIndex - fromIndex;
this .modCount = ArrayList.this .modCount;
}
Iterator遍历元素
获取原List的内部数组Element
从Sublist创建时配置的偏移量offset开始遍历
遍历的长度是时计算的size
在iterator之前会进行modeCount的校验,这也就说明,在获取subList和操作subList之间不能对原有的ArrayList对象进行增删操作
public E next () {
checkForComodification();
int i = cursor;
if (i >= SubList.this .size)
throw new NoSuchElementException ();
Object[] elementData = ArrayList.this .elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException ();
cursor = i + 1 ;
return (E) elementData[offset + (lastRet = i)];
}
增删改查操作
增删改查操作的时候都会校验操作的modeCount
public void add (int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this .modCount = parent.modCount;
this .size++;
}
private void checkForComodification () {
if (this .root.modCount != this .modCount) {
throw new ConcurrentModificationException ();
}
}
public ListIterator<E> listIterator (final int index) {
checkForComodification ();
。。。。
}
private void checkForComodification () {
if (ArrayList.this .modCount != this .modCount)
throw new ConcurrentModificationException ();
}
subList的增删改查操作
public E remove(int index) {
Objects.checkIndex(index, this .size);
this .checkForComodification();
E result = this .root.remove(this .offset + index);
this .updateSizeAndModCount(-1 );
return result;
}
测试代码
ArrayList<String> list = new ArrayList<>();
list.add ("a0" );
list.add ("a1" );
list.add ("a2" );
list.add ("a3" );
list.add ("a4" );
List<String> temp = list.subList(2 , 5 );
list.add ("w1" );
temp.add ("a6" );
System.out .println(temp);
总结
Sublist是ArrayList原list的视图并不是生成新的ArrayList,而是SubList的List
原list进行增删操作,会让Sublist的操作报错ConcurrentModificationException
Sublist进行增删改查,直接对原list的数组进行操作
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示