我们都知道你不能这样做:
for (Object i : l) {
if (condition(i)) {
l.remove(i);
}
}
Run Code Online (Sandbox Code Playgroud)
ConcurrentModificationException等等......这显然有时起作用,但并非总是如此.这是一些特定的代码:
public static void main(String[] args) {
Collection<Integer> l = new ArrayList<>();
for (int i = 0; i < 10; ++i) {
l.add(4);
l.add(5);
l.add(6);
}
for (int i : l) {
if (i == 5) {
l.remove(i);
}
}
System.out.println(l);
}
Run Code Online (Sandbox Code Playgroud)
当然,这会导致:
Exception in thread "main" java.util.ConcurrentModificationException
Run Code Online (Sandbox Code Playgroud)
...即使多线程没有这样做......无论如何.
什么是这个问题的最佳解决方案?如何在循环中从集合中删除项而不抛出此异常?
我也在Collection这里使用任意,不一定是ArrayList,所以你不能依赖get.
我有一个我想迭代的ArrayList.迭代它时,我必须同时删除元素.显然这会抛出一个java.util.ConcurrentModificationException.
处理此问题的最佳做法是什么?我应该先克隆列表吗?
我删除不在循环本身但是代码的另一部分的元素.
我的代码看起来像这样:
public class Test() {
private ArrayList<A> abc = new ArrayList<A>();
public void doStuff() {
for (A a : abc)
a.doSomething();
}
public void removeA(A a) {
abc.remove(a);
}
}
Run Code Online (Sandbox Code Playgroud)
a.doSomething可能打电话Test.removeA();
我在一个arraylist上运行一个迭代器,并在条件为真时尝试删除一个项目.
我有以下代码:
String item = (String) model.getElementAt(selectedIndices[i]);
Iterator it = p.eggMoves.iterator();
while(it.hasNext())
{
String text = (String) it.next();
if ( text.equals(item) )
{
it.remove();
p.eggMoves.remove(selectedIndices[i]);
model.removeElementAt(selectedIndices[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
现在这段代码工作正常,该项从p对象和jlist中删除,但它在it.next()行引发"ConcurrentModificationException"异常.
我该如何解决这个问题?
我按照测试ConcurrentModificationException概念编写了这个例子:
public class Person
{
String name;
public Person(String name)
{
this.name = name;
}
}
public static void main(String[] args)
{
List<Person> l = new ArrayList<Person>();
l.add(new Person("a"));
l.add(new Person("b"));
l.add(new Person("c"));
int i = 0;
for(Person s : l)
{
if(s.name.equals("b"))
l.remove(i);
i++;
}
for(Person s : l)
System.out.println(s.name);
}
Run Code Online (Sandbox Code Playgroud)
当我执行上面的main方法时,ConcurrentModificationException不会抛出,输出控制台会输出以下结果:
a
c
Run Code Online (Sandbox Code Playgroud)
根据我对这个问题的了解,当在循环列表中时,在修改列表时,ConcurrentModificationException应该抛出异常.但为什么在我的样本中这不会发生?
我的应用程序已在Google登录过程中开始崩溃。
以前没有像这样崩溃。
是否可以连接到更改Google Play服务版本?
还有什么可能导致此崩溃?
我可以通过延迟在Application类中实现OneSignal初始化之前停止它。但是,我不确定它们是如何连接的,只是由于反复试验,才发现它们之间的连接。更改OneSignal实现似乎不是一个合适的解决方案,因为它回避了以前没有发生过的问题,如果我找不到更具体的原因,可能会再次发生。
此外,崩溃并不总是在登录过程中发生。
logcat的主要线索似乎是:
An error occurred while executing doInBackground()
Caused by: java.util.ConcurrentModificationException
at com.google.android.gms.auth.api.signin.internal.zzb.zzafx(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.zzb.loadInBackground(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
这是完整的日志:
UncaughtException: java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:142)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.util.ConcurrentModificationException
at java.util.WeakHashMap$HashIterator.next(WeakHashMap.java:165)
at com.google.android.gms.auth.api.signin.internal.zzb.zzafx(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.zzb.loadInBackground(Unknown Source)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:296)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:54)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:42)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:128)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818) `11-11 00:35:53.023 11247-11903/com.example.package E/AndroidRuntime: FATAL EXCEPTION: ModernAsyncTask …Run Code Online (Sandbox Code Playgroud) android android-asynctask google-play-services onesignal google-signin
在循环的第一行中,我收到错误消息,但我不明白为什么。从我读到的,只有当我迭代一个集合并尝试同时修改它时才会发生这种情况,但事实并非如此。
在代码中,list是 类型ArrayList<Product>。
void mergeSort() {
mergeSort(0, list.size() - 1); //128
}
private void mergeSort(int p, int r) {
if (p < r) {
int q = (p + r) / 2;
mergeSort(p, q); //133
mergeSort(q + 1, r);
merge(p, q, r); //135
}
}
private void merge(int p, int q, int r) {
List<Product> left = list.subList(p, q);
left.add(Product.PLUS_INFINITE);
List<Product> right = list.subList(q + 1, r);
right.add(Product.PLUS_INFINITE);
int i = 0;
int j = 0; …Run Code Online (Sandbox Code Playgroud) OnDragListener:
@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_ENTERED:
switch (v.getId()) {
case R.id.delete_zone: {
addToShowCaseZone.setImageDrawable(getResources().getDrawable(R.drawable.showcase_2));
inAddToShowcasesZone = true;
break;
}
case MagazineGridAdapter.ID: {
enteredView = v;
break;
}
}
return false;
case DragEvent.ACTION_DRAG_EXITED: {
switch (v.getId()) {
case R.id.delete_zone: {
addToShowCaseZone.setImageDrawable(getResources().getDrawable(R.drawable.showcase_1));
inAddToShowcasesZone = false;
break;
}
case MagazineGridAdapter.ID: {
enteredView = null;
break;
}
}
return true;
}
case DragEvent.ACTION_DRAG_STARTED:
return true;
case DragEvent.ACTION_DRAG_LOCATION:
return false;
case DragEvent.ACTION_DROP: {
if (inAddToShowcasesZone) {
final int …Run Code Online (Sandbox Code Playgroud) 我使用 Stack 和 StringBuilder 类编写了用于字符串反转的代码。我注意到这段代码中的 'foreach' 循环会生成 java.util.ConcurrentModificationException,但通常的 'for' 循环不会。所以为什么?
public static String reverse(String str)
{
Stack<Character> stack = new Stack<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++)
stack.push(str.toCharArray()[i]);
}
for (Character c: stack) // generates an exception
{
sb.append(stack.pop());
}
return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)
我期望一个反转的字符串,但发生了 ConcurrentModificationException。