项目中使用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的位置添加了一个ForiginalList.add("G");
// 调用subList()后,如果再对原list进行操作同时对subList()也进行操作(打印、添加、清除),都会报错ConcurrentModificationException,因为这会修改视图的结构
// subList.add("H") java.util.ConcurrentModificationException
// System.out.println(subList);  java.util.ConcurrentModificationExceptionSystem.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 workfor (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博客

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC学习与开发(四)

注&#xff1a;此为笔者学习狂神说SpringMVC的笔记&#xff0c;其中包含个人的笔记和理解&#xff0c;仅做学习笔记之用&#xff0c;更多详细资讯请出门左拐B站&#xff1a;狂神说!!! 11、Ajax初体验 1、伪造Ajax 结果&#xff1a;并未有xhr异步请求 <!DOCTYPE html> &…

NXP实战笔记(一):基于RTD-SDK新建一个S32DS工程

目录 1、概述 2、操作步骤 2.1、新建Application工程 2.2、命名工程、选择芯片型号、选择编译器GCC版本 2.3、配置基本参数 3、文件描述 3.1、文件结构描述 3.2、编译之后 4、下载调试 1、概述 安装了S32DS之后&#xff0c;导入SDK插件&#xff0c;这个步骤不赘述&…

R统计学1 - 基础操作入门问题1-20

R统计学入门基础问题 1. 如何生成100个高斯&#xff08;正态&#xff09;分布随机数 x <- rnorm(100, mean 5, sd 0.1) x # [1] 4.893534 5.046611 5.081097 4.979164 5.181700 5.038192 5.135376 5.173346 4.968877 4.986146 # [11] 4.946258 5.198199 5.055531 4.9430…

LSTM中文新闻分类源码详解

LSTM中文新闻分类 一、导包二、读取数据三、数据预处理1.分词、去掉停用词和数字、字母转换成小写等2.新闻文本标签数值化 三、创建词汇表/词典1.data.Field()2.空格切分等3.构建词汇表/词典使用训练集构建单词表&#xff0c;vectorsNone:没有使用预训练好的词向量,而是使用的是…

【机器学习合集】深度生成模型 ->(个人学习记录笔记)

深度生成模型 深度生成模型基础 1. 监督学习与无监督学习 1.1 监督学习 定义 在真值标签Y的指导下&#xff0c;学习一个映射函数F&#xff0c;使得F(X)Y 判别模型 Discriminative Model&#xff0c;即判别式模型&#xff0c;又称为条件模型&#xff0c;或条件概率模型 生…

swift-碰到的问题

如何让工程不使用storyboard和scene 删除info.plist里面的Application Scene mainifest 删除SceneDelegate.swift 删除AppDelegate.swift里面的这两个方法 func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession…

[C#]opencvsharp进行图像拼接普通拼接stitch算法拼接

介绍&#xff1a; opencvsharp进行图像拼一般有2种方式&#xff1a;一种是传统方法将2个图片上下或者左右拼接&#xff0c;还有一个方法就是融合拼接&#xff0c;stitch拼接就是一种非常好的算法。opencv里面已经有stitch拼接算法因此我们很容易进行拼接。 效果&#xff1a; …

十三:爬虫-Scrapy框架(下)

一&#xff1a;各文件的使用回顾 1.items的使用 items 文件主要用于定义储存爬取到的数据的数据结构&#xff0c;方便在爬虫和 Item Pipeline 之间传递数据。 items.pyimport scrapyclass TencentItem(scrapy.Item):# define the fields for your item here like:title scr…

[mysql 基于C++实现数据库连接池 连接池的使用] 持续更新中

目背景 常见的MySQL、Oracle、SQLServer等数据库都是基于C/S架构设计的&#xff0c;即&#xff08;客户端/服务器&#xff09;架构&#xff0c;也就是说我们对数据库的操作相当于一个客户端&#xff0c;这个客户端使用既定的API把SQL语句通过网络发送给服务器端&#xff0c;MyS…

Animate 2024(Adobe an2024)

Animate 2024是一款由Adobe公司开发的动画和互动内容创作工具&#xff0c;是Flash的演进版本。Animate 2024为设计师和开发者提供了更丰富的功能&#xff0c;让他们能够创建各种类型的动画、交互式内容和多媒体应用程序。 Animate 2024具有以下特点&#xff1a; 强大的设计工…

一个静态网站可以增加什么第三方功能/服务

一个静态网站&#xff0c;无后台功能&#xff0c;怎么增加一些实用功能呢&#xff1f;我们来看看一些免费的第三方服务。 静态页面寄存 Gitee pages/Github pages 都可以&#xff0c;绑定一个域名&#xff0c;版本一提交&#xff0c;直接发布有效果。 评论 每个 URL 页面都…

华为hcia之ipv6实验手册

R3: dhcp enable ipv6 dhcpv6 pool test address prefix 2000:23::/64 excluded-address 2000:23::2 dns-server 2000:23::2 interface GigabitEthernet0/0/0 ipv6 enable ipv6 address 2000:12::2/64 ipv6 address auto link-local undo ipv6 nd ra halt //无状态配置 inter…

SpringBoot用JDK1.8的依赖设置pom.xml

pom.xml的修改主要是两个地方&#xff1a; 1.修改springframework的版本为2.5.0&#xff0c;版本太高可能和其他插件搭配有冲突&#xff1b; 2.Java的版本修改成8&#xff0c;也就是对应JDK1.8。

uni-app API接口扩展组件(uni-ui)

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…

云原生|kubernetes|kubernetes资源备份和集群迁移神器velero的部署和使用

前言&#xff1a; kubernetes集群需要灾备吗&#xff1f;kubernetes需要迁移吗&#xff1f; 答案肯定是需要的 那么&#xff0c;如何做kubernetes灾备和迁移呢&#xff1f;当然了&#xff0c;有很多的方法&#xff0c;例如&#xff0c;自己编写shell脚本&#xff0c;或者使用…

Geotrust的rapidssl证书产品

Geotrust成立于2001年&#xff0c;现在是Digicert旗下的SSL数字证书品牌&#xff0c;经营范围遍布全球&#xff0c;为众多用户提供网站数据加密和身份认证服务。RapidSSL是Geotrust旗下的子品牌证书&#xff0c;主要有两款入门级的SSL数字证书&#xff0c;今天就随SSL盾小编了解…

RM3100 stm32驱动(硬件i2c)

目录 RM3100接线HAL库I2C函数HAL_I2C_Mem_ReadHAL_I2C_Mem_WriteHAL_I2C_Master_Transmit / HAL_I2C_Master_Receive例子 HSHAKE寄存器 cubemx配置RM3100寄存器驱动最终效果 RM3100接线 原理图 SA0 SA1接地&#xff0c;此时i2c设备地址为0100000&#xff0c;即0x20 如果SA0接…

大创项目推荐 深度学习交通车辆流量分析 - 目标检测与跟踪 - python opencv

文章目录 0 前言1 课题背景2 实现效果3 DeepSORT车辆跟踪3.1 Deep SORT多目标跟踪算法3.2 算法流程 4 YOLOV5算法4.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; *…

springBoot2.3-基本介绍及入门案例

本次学习雷丰阳springBoot(2.3版本)。建议先修ssm 一、SpringBoot基本介绍 springBoot是当今最为流行的java开发框架。 1、springBoot的底层是spring&#xff0c; 因此继承了spring的粘合其他框架的能力。 2、本质上还是其他框架包括spring在工作 , springBoot起到一个整合其他…

uni-app page新建以及page外观配置

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…