subList方法踩坑记录

2023-11-09

前言

现有一个简化的需求,假设有一个点位列表["1", "2", "4", "5"],现在需要将该列表从中间分成两份:

  • 序列1:["1", "2"]
  • 序列2:["4", "5"]

分开后在序列1的末尾添加一个元素"3",变成["1", "2", "3"]

问题复现

在编写下面的测试代码运行后,结果并不是想要的:

public static void testSubList() {
    List<String> origin = new ArrayList<>();
    origin.add("1");
    origin.add("2");
    origin.add("4");
    origin.add("5");
    
    List<String> sub1 = origin.subList(0, 2);
    sub1.add("3");
    
    List<String> sub2 = origin.subList(2, origin.size());
    
    // 打印结果
    System.out.println(sub1);
    System.out.println(sub2);
}

结果:

[1, 2, 3] //sub1
[3, 4, 5] //sub2

按需求来说,sub2中应该是["4", "5"],为什么在sub1中插入的"3"也进去了呢?

subList方法解析

在查阅资料时,发现该篇文章做了说明:https://www.jianshu.com/p/69937e239d61。

总结来说,就是使用subList方法分割出来的子序列,仍然和原序列关联,在子序列上进行的增删操作,影响的其实是原序列。这也解释了上面代码出现的问题:

  • 在sub1中插入元素"3"后,原序列变成了["1", "2", "3", 4", "5"]
  • sub2截取到的元素自然变成了["3", 4", "5"]

同时,对于subList的不正确使用还会引发java.util.ConcurrentModificationException异常。

复现异常

如果将sub1添加元素的操作放在切割sub2后,则会引发异常:

public static void testSubList() {
    List<String> origin = new ArrayList<>();
    origin.add("1");
    origin.add("2");
    origin.add("4");
    origin.add("5");
    
    List<String> sub1 = origin.subList(0, 2);
    
    List<String> sub2 = origin.subList(2, origin.size());
    sub1.add("3");
    
    // 打印结果
    System.out.println(sub1);
    System.out.println(sub2);
}
[1, 2, 3]
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1241)
	at java.util.ArrayList$SubList.listIterator(ArrayList.java:1101)
	at java.util.AbstractList.listIterator(AbstractList.java:299)
	at java.util.ArrayList$SubList.iterator(ArrayList.java:1097)
	at java.util.AbstractCollection.toString(AbstractCollection.java:454)
	at java.lang.String.valueOf(String.java:2994)
	at java.io.PrintStream.println(PrintStream.java:821)
	at com.example.nb_road.IndexTest.testSubList(IndexTest.java:118)
	at com.example.nb_road.IndexTest.main(IndexTest.java:126)

意思是非线程安全的容器被非法修改了。

上面说到,子序列的修改会反应在原序列上,同样的,原序列的操作也会反应在子序列上。由此我们可以推出,sub1的修改也会影响到sub2,但是,当sub1的修改操作是在sub2已经建立之后的,就会引发异常。

可以想象,sub2的内容可能不知道在某个地方就被修改了!因此必须要避免这种情况的发生。

解决方案

解决方案也简单,复制一份我们需要的元素不就可以了吗?

public static void testSubList() {
    List<String> origin = new ArrayList<>();
    origin.add("1");
    origin.add("2");
    origin.add("4");
    origin.add("5");
    List<String> sub1 = origin.subList(0, 2);
    List<String> newSub1 = new ArrayList<>(sub1);
    newSub1.add("3");
    
    List<String> sub2 = origin.subList(2, origin.size());
    List<String> newSub2 = new ArrayList<>(sub2);
    
    
    System.out.println(newSub1); //[1, 2, 3]
    System.out.println(newSub2); //[4, 5]
}

所以在使用subList时一定要注意。

参考

java.util.ConcurrentModificationException 原因分析及解决方案

sublist()方法坑

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

subList方法踩坑记录 的相关文章

  • 带路径压缩算法的加权 Quick-Union

    有一种 带路径压缩的加权快速联合 算法 代码 public class WeightedQU private int id private int iz public WeightedQU int N id new int N iz new
  • Java:扩展类并实现具有相同方法的接口

    可能无法完成以下操作 我收到编译错误 继承的方法 A doSomthing int 无法隐藏 B 中的公共抽象方法 public class A int doSomthing int x return x public interface
  • 使用 Tabula 通过 Python 读取 pdf 时出现 Java 错误

    我已经安装了 tabula 库 用于使用 python 将 pdf 读取到 pandas 数据框中 但是当我运行代码时 import tabula df tabula read pdf sample1 pdf pages 1 我得到了例外
  • Java Logger 未记录到 Netbeans 中的输出

    我正在 Netbeans 中使用 Maven 启动一个 Java 项目 我编写了一些代码来使用 Logger 类进行日志记录 但是 日志记录似乎不起作用 在程序开始时 我运行 Logger getLogger ProjectMainClas
  • 如何在 JavaFX 中连接可观察列表?

    我所说的串联是指获得一个新列表 该列表侦听所有串联部分的更改 方法的目的是什么FXCollections concat ObservableList
  • 什么是抽象类? [复制]

    这个问题在这里已经有答案了 当我了解抽象类时 我说 WT H 问题 创建一个无法实例化的类有什么意义呢 为什么有人想要这样的课程 什么情况下需要抽象类 如果你明白我的意思 最常见的是用作基类或接口 某些语言有单独的interface构建 有
  • 如何在 JPQL 或 HQL 中进行限制查询?

    在 Hibernate 3 中 有没有办法在 HQL 中执行相当于以下 MySQL 限制的操作 select from a table order by a table column desc limit 0 20 如果可能的话 我不想使用
  • 从 MATLAB 调用 Java?

    我想要Matlab程序调用java文件 最好有一个例子 需要考虑三种情况 Java 内置库 也就是说 任何描述的here http docs oracle com javase 6 docs api 这些项目可以直接调用 例如 map ja
  • 如何在单个查询中搜索 RealmObject 的 RealmList 字段

    假设我有一堂课 public class Company extends RealmObject private String companyId private RealmList
  • Java 中如何将 char 转换为 int? [复制]

    这个问题在这里已经有答案了 我是Java编程新手 我有例如 char x 9 我需要得到撇号中的数字 即数字 9 本身 我尝试执行以下操作 char x 9 int y int x 但没有成功 那么我应该怎么做才能得到撇号中的数字呢 ASC
  • 将非 Android 项目添加到 Android 项目

    我在 Eclipse 中有三个项目 Base Server 和 AndroidClient Base和Server是Java 1 7项目 而AndroidClient显然是一个android项目 基础项目具有在服务器和 Android 客户
  • 如何在 Spring 中使 @PropertyResource 优先于任何其他 application.properties ?

    我正在尝试在类路径之外添加外部配置属性资源 它应该覆盖任何现有的属性 但以下方法不起作用 SpringBootApplication PropertySource d app properties public class MyClass
  • Java Applet 中的 Apache FOP - 未找到数据的 ImagePreloader

    我正在研究成熟商业产品中的一个问题 简而言之 我们使用 Apache POI 库的一部分来读取 Word DOC 或 DOCX 文件 并将其转换为 XSL FO 以便我们可以进行标记替换 然后 我们使用嵌入到 Java 程序中的 FOP 将
  • 如何使用 JMagick 转换色彩空间?

    如何使用 JMagick API 转换色彩空间 例如 CMYK gt RGB 和 RGB gt CMYK None
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • 使用 Elastic Beanstalk 进行 Logback

    我在使用 Elastic Beanstalk 记录应用程序日志时遇到问题 我正在 AWS Elastic Beanstalk 上的 Tomcat 8 5 with Corretto 11 running on 64bit Amazon Li
  • 轻松的反应

    我有一个与这里描述的类似的案例 动态更改RESTEasy服务返回类型 https stackoverflow com questions 3786781 dynamically change resteasy service return
  • 手动设置Android Studio的JDK路径

    如何为 Android Studio 使用自定义 JDK 路径 我不想弄乱 PATH 因为我没有管理员权限 是否有某个配置设置文件允许我进行设置 如果您查看项目设置 您可以从那里访问 jdk 在标准 Windows 键盘映射上 您可以在项目
  • partitioningBy 必须生成一个包含 true 和 false 条目的映射吗?

    The 分区依据 https docs oracle com javase 8 docs api java util stream Collectors html partitioningBy java util function Pred
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何

随机推荐

  • Git的下载与安装教程

    一 Git下载 官网下载地址 Git git scm com 点击 Download for Windows 跳转至详细下载页面 以Windows64位安装版为例 点击 64 bit Git for Windows Setup 即可进行下载
  • 3分钟阿里云服务器网络收发包PPS性能详解

    阿里云服务器ECS网络收发包PPS是什么 云服务器PPS多少合适 网络收发包PPS是指云服务器每秒可以处理的网络数据包数量 单位是PPS即packets per second每秒发包数量 阿里云百科来详细说下阿里云服务器网络收发包PPS性能
  • 【Unity学习笔记】[Unity中文课堂教程] C#中级编程代码

    Unity学习笔记 Unity中文课堂教程 C 中级编程代码 最近想补一补C 基础 Unity官方的C 中级编程教程质量很高 于是开个帖子把跟着敲 记录了部分价讲解和我自己的理解的代码存在这 原课程链接 添加链接描述 https www b
  • s3c2440上的nor flash启动与nand flash启动的区别

    nor flash启动与nand flash启动的区别 1 接口区别 NOR FLASH地址线和数据线分开 来了地址和控制信号 数据就出来 NAND Flash地址线和数据线在一起 需要用程序来控制 才能出数据 通俗的说 就是光给地址不行
  • vue基础之组件化及父子间通信

    基本组件拆分和嵌套 为了不是项目看起来复杂难懂 所以我们采用组件化开发 所有的组件单独放 在需要使用的地方嵌套即可 app vue
  • Vue组件嵌套和组件通信

    一 组件嵌套 组件嵌套 在一个组件中使用另一个组件 div div
  • Lodash中的_.cloneDeep(value) 深拷贝和_.clone(value) 浅拷贝

    Lodash 是一个一致性 模块化 高性能的 JavaScript 实用工具库 cloneDeep value 这个方法类似 clone 除了它会递归拷贝 value 注 也叫深拷贝 参数 value 要深拷贝的值 返回 返回拷贝后的值 例
  • 距离计算方法-聚类

    k 均值聚类算法的性能会受到所选距离计算方法的影响 所以 今天总结了一下有关距离计算的一些总结 如有错误 望大家指正 1 欧式距离是大家最熟悉的了 比如两点之间的距离的计算 可以写成向量的运算形式 工程中用的最多 2 曼哈顿距离 Manha
  • TypeScript学习(Never、辨析联合类型、索引签名)

    Never 程序语言的设计确实应该存在一个底部类型的概念 当你在分析代码流的时候 这会是一个理所当然存在的类型 TypeScript 就是这样一种分析代码流的语言 因此它需要一个可靠的 代表永远不会发生的类型 never 类型是 TypeS
  • 黑客常用的攻击手段

    黑客攻击手段分为非破坏性攻击和破坏性攻击两大类 非破坏性攻击一般只是为了扰乱系统的运行 并不盗窃系统资料 通常采用拒绝服务攻击或信息炸弹 破坏性攻击是以入侵他人电脑系统 盗窃系统保密信息 破坏目标系统的数据为目的的 下面介绍黑客常用的几种攻
  • YARN原理总结

    问题导读 1 hadoop1 x中mapreduce框架与yarn有什么共同点 2 它们有什么不同点 3 yarn中有哪些改变 4 yarn中有哪些术语 yarn是比较难懂的一个地方 也是很重要的一个组件 不止hadoop使用yarn sp
  • 局域网计算机无法配置网关,在内网中,为什么不设置“默认网关”计算机也能互相通讯?...

    在内网中不设置 默认网关 的计算机也能互相通讯 是因为在同一内网 同一VLAN同一子网 中两台计算机机之间是不需要通过默认网关来通信的 是通过交换机 或路由器 上的列表来匹配进行数据传输的 下面讲一下这样子的通信原理 一 PC A向PC C
  • 关键路径例题图表_计算题专题:关键路径法(CPM)

    关键路径法 Critical Path Method CPM 通过分析项目过程中哪个活动序列进度安排的总时差最少来预测项目工期的网络分析 产生目的 为了解决 在庞大而复杂的项目中 如何合理而有效地组织人力 物力和财力 使之在有限资源下以最短
  • 只出现一次的数字 LeetCode C++

    目录 题目描述 方法一 vector 方法二 set 方法三 异或 题目描述 给定一个非空整数数组 除了某个元素只出现一次以外 其余每个元素均出现两次 找出那个只出现了一次的元素 说明 你的算法应该具有线性时间复杂度 你可以不使用额外空间来
  • 爆库原理剖析

    一 方式 暴库的方式有多种多样 我知道的就有3种以上 常见的暴的方法有 5c类暴 conn asp暴 ddos暴等等 二 原理 5c 暴库法 它不是网页本身的漏洞 而是利用了 解码方式中的一个特性 如果 安全设置不周全 而网页设计者未考虑
  • 解决seaborn无法加载数据集错误

    欢迎关注笔者的微信公众号 问题描述 因研究需要 今天在了解seaborn 这个可视化框架 但是在第一行代码就报错了 好嘛 看看啥错 看到这我就知道大概啥问题了 国内网络对国外的网站很不友好 解决方案 解决方法也很简单 主要有以下三种 ke
  • 关于win7下styleSheet设置不成功

    为 QTreeWidget 设置 style sheet 当使用下面的语句时 在 Windows Vista 和 Windows 7 下是失败的 QTreeWidget selection background color rgb 51 1
  • Java怎样求解n的阶乘 n!(详解)

    n 是表示为自然数n的阶乘 即 n 1 2 3 n 2 n 1 n 如 9 9 8 7 6 5 4 3 2 1 阶乘也可以递归方式定义 0 1 n n 1 n 希望对您有所帮助 具体代码实现 import java util Scanner
  • 软件测试分类

    一 软件测试的分类 1 按开发阶段 单元测试 集成测试 系统测试 验收测试 2 按测试实施组织 第三方 3 按测试执行方式 静态测试 动态测试 4 按是否查看代码 黑盒测试 白盒测试 灰盒测试 5 按是否手工执行划分 手工测试 自动化测试
  • subList方法踩坑记录

    前言 现有一个简化的需求 假设有一个点位列表 1 2 4 5 现在需要将该列表从中间分成两份 序列1 1 2 序列2 4 5 分开后在序列1的末尾添加一个元素 3 变成 1 2 3 问题复现 在编写下面的测试代码运行后 结果并不是想要的 p