「知识星球」社群服务多,还有开源项目等资料分享

2025-04-06
来源:网络整理

这是一个对您有用的社区

一对一的交流/采访手册/简历优化/求职和回答问题,欢迎加入“”知识星球。以下是地球提供的一些信息:

这是一个可能对您有用的开源项目

国内恒星具有一个10W +开源项目,包括管理后端 +微信小计划,后端支持单体和微服务体系结构。

功能涵盖RBAC权限,SaaS多租户,数据权限,购物中心,付款,工作流程,大屏幕报告,微信公共帐户和其他功能:

[中国的第一批批次]支持JDK 21+ 3.2.0,JDK 8+靴子的双版本2.7.18

这是我在最近的采访中被问到的一个采访问题。该博客总结并分享了这个问题。

也许许多新手(包括我当时,哈哈)想到以下写作方法:

public static void main(String[] args) {
    List platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (String platform : platformList) {
        if (platform.equals("博客园")) {
            platformList.remove(platform);
        }
    }

    System.out.println(platformList);
}

然后他充满信心地运行了它,但实际上他扔了一个爪哇。例外,被翻译成中文为:并发修改异常。

您是否感到困惑和想知道为什么?

首先,让我们查看上述代码生成的字节码,如下所示:

从中,我们可以看到,当循环实际执行时,使用的核心方法为()和next()。

然后,让我们看一下如何实施以下课程?

可以看出,调用下一个()获得下一个元素时,第一行代码是调用();),此方法的核心逻辑是比较这两个变量的值。

在上面的示例中,开始时的总和值为3,因此可以第一次获得元素“博客花园”,但是当执行以下代码行时:

platformList.remove(platform);

修改4的值。

因此,当第二次获得元件时,总和值不相等,因此java.util。抛出了例外。

由于无法使用它实施,我们应该如何实施它?

主要有三种方法:

二手方法

用于循环呈正顺序遍历

反向遍历用于循环

接下来,我们将一一解释。

后端管理系统 +基于启动 + plus + vue&支持RBAC动态权限,多租户,数据权限,工作流程,三方登录,付款,SMS,购物中心和其他功能的后端管理系统 +用户

所使用的()方法的实现如下:

public static void main(String[] args) {
    List platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    Iterator iterator = platformList.iterator();
    while (iterator.hasNext()) {
        String platform = iterator.next();
        if (platform.equals("博客园")) {
            iterator.remove();
        }
    }

    System.out.println(platformList);
}

输出结果是:

[CSDN,掘金]

为什么使用。();

让我们看一下其源代码:

可以看出,每次删除元素时,值都会重新分配到,以使两个变量相等,并且Java.util。异常不会触发。

后端管理系统 +基于 + + + + vue&支持RBAC动态权限,多租户,数据权限,工作流程,三方登录,付款,SMS,购物中心和其他功能的后端管理系统 +用户

使用循环的正顺序遍历的实施如下:

public static void main(String[] args) {
    List platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (int i = 0; i < platformList.size(); i++) {
        String item = platformList.get(i);

        if (item.equals("博客园")) {
            platformList.remove(i);
            i = i - 1;
        }
    }

    System.out.println(platformList);
}

这种实现方法更容易理解,即通过数组的下标将其删除。但是,要注意的一件事是,删除元素后,您必须纠正下标的值:

i = i - 1;

为什么要纠正下标的价值?

因为初始元素的下标是这样:

在第一个循环删除元素“博客花园”之后,该元素的下标如下:

i的值是第二个循环中的1个,这意味着采用元素“掘金”,这会导致元素“ csdn”被跳过并检查。因此,删除元素后,我们需要纠正下标,这也是i = i -1的目的;在上述代码中。

使用用于循环的反向顺序遍历的实现如下:

public static void main(String[] args) {
    List platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (int i = platformList.size() - 1; i >= 0; i--) {
        String item = platformList.get(i);

        if (item.equals("掘金")) {
            platformList.remove(i);
        }
    }

    System.out.println(platformList);
}

此实现方法类似于使用for for循环进行遍历,但是无需修改下标,因为该元素的初始下标如下:

在第一个循环中删除元素“掘金”后,该元素的下标如下:

在第二个循环期间,i的值是1,这意味着采用元素“ csdn”,这不会导致元素跳过,因此无需纠正下标。

从JDK1.8开始,您可以使用()方法在遍历遍历时实现删除。实际上,想法也会提示:

因此,原始代码:

Iterator iterator = platformList.iterator();
while (iterator.hasNext()) {
    String platform = iterator.next();
    if (platform.equals("博客园")) {
        iterator.remove();
    }
}

它可以简化为1行代码,如下所示,这非常简洁:

platformList.removeIf(platform -> "博客园".equals(platform));

查看()方法的源代码后,您会发现基础层还使用()方法:

让我们首先谈论结论:需要。

但是,上一篇文章中提到的示例不是很好,因此许多读者认为可以在阅读后不纠正下标是可以的。实际上,不是。让我们以另一个例子理解它:

List platformList = new ArrayList<>();
platformList.add("博客园");
platformList.add("博客园");
platformList.add("CSDN");
platformList.add("掘金");

for (int i = 0; i < platformList.size(); i++) {
 String item = platformList.get(i);
    if ("博客园".equals(item)) {
     platformList.remove(i);
    }
}

System.out.println(platformList);

输出结果:

[博客公园,CSDN,掘金]

可以发现,如果未纠正下标,则第二个要素“博客花园”将在循环遍历期间跳过,并且不会删除,因此必须纠正下标:

欢迎加入我的知识星球,以全面提高技术能力。

还要补充,“长按”或“扫描”以下QR码:

地球的内容包括:项目实践,面试招聘,源代码分析和学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

分享