欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > sublist使用和踩坑

sublist使用和踩坑

2025/5/5 21:14:08 来源:https://blog.csdn.net/xianyu_x/article/details/144306608  浏览:    关键词:sublist使用和踩坑

内存分页会用到sublist,业务里面比较常用的场景就是多线程跑批,需要先拆分任务。

文章目录

      • 注意事项(demo)
      • 应用(demo)
      • 详细介绍

注意事项(demo)

  • 结论:sublist获取的是原列表的镜像;改子列表不会报错、但会影响原列表;改原列表会导致子列表报错,子列表依赖原列表
    public static void main(String[] args) {List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));List<String> subList = list.subList(1, 3); //[1, 3)log.info("=== 刚截取的");log.info("list = {}", list);log.info("subList = {}", subList);subList.add("E");log.info("=== 修改子列表后");log.info("list = {}", list);log.info("subList = {}", subList);list.add("K");log.info("=== 修改原列表后");log.info("list = {}", list);log.info("subList = {}", subList); //TODO subList = [FAILED toString()] 异常java.util.ConcurrentModificationExceptionList<String> subList2 = new ArrayList<>(list.subList(1, 3));subList2.add("F");log.info("=== 截取子列表重新创建新list之后");log.info("list = {}", list.size());log.info("subList = {}", subList); //TODO subList = [FAILED toString()] 异常java.util.ConcurrentModificationExceptionlog.info("subList2 = {}", subList2);log.info("结论:sublist获取的是原列表的镜像;改子列表不会报错、但会影响原列表;改原列表会导致子列表报错,子列表依赖原列表");}

执行结果:
在这里插入图片描述
在这里插入图片描述

应用(demo)

  • 内存分页
public static void main(String[] args) {//三个测试样本List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E", "F", "G", "H"));//List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E", "F", "G", "H", "I"));//List<String> list = new ArrayList<>(Arrays.asList());int groupSize = 3; //一组3个int totalSize = list.size();int handleTimes = totalSize == 0 ? 0 : (totalSize%groupSize == 0 ? (totalSize/groupSize) : (totalSize/groupSize + 1));//处理次数for (int i = 1; i <= handleTimes; i++) {List<String> subList = null;if(i == handleTimes) {subList = list.subList((i-1)*groupSize, totalSize);} else {subList = list.subList((i-1)*groupSize, i*groupSize);}log.info("分组 - {}", subList);}}

执行结果:
在这里插入图片描述

详细介绍

在使用 subList 方法时,需要注意以下几个关键点,以避免潜在的问题:

  1. 子列表与原列表共享数据
    subList 返回的子列表不是一个新的列表,而是原列表的视图(view)。
    对子列表的修改会影响原列表,反之亦然。

List list = new ArrayList<>(Arrays.asList(“A”, “B”, “C”, “D”));
List subList = list.subList(1, 3);
subList.set(0, “X”); // 修改子列表
System.out.println(list); // 输出: [A, X, C, D]

  1. 子列表不能独立于原列表操作
    如果修改了原列表的结构(如增删元素),子列表会变得不可用,操作时会抛出 ConcurrentModificationException。

List list = new ArrayList<>(Arrays.asList(“A”, “B”, “C”, “D”));
List subList = list.subList(1, 3);
list.add(“E”); // 修改原列表结构
subList.get(0); // 抛出 ConcurrentModificationException

解决办法:

如果需要独立的子列表,建议创建一个新的列表:

List independentList = new ArrayList<>(list.subList(1, 3));

  1. 索引范围必须合法
    subList(fromIndex, toIndex) 方法要求:
    fromIndex >= 0
    toIndex <= list.size()
    fromIndex <= toIndex
    如果索引越界,会抛出 IndexOutOfBoundsException。

List list = new ArrayList<>(Arrays.asList(“A”, “B”, “C”, “D”));
List subList = list.subList(2, 5); // 抛出 IndexOutOfBoundsException

  1. 子列表的并发问题
    如果在多线程环境中使用 subList,要注意线程安全问题。
    推荐在外部同步访问原列表和子列表,或使用线程安全的集合(如 Collections.synchronizedList)。
  2. 子列表的序列化问题
    由于子列表依赖于原列表,因此在序列化时需要确保原列表也可序列化。否则,序列化子列表会失败。
  3. 使用场景
    推荐:

用于对列表的一个范围执行只读操作。
用于分块操作(如分页处理)。
避免:

长期保存子列表引用,容易导致意外问题。
通过了解这些注意事项,可以更安全和高效地使用 subList 方法。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词