这是一个对您有用的社区
一对一的交流/采访手册/简历优化/求职和回答问题,欢迎加入“”知识星球。以下是地球提供的一些信息:
这是一个可能对您有用的开源项目
国内恒星具有一个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码:
地球的内容包括:项目实践,面试招聘,源代码分析和学习路线。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)