项目中使用Java中List.subList()的注意事项

使用介绍

在Java中,subListList接口的一个方法,用于获取原始列表的子列表

方法的声明如下

List<E> subList(int fromIndex, int toIndex);
  • fromIndex:起始索引(包括)
  • toIndex:结束索引(不包括)
List<Object> list = new Arraylist<>();

List<Object> subList = list.subList(0, 5);

返回的子列表是原始列表的一个视图,对子列表的修改会反映在原始列表上,反之亦然。

例如,下面的语句从列表中移除了元素的范围:

list.subList(from, to).clear();

下面是一个简单的例子:

List<String> originalList = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E"));
List<String> subList = originalList.subList(1, 4);
System.out.println("subList = " + subList); // 子列表包括索引 1,2,3  输出:[B, C, D]
System.out.println("originalList = " + originalList); // 输出:[A, B, C, D, E]

subList.add("F");
System.out.println("subList = " + subList); // 输出: [B, C, D, F]
System.out.println("originalList = " + originalList);// 输出:[A, B, C, D, F, E] 因为通过subList视图对索引为4的位置添加了一个F


originalList.add("G");
// 调用subList()后,如果再对原list进行操作同时对subList()也进行操作(打印、添加、清除),都会报错ConcurrentModificationException,因为这会修改视图的结构
// subList.add("H") java.util.ConcurrentModificationException
// System.out.println(subList);  java.util.ConcurrentModificationException

System.out.println("originalList = " + originalList); // 输出:[A, B, C, D, F, E, G]
originalList.subList(1, 2).clear();
System.out.println("originalList = " + originalList); // 输出: [A, C, D, F, E, G] 因为通过视图对索引为1的数据进行了清除

注意事项

  • ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException 异常,即java.util.RandomAccessSubList cannot be cast to java.util.ArrayList.

说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是 ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。

  • 在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、 删除均会产生 ConcurrentModificationException 异常。
  • 索引范围: fromIndextoIndex 是左闭右开的范围,即包括 fromIndex 处的元素,但不包括 toIndex 处的元素。
  • 修改原列表: 对子列表的修改会反映在原列表上,反之亦然。这是因为子列表实际上是原列表的一个视图。
  • 不支持结构性修改: 在子列表的视图上不支持对原列表的结构性修改(例如插入、删除元素),否则会抛出ConcurrentModificationException异常。结构性修改是指改变原列表的大小或者使其元素的数量发生变化的操作。
  • 子列表可以增、删、改,但是原列表不支持,理由同上
  • subList()返回的不是List!是Sublist,不是原来的类型
 public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<>(this, fromIndex, toIndex) :
                new SubList<>(this, fromIndex, toIndex));
    }
    声明:
    class SubList<E> extends AbstractList<E>{}
  •  LinkedList并没有覆盖这个方法.ArryList自己覆盖了这个方法,返回的是java.util.ArrayList.SubList

public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}
声明:
private class SubList extends AbstractList<E> implements RandomAccess {}

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

看来ArryList处处体现出RandomAccess接口的特性——支持随机访问。

  • java.util.AbstractList.clear()方法就是subList的clear方法
public void clear() {
    removeRange(0, size());
}

...
// ArrayList的覆盖
public void clear() {
    modCount++;
 
    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;
 
    size = 0;
}

...
// LinkedList的覆盖
public void clear() {
    for (Node<E> x = first; x != null; ) {
        Node<E> next = x.next;
        x.item = null;
        x.next = null;
        x.prev = null;
        x = next;
    }
    first = last = null;
    size = 0;
    modCount++;
}

...
// 根据上面,截短一个List的正确姿势
list.subList(from, to).clear();

项目实战

大家可以看一下我的慢查询优化实战文章

在最开始分页慢查询优化没有得到较好的解决方案时,我的操作是直接获取到全部数据的List,然后对List进行截取,达到分页的效果,这是相关的代码

