你真的会用ArrayList的subList方法吗?

article/2025/10/21 20:19:24

导语

在日常的开发中通常会遇到截取List的情况,而大多数会选择使用subList方法进行截取,但是好多人对这个方法的理解都只是停留在使用层面上?这篇文章会非常详细达到源码级别的讲解sublList方法,需要的朋友赶紧收藏起来吧。

关于SubList

先通过下面这个例子,看看具体的返回类型:

public class TestSubList {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();for (int i = 0; i < 10; i++) {list.add(""+i);}List<String> subList = list.subList(3, 6);System.out.println(subList.getClass()+"  "+subList);System.out.println(list.getClass()+"  "+list);}
}

输出结果:

class java.util.ArrayList$SubList  [3, 4, 5]
class java.util.ArrayList  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

通过例子可以看出,当对list进行subList之后返回的subList对象,其实是一个内部类SubList,严格意思上来说,subList是ArrayList对象的一个视图,对于subList对象的操作都会映射到原来的ArrayList集合中。再通过下面这个例子看下具体的操作影响。

public class TestSubList {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();for (int i = 0; i < 10; i++) {list.add(""+i);}List<String> subList = list.subList(3, 6);System.out.println(subList.getClass()+"  "+subList);System.out.println(list.getClass()+"  "+list);System.out.println("----------------");subList.add("subList添加");System.out.println(subList.getClass()+"  "+subList);System.out.println(list.getClass()+"  "+list);}
}

输出结果:

class java.util.ArrayList$SubList  [3, 4, 5]
class java.util.ArrayList  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
----------------
class java.util.ArrayList$SubList  [3, 4, 5, subList添加]
class java.util.ArrayList  [0, 1, 2, 3, 4, 5, subList添加, 6, 7, 8, 9]

从上面可以看出,对subList的操作已经影响到ArrayList了,下面咱根据源码进行详细的分析一下原因。

关于集合类,《阿里巴巴Java开发手册》中其实还有另外一个规定:

在这里插入图片描述

源码概览

// subList方法
public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);
}

从源码中可以看出,其实subList方法返回的是ArrayList的内部类SubList,并不是ArrayList,所以,在使用的时候会有许多的注意细节。

 private class SubList extends AbstractList<E> implements RandomAccess {private final AbstractList<E> parent;private final int parentOffset;private final int offset;int size;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;}public E set(int index, E e) {rangeCheck(index);checkForComodification();E oldValue = ArrayList.this.elementData(offset + index);ArrayList.this.elementData[offset + index] = e;return oldValue;}public E get(int index) {rangeCheck(index);checkForComodification();return ArrayList.this.elementData(offset + index);}public int size() {checkForComodification();return this.size;}public void add(int index, E e) {rangeCheckForAdd(index);checkForComodification();parent.add(parentOffset + index, e);this.modCount = parent.modCount;this.size++;}public E remove(int index) {rangeCheck(index);checkForComodification();E result = parent.remove(parentOffset + index);this.modCount = parent.modCount;this.size--;return result;}protected void removeRange(int fromIndex, int toIndex) {checkForComodification();parent.removeRange(parentOffset + fromIndex,parentOffset + toIndex);this.modCount = parent.modCount;this.size -= toIndex - fromIndex;}public boolean addAll(Collection<? extends E> c) {return addAll(this.size, c);}public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);int cSize = c.size();if (cSize==0)return false;checkForComodification();parent.addAll(parentOffset + index, c);this.modCount = parent.modCount;this.size += cSize;return true;}}

其实从SubList类的源码中可以看出,SubList类中也实现了和ArrayList中的一样的方法,所以在调用subList的一些方法时,运行的是SubList中的实现,而且从上面可以看出,真正操作的还是原ArrayList对象。

源码详解

先看subList方法以及SubList的构造方法:

// subList方法
public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);
}// SubList构造方法
SubList(AbstractList<E> parent,int offset, int fromIndex, int toIndex) {this.parent = parent;this.parentOffset = fromIndex;this.offset = offset + fromIndex;// 将截取长度作为SubList的长度this.size = toIndex - fromIndex;// 将ArrayList对象的modCount赋值给SubList对象this.modCount = ArrayList.this.modCount;
}

从上面可以看出,当构造SubList对象的时候,会存储原集合在parent变量中,并且把截取的开始下标存为parentOffset。

