制作 .removeAll() 方法时出现 ConcurrentModificationException
ConcurrentModificationException while making .removeAll() method
我有这样的代码
public class ListAnalyzer {
public static List<String> base;
public static void addOfflineToBase(String offline) {
base.add(offline);
}
public static List<String> prepareArrayList() throws IOException {
base = Files.readAllLines(Paths.get("/Users/noname/Desktop/test.txt").toAbsolutePath().normalize());
List<String> part = base.subList(0, 200);
base.removeAll(part);
saveBase();
return part;
}
当我尝试 运行 它时 - 我看到:
Unable to evaluate the expression Method threw 'java.util.ConcurrentModificationException' exception.
在线时我尝试base.removeAll(part)
我在这里看不到冲突。有人能帮助我吗?
顺便说一句: saveBase() 只是将数据写入文本文件
UPD:堆栈跟踪
21:59:26: Executing task 'App.main() --scan'...
> Task :compileJava UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :App.main() FAILED
2 actionable tasks: 1 executed, 1 up-to-date
Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service. Do you accept these terms? [yes, no] Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1445)
at java.base/java.util.ArrayList$SubList.size(ArrayList.java:1185)
at java.base/java.util.AbstractCollection.isEmpty(AbstractCollection.java:87)
at com.lukaspradel.steamapi.webapi.request.GetPlayerSummariesRequest$GetPlayerSummariesRequestBuilder.<init>(GetPlayerSummariesRequest.java:41)
at hexlet.code.App.getOnlineIds(App.java:39)
at hexlet.code.App.start(App.java:21)
at hexlet.code.App.main(App.java:16)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':App.main()'.
> Process 'command '/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 337ms
```lang-none
I need to understand how i can safely remove strings from base
.
有两种方法:
添加一些应用程序级锁定,这样您就不会在其他内容迭代列表时尝试从列表中删除字符串。
使用并发集合类型而不是 List
。 (不清楚哪种集合类型最合适。没有合适的并发列表类型;即支持高效更新的类型。)并发集合类型在 java.util.concurrent
package 中定义。
我想问题出在这几行:
List<String> part = base.subList(0, 200);
base.removeAll(part);
列表 part
实际上由列表 base
支持,因此 base
中的更改反映在 part
中。那可能会导致这样的异常。
要确认这一点,请您尝试:
List<String> part = new ArrayList<>(base.subList(0, 200));
base.removeAll(part);
另一种可能性,它与您的有所不同但相似:
base.subList(0, 200).clear();
这将删除 0 到 200 范围内的所有元素,前提是所有元素都是唯一的。
我有这样的代码
public class ListAnalyzer {
public static List<String> base;
public static void addOfflineToBase(String offline) {
base.add(offline);
}
public static List<String> prepareArrayList() throws IOException {
base = Files.readAllLines(Paths.get("/Users/noname/Desktop/test.txt").toAbsolutePath().normalize());
List<String> part = base.subList(0, 200);
base.removeAll(part);
saveBase();
return part;
}
当我尝试 运行 它时 - 我看到:
Unable to evaluate the expression Method threw 'java.util.ConcurrentModificationException' exception.
在线时我尝试base.removeAll(part) 我在这里看不到冲突。有人能帮助我吗? 顺便说一句: saveBase() 只是将数据写入文本文件 UPD:堆栈跟踪
21:59:26: Executing task 'App.main() --scan'...
> Task :compileJava UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :App.main() FAILED
2 actionable tasks: 1 executed, 1 up-to-date
Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service. Do you accept these terms? [yes, no] Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1445)
at java.base/java.util.ArrayList$SubList.size(ArrayList.java:1185)
at java.base/java.util.AbstractCollection.isEmpty(AbstractCollection.java:87)
at com.lukaspradel.steamapi.webapi.request.GetPlayerSummariesRequest$GetPlayerSummariesRequestBuilder.<init>(GetPlayerSummariesRequest.java:41)
at hexlet.code.App.getOnlineIds(App.java:39)
at hexlet.code.App.start(App.java:21)
at hexlet.code.App.main(App.java:16)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':App.main()'.
> Process 'command '/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 337ms
```lang-none
I need to understand how i can safely remove strings from
base
.
有两种方法:
添加一些应用程序级锁定,这样您就不会在其他内容迭代列表时尝试从列表中删除字符串。
使用并发集合类型而不是
List
。 (不清楚哪种集合类型最合适。没有合适的并发列表类型;即支持高效更新的类型。)并发集合类型在java.util.concurrent
package 中定义。
我想问题出在这几行:
List<String> part = base.subList(0, 200);
base.removeAll(part);
列表 part
实际上由列表 base
支持,因此 base
中的更改反映在 part
中。那可能会导致这样的异常。
要确认这一点,请您尝试:
List<String> part = new ArrayList<>(base.subList(0, 200));
base.removeAll(part);
另一种可能性,它与您的有所不同但相似:
base.subList(0, 200).clear();
这将删除 0 到 200 范围内的所有元素,前提是所有元素都是唯一的。