public static <T> IPage<T> listToPage(List<T> list, Integer current, Integer size){
        IPage<T> iPage = new Page<>(current,size);
        iPage.setTotal(list.size());
        int startIndex = (int)((current - 1)*size);
        if(null == list || list.isEmpty() || startIndex > list.size()){
            iPage.setRecords(new ArrayList<>());
        }
        else {
            int toIndex = (int)(current*size);
            iPage.setRecords(list.subList(startIndex,toIndex > list.size() ? list.size() : toIndex));
        }
        return iPage;
    }

大家可以看到,我对List是只截取不操作的,也就不会出现bug

注意!subList是返回一个镜像而不是新示例,用了得保证原来的list不能更改!

over

参考

Java中List的subList()方法及使用注意事项_list sublist-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/280676.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

dash 中的模式匹配回调函数Pattern-Matching Callbacks 8

模式匹配 模式匹配回调选择器 MATCH、ALL 和 ALLSMALLER 允许您编写可以响应或更新任意或动态数量组件的回调函数。 此示例呈现任意数量的 dcc. Dropdown 元素&#xff0c;并且只要任何 dcc. Dropdown 元素发生更改&#xff0c;就会触发回调。尝试添加几个下拉菜单并选择它们的…

Java项目:101SpringBoot仓库管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 仓库管理系统基于SpringBootMybatis开发&#xff0c;系统使用shiro框架做权限安全控制&#xff0c;超级管理员登录系统后可根据自己的实际需求配角色&…

(四)开启定时器2中断

文章目录 定时器2中断的开启借用isp软件生成代码下面进行定时器2中断开启 最终开启定时器2中断的代码定时器2中断服务函数的编写查手册得到定时器2中断查询次序号查手册得次序号为12通过公式计算 中断服务函数编写 结合之前学的点亮LED现象演示 定时器2中断的开启 借用isp软件…

【开源】基于Vue+SpringBoot的二手车交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…

大模型推理部署:LLM 七种推理服务框架总结

自从ChatGPT发布以来&#xff0c;国内外的开源大模型如雨后春笋般成长&#xff0c;但是对于很多企业和个人从头训练预训练模型不太现实&#xff0c;即使微调开源大模型也捉襟见肘&#xff0c;那么直接部署这些开源大模型服务于企业业务将会有很大的前景。 本文将介绍七中主流的…

git基础概念和常用命令(日常开发收藏备用)

目录 ### 常用命令 ### 远程仓库与克隆 ### 分支管理 ### 子模块&#xff08;Submodule&#xff09; ### 其他高级操作 ### 交互式暂存&#xff08;Interactive Staging&#xff09; ### cherry-pick ### rebase ### reflog与reset ### 子树合并&#xff08;Subtree …

Linux操作系统( YUM软件仓库技术 )

镜像文件的回环挂载&#xff08;把iso镜像文件释放成系统安装光盘&#xff09;foundation0上操作 回环挂载的用法&#xff1a; du -sh 对象名 //估算文件&#xff08;一切对象皆文件&#xff09;大小 !$ //上一条命令的最后一个参数 新创建的挂载点目录是空白目录 挂载&#xf…

【OpenCV】OpenCV 4.9.0 正式发布

​ 开源计算机视觉库 OpenCV 4.9.0 已于2023年12月29日正式发布。 此次发布有DNN模块对ONNX Attention、Einsum等层的支持、新的fastGEMM实现、transformers的实验性支持等诸多亮点。 OpenCV 4.9.0 更新内容&#xff1a; &#xff08;来自OpenCV中国团队以及中国社区的贡献…

【Web】vulhub-httpd apache解析漏洞复现(1)

目录 ①CVE-2017-15715 ②apache_parsing_vulnerability ①CVE-2017-15715 贴出源码&#xff1a; <?php if(isset($_FILES[file])) {$name basename($_POST[name]);$ext pathinfo($name,PATHINFO_EXTENSION);if(in_array($ext, [php, php3, php4, php5, phtml, pht]))…

Linux:apache优化(4)—— 隐藏版本号

运行环境 yum -y install apr apr-devel cyrus-sasl-devel expat-devel libdb-devel openldap-devel apr-util-devel apr-util pcre-devel pcre gcc make zlib-devel 源码包配置 ./configure --prefix/usr/local/httpd --enable-cgi --enable-rewrite --enable-so --enabl…