下面详细看一个SubList的add方法,对上面的现象进行一个详细的分析。

// SubList对象的add方法
public void add(int index, E e) {// 检查下标是否合规rangeCheckForAdd(index);// 检查modCount是否和ArrayList的modCount一致(注:modCount表示的是集合的结构变化次数)checkForComodification();// 在原ArrayList指定位置添加元素parent.add(parentOffset + index, e);// 将ArrayList对象的modCount赋值给SubList对象this.modCount = parent.modCount;// 使SubList对象的长度加一this.size++;
}

通过上面的方法讲解,可以看出,对SubList对象的操作,其实就是对ArrayList对象的操作,其他的方法也都是同理。

总结

本篇文章详细介绍了ArrayList的subLIst方法以及SubList类的用法,由于纯手打,难免会有纰漏,如果发现错误的地方,请第一时间告诉我,这将是我进步的一个很重要的环节。


http://chatgpt.dhexx.cn/article/O4ZwY1oX.shtml

相关文章

Java SubList 类 Java subList方法 Java ArrayList$SubList 方法特点 SubList 用法

Java SubList 类 Java subList方法 Java ArrayList$SubList 方法特点 SubList 用法 一、概述 在java集合中&#xff0c;常用ArrayList类中&#xff0c;若需要对 list进行截取&#xff0c;可以使用subList方法&#xff0c;进行生成 SubList的内部类&#xff0c;那么 ArrayList 和…

使用ArrayList中的subList方法

集合是Java开发日常开发中经常会使用到的。在之前的一些文章中&#xff0c;我们介绍过一些关于使用集合类应该注意的事项&#xff0c;如《为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作》、《为什么阿里巴巴建议集合初始化时&#xff0c;指定集合容量大小》等…

sublist详解

接口中定义 List<E> subList(int fromIndex, int toIndex);1&#xff0c;该方法返回的是父list的一个视图&#xff0c;从fromIndex&#xff08;包含&#xff09;&#xff0c;到toIndex&#xff08;不包含&#xff09;。fromIndextoIndex 表示子list为空 2&#xff0c;父…

数据建模应用

数据建模应用 一、为什么要数据建模二、数据建模种类1、关系建模&#xff08;3NF&#xff09;2、维度建模 三、3NF数据建模1、范式介绍2、3NF建模实战 四、维度建模1、维度和指标的概念2、星型模型3、雪花模型4、星型与雪花模型对比5、维度建模测试案例 五、3NF建模与维度建模的…

分享大数据建模工具-大数据挖掘建模平台

大数据挖掘建模平台 是面向企业级用户的大数据挖掘建模平台。平台采用可视化操作方式&#xff0c;通过丰富内置算法&#xff0c;帮助用户快速、一站式地进行数据分析及挖掘建模&#xff0c;可应用于处理海量数据、高复杂性的数据挖掘任务&#xff0c;为其提供准确、高精度的计算…

大数据之数据模型

一、星型摸型 事实表是记录一个事实的&#xff0c;可以理解为订单表&#xff0c; 纬度表是提供更丰富信息的表&#xff0c;可以理解为商品明细表、订单明细表&#xff1b; 它是由一个事实表和一组维表组成&#xff0c;每个维表都有一个维作为主键&#xff0c;所有这些维的主键…

数据建模概述

数据建模&#xff08;data modeling&#xff0c;其实应该就是创建一个函数&#xff09;指的是对现实世界各类数据的抽象组织&#xff0c;确定数据库需管辖的范围、数据的组织形式等直至转化成现实的数据库。 将经过系统分析后抽象出来的概念模型转化为物理模型后&#xff0c;在…

大数据时代建模——图数据库建模

导读&#xff1a;云计算环境下&#xff0c;传统关系型数据库在海量数据存储方面存在瓶颈&#xff0c;对树形结构与半结构化数据的建模比较困难。本文介绍一种全新的建模方式——图数据库建模。应用图数据库模型更具扩展性、灵活性、高可靠性和高性能&#xff0c;能建立高细粒度…

大数据挖掘建模平台是怎样的?

大数据挖掘建模平台是可视化、一站式、高性能的数据挖掘与人工智能建模服务平台。面向企业级用户的大数据挖掘建模平台。平台采用可视化操作方式&#xff0c;通过丰富内置算法&#xff0c;帮助用户快速、一站式地进行数据分析及挖掘建模&#xff0c;可应用于处理海量数据、高复…

