ListUtil#split和remove搭配使用的坑

一、问题描述

代码:

  1. 在代码中用到了hutool工具的ListUtil#split方法;
  2. 在切分list后,循环,并在循环里调用了removeAll方法;

现象描述:发现后续被切分的list集合,以及list集合的子集数量和我期望的对不上。

代码如下:

java 复制代码
public static void test1(){
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");

        List<List<String>> split =ListUtil.split(list,3);

        for (List<String> strings : split) {
            remove(strings);
            for (String string : strings) {
                System.out.println(string);
            }

        }
    }


	public static void remove(List<String> strings){
        List<String> removeList = new ArrayList<>();
        removeList.add("1");
        strings.removeAll(removeList);
    }

我期望输出:

2

3

4

5

实际输出:

2

3

5

二、原因分析

  1. hutool的ListUtil#split内部用的是 list.subList;
  2. subList 执行结果是获取 ArrayList 的一部分,返回的是 ArrayList 的部分视图。对子集合的操作会反映到原集合, 对原集合的操作也会影响子集合;
  3. 说白了,你对子集合,remove数据,后面的就会顶上去;你add数据,就会加在后面。

断点分析:

其实源码里已经有说明了:

三、注意点及解决方法

  1. 在ListUtil#split后,不要去remove或者add元素;
  2. 新建list,用新的list来处理移除或新增逻辑;
  3. 不光是hutool的ListUtil#split方法哦,其他第三方的partition、subList方法都是一个原理!!
相关推荐
蛋蛋的就会顺顺的9 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
需要8269 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡9 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
伯恩bourne11 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
silvamux_12 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
省钱兄--zs12 小时前
深圳24小时自助健身房软硬件解决方案实战指南与开发流程详解
java·数据仓库·spring boot·小程序·架构
顽疲12 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog13 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
用户212968352616813 小时前
开源了一个 Java 多智能体 LLM 框架 Baton:一个依赖,把 Agent 循环、工具调用、记忆、编排全配齐
java·llm
helmsail13 小时前
05 管理活动与选品
java