cleanmymac这个软件怎么样?值不值得下载

cleanmymac是我必装的mac端清理软件&#xff0c;界面简洁好看&#xff0c;完美适配mac系统&#xff0c;文件清理的速度、精度都比较优秀&#xff0c;还是比较不错的呢。cleanmymac作为一款第三方清洁应用程序&#xff0c;具有专业完整的清理功能&#xff0c;包括释放内存、一键…

【办公技巧】怎么批量提取文件名到excel

Excel是大家经常用来制作表格的文件&#xff0c;比如输入文件名&#xff0c;如果有大量文件需要输入&#xff0c;用张贴复制或者手动输入的方式还是很费时间的&#xff0c;今天和大家分享如何批量提取文件名。 打开需要提取文件名的文件夹&#xff0c;选中所有文件&#xff0c…

HTML---JavaScript基础

文章目录 目录 文章目录 本章目标 一.JavaScript基础 概述 特点 JavaScript 基本机构 语法 网页中引用JavaScript的方式 二. JavaScript核心语法 变量 ​编辑 数据类型 数组 练习 本章目标 掌握JavaScript的组成掌握JavaScript的基本语法会定义和使用函数会使用工具进行…

[Angular] 笔记 22:ElementRef

chatgpt: ElementRef 是 Angular 中的一个类&#xff0c;它用于包装对 DOM 元素的引用。它允许开发者直接访问与 Angular 组件关联的宿主 DOM 元素。 当在 Angular 中需要直接操作 DOM 元素时&#xff0c;可以使用 ElementRef。通常情况下&#xff0c;最好避免直接操作 DOM&a…

【Transformer】深入理解Transformer模型1——初步认识了解

前言 Transformer模型出自论文&#xff1a;《Attention is All You Need》 2017年 近年来&#xff0c;在自然语言处理领域和图像处理领域&#xff0c;Transformer模型都受到了极为广泛的关注&#xff0c;很多模型中都用到了Transformer或者是Transformer模型的变体&#xff0…

OSPF的DR与BDR-新版(16)

目录 整体拓扑 操作步骤 1.基本配置 1.1 配置R1的IP 1.2 配置R2的IP 1.3 配置R3的IP 1.4 配置R4的IP 1.5 检测R1与R4连通性 1.6 检测R1与R2连通性 1.7 检测R1与R3连通性 2.搭建基本的OSPF网络 2.1 配置R1 OSPF 2.2 配置R2 OSPF 2.3 配置R3 OSPF 2.4 配置R4 OSPF…

前端八股文(工程化篇)

目录 1.常用的git命令有哪些&#xff1f; 2.git rebase和git merge的区别 3.有哪些常见的Loader和Plugin&#xff1f; 4.webpack的构建流程 5.bundle,chunk,module是什么&#xff1f; 6.如何提高webpack的打包速度 7.vite比webpack快在哪里 8.说一下你对Monorepo的理解 …

C语言函数篇——strcat()函数

strcat()函数介绍&#xff1a; strcat()函数是C语言中用于连接两个字符串的函数。它将第二个字符串连接到第一个字符串的末尾&#xff0c;并返回第一个字符串的地址。 strcat()函数的语法&#xff1a; char *strcat(char *dest, const char *src); 其中&#xff0c;dest是目标…

数字图像处理——亚像素边缘的轮廓提取

像素 像素是图像处理中的基本单位&#xff0c;一个像素是图像中最小的离散化单位&#xff0c;具有特定的位置和颜色信息。在数字图像中&#xff0c;每个像素都有一个特定的坐标&#xff0c;通常以行和列的形式表示。每个像素的颜色信息可以通过不同的表示方式&#xff0c;如灰…

大数据- Hadoop入门

目录 &#x1f436;2.1 hadoop的简介 1. 概述 2. 什么是分布式&#xff1f; 3. Hadoop的指代 &#x1f436;2.2 hadoop的发展历程 &#x1f436;2.3 hadoop的版本介绍 &#x1f436;2.4 hadoop的常用端口号 &#x1f436;2.5 hadoop的设计目的 &#x1f436;2.6 hadoo…