数据建模.

数据建模 什么是数据建模为什么要进行数据建模怎么进行数据建模 1. 为什么要进行数据建模&#xff1f; 提高 效率/性能&#xff1a; 计算机的的吞吐率&#xff0c;减少I/O的时间&#xff0c;提高用户使用数据的效率。开销&#xff1a;减少数据的冗余&#xff0c;从而节省存…

大数据数据建模

今天给大家分享一下 数据开发工作中数据建模的步骤&#xff0c; 第一步&#xff1a;选择模型或者自定义模型 这第一步需要我们基于业务问题&#xff0c;来决定我们需要选择哪种模型&#xff0c;目前市场中有很多模型可以供我们选择&#xff0c; 比如&#xff0c;如果要预测产…

数据建模

周三保(zhousbcn.ibm.com) IBM 软件部信息技术专家. 简介&#xff1a; 本文的主要内容不是介绍现有的比较流行的主要行业的一些数据模型&#xff0c;而是将笔者在数据仓库建设项目中的一些经验&#xff0c;在这里分享给大家。希望帮助大家在数据仓库项目建设中总结出一套能够合…

大数据分析及其建模利用

在数字经济时期&#xff0c;互联网、物联网、5G、大数据、智慧城市等各类模式的信息技术呈爆炸式增长&#xff0c;使得数据以令人难以设想的速度始终增长&#xff0c;企业运营的各个阶段都可以被记载下来&#xff0c;产品销售的各个环节也被记载下来&#xff0c;客户的生产行为…

浅谈大数据建模的主要技术:维度建模

文章目录 前言维度建模关键概念度量和环境事实和维度事实表维度表星形架构和雪花架构 维度建模一般过程1. 选取业务过程2. 定义粒度3. 确定维度4. 确定事实 前言 我们不管是基于 Hadoop 的数据仓库&#xff08;如 Hive &#xff09;&#xff0c;还是基于传统 MPP 架构的数据仓…

大数据建模五步法

from&#xff1a;https://www.sohu.com/a/198093510_783844 前一阵子&#xff0c;某网络公司发起了一个什么建模大赛&#xff0c;有个学员问我&#xff0c;数据建模怎么搞&#xff1f; 为了满足他的好学精神&#xff0c;我决定写这一篇文章&#xff0c;来描述一下数据分析必须…

大数据实践之数据建模

随着DT时代互联网、智能设备及其他信息技术的发展&#xff0c;数据爆发式增长&#xff0c;如何将这些数据进行有序、有结构地分类组织和存储是我们面临的一个挑战。 为什么需要数据建模 如果把数据看作图书馆里的书&#xff0c;我们希望看到它们在书架上分门别类地放置&#xf…

大数据之数据建模

1.星座模型 星形模型中有一张事实表&#xff0c;以及零个或多个维度表&#xff0c;事实表与维度表通过主键外键相关联&#xff0c;维度表之间没有关联&#xff0c;当所有维表都直接连接到“事实表”上时&#xff0c;整个图解就像星星一样。 星形模型是最简单&#xff0c;也是…

数据模型篇之大数据领域建模综述

第8章 大数据领域建模综述 1.为什么需要数据建模 为了更好的将数据进行有序、有结构地分类组织和存储。数据模型就是数据组织和存储方法&#xff0c;它强调从业务、数据存取和使用角度合理存储数据。 数据建模的好处&#xff1a; 性能&#xff1a;良好的数据模型能帮助我们快…

大数据学习(七)一分钟了解数据建模

何为大数据建模&#xff0c;我们从3个W&#xff08;什么、为什么、如何&#xff09;出发来详解下大数据建模。 一、什么是数据建模&#xff08;what&#xff09; 数据建模指的是对现实世界各类数据的抽象组织&#xff0c;确定数据库需管辖的范围、数据的组织形式等直至转化成…

[数学建模] 大数据建模五步法

目录传送门 概要第一步&#xff1a;选择模型或自定义模式第二步&#xff1a;训练模型第三步&#xff1a;评估模型第四步&#xff1a;应用模型第五步&#xff1a;优化模型最后语 概要 PS: 本文转载自 https://www.sohu.com/a/198093510_783844 本文将尝试来梳理一下数据建模的…