You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中ArrayList去重代码里size--的作用疑问

关于Java ArrayList去重代码中size--作用的解析

你提到这段去重代码只有加上size--才能正常运行,疑惑为什么for循环不会自动处理集合大小的变化,下面就拆解size--的核心作用:

首先看你的代码逻辑:

public static ArrayList<String> removeDuplicates(ArrayList<String> members)
{
    int size = members.size();
    for(int i = 0; i < size - 1; i++)
    {
        for(int j = i + 1; j < size; j++)
        {
            if(members.get(i).equals(members.get(j)))
            {
                members.remove(i);
                i--;
                size--;
            }
        }
    }
    return members;
}

size--的核心作用

  1. 同步缓存值与集合真实大小
    你一开始就把集合的初始大小存在了size变量里,后续循环的终止条件(i < size -1、j < size)都是基于这个缓存值,而不是每次调用members.size()获取实时大小。当执行members.remove(i)后,ArrayList的实际元素数量已经减1,但缓存的size不会自动更新,如果不手动size--,这个变量就和集合真实大小脱节,后续循环会访问超出集合范围的索引,直接抛出IndexOutOfBoundsException。

  2. 控制循环的迭代范围
    外层循环的终止条件是i < size -1,如果不更新size,当集合元素被删除后,i的上限还是初始的size-1,会导致i遍历到已经不存在的元素位置。比如初始集合大小是5,删除2个元素后实际大小是3,但外层循环还会让i跑到3(初始size-1是4),此时members.get(i)就会触发越界异常。

  3. 避免无效的循环迭代
    内层循环j的范围是j < size,如果size不更新,j会一直循环到初始的大小值,而那些超过当前集合真实大小的j值都是无效的,既浪费性能,又会引发异常。

补充说明

如果你把循环条件改成直接依赖members.size(),比如:

for(int i = 0; i < members.size() - 1; i++)
{
    for(int j = i + 1; j < members.size(); j++)
    {
        // ... 逻辑不变
    }
}

那确实不需要手动维护size变量,因为每次循环都会获取集合的实时大小。但你的代码选择了提前缓存size的方式,就必须通过size--来同步这个变量和集合的真实状态,否则循环逻辑就会出错。

内容的提问来源于stack exchange,提问作者P M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:12:41