相关疑难解决方法(0)

迭代集合,在循环中删除对象时避免使用ConcurrentModificationException

我们都知道你不能这样做:

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.

java iteration collections

1158
推荐指数
12
解决办法
46万
查看次数

什么是堆栈跟踪,如何使用它来调试应用程序错误?

有时,当我运行我的应用程序时,它会给我一个错误,如下所示:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
Run Code Online (Sandbox Code Playgroud)

人们将此称为"堆栈跟踪".什么是堆栈跟踪?有什么能告诉我程序中发生的错误?


关于这个问题 - 我经常看到一个问题,一个新手程序员"得到一个错误",他们只是粘贴他们的堆栈跟踪和一些随机的代码块,而不了解堆栈跟踪是什么或如何使用它.这个问题旨在作为新手程序员的参考,他们可能需要帮助来理解堆栈跟踪的价值.

java debugging stack-trace

622
推荐指数
7
解决办法
38万
查看次数

在Java中迭代列表的方法

对于Java语言有些新意,我试图让自己熟悉一个可能遍历列表(或者可能是其他集合)以及每个集合的优点或缺点的所有方法(或者至少是非病态方法).

给定一个List<E> list对象,我知道以下循环所有元素的方法:

基本 循环(当然,还有就是相当于while/ do while循环以及)

// Not recommended (see below)!
for (int i = 0; i < list.size(); i++) {
    E element = list.get(i);
    // 1 - can call methods of element
    // 2 - can use 'i' to make index-based calls to methods of list

    // ...
}
Run Code Online (Sandbox Code Playgroud)

注意:正如@a​​marseillan指出的那样,这种形式对于迭代Lists来说是一个糟糕的选择,因为该get方法的实际实现可能不如使用时那样有效Iterator.例如,LinkedList实现必须遍历i之前的所有元素以获得第i个元素.

在上面的例子中,List实现没有办法"保存它的位置"以使未来的迭代更有效.因为ArrayList它并不重要,因为复杂性/成本get是恒定时间(O(1)),而a LinkedList是它与列表的大小(O(n))成比例.

有关内置Collections实现的计算复杂性的更多信息,请查看此问题 …

java iteration collections loops

543
推荐指数
6
解决办法
87万
查看次数

为什么我在这个例子中没有得到java.util.ConcurrentModificationException?

注意:我知道这个Iterator#remove()方法.

在下面的代码示例中,我不明白为什么List.removein main方法抛出ConcurrentModificationException,而不是remove方法中.

public class RemoveListElementDemo {    
    private static final List<Integer> integerList;

    static {
        integerList = new ArrayList<Integer>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
    }

    public static void remove(Integer toRemove) {
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }

    public static void main(String... args) {                
        remove(Integer.valueOf(2));

        Integer toRemove = Integer.valueOf(3);
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

java foreach list concurrentmodification

173
推荐指数
5
解决办法
27万
查看次数

并发修改例外

我有这段小代码,它给了我并发修改异常.我无法理解为什么我一直得到它,即使我没有看到任何同时进行的修改.

import java.util.*;

public class SomeClass {
    public static void main(String[] args) {
        List<String> s = new ArrayList<>();
        ListIterator<String> it = s.listIterator();

        for (String a : args)
            s.add(a);

        if (it.hasNext())
            String item = it.next();

        System.out.println(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

java concurrentmodification

43
推荐指数
5
解决办法
7万
查看次数

为什么这段代码不会抛出ConcurrentModificationException?

为什么这段代码没有抛出ConcurrentModificationException?它修改了一段Collection时间迭代它,而不使用Iterator.remove()方法,这是唯一安全的删除方法.

List<String> strings = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (String string : strings)
    if ("B".equals(string))
        strings.remove("B");
System.out.println(strings);
Run Code Online (Sandbox Code Playgroud)

如果我ArrayList用a 替换,我会得到相同的结果LinkedList.但是,如果我将列表更改为("A", "B", "C", "D)或只是("A", "B")按预期获得异常.到底是怎么回事?我正在使用,jdk1.8.0_25如果这是相关的.

编辑

我找到了以下链接

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078

相关部分是

天真的解决方案是在AbstractList中为hasNext添加编码检查,但这会使编纂检查的成本增加一倍.事实证明,仅在最后一次迭代时进行测试就足够了,这几乎不会增加成本.换句话说,hasNext的当前实现:

    public boolean hasNext() {
        return nextIndex() < size;
    }
Run Code Online (Sandbox Code Playgroud)

被此实现取代:

    public boolean hasNext() {
        if (cursor != size())
            return true;
        checkForComodification();
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

由于Sun内部监管机构拒绝了此项更改,因此不会进行此更改.正式裁决表明,这一变化"已证明可能对现有代码产生重大的兼容性影响." ("兼容性影响"是修复程序有可能用ConcurrentModificationException替换静默不当行为.)

java

25
推荐指数
2
解决办法
1496
查看次数

子列表抛出的ConcurrentModificationException

我有非常简单的代码:

    List<String> list = new ArrayList<String>();
    String a = "a";
    String b = "b";
    String c = "c";
    String d = "d";

    list.add(a);
    list.add(b);
    list.add(c);

    List<String> backedList = list.subList(0, 2);
    list.add(0, d); 
    System.out.println("2b: " + backedList);
Run Code Online (Sandbox Code Playgroud)

我通过list.add(0,d)得到ConcurrentModificationException异常.所以一般来说,这是因为sublist().我很困惑,因为在sublist()的情况下,文档说:

返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然.

你能解释一下捕获的位置吗?

java list

18
推荐指数
2
解决办法
5678
查看次数

Collection根据Collection的内容抛出或不抛出ConcurrentModificationException

以下Java代码ConcurrentModificationException按预期抛出:

public class Evil
{
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        c.add("lalala");
        c.add("sososo");
        c.add("ahaaha");
        removeLalala(c);
        System.err.println(c);
    }
    private static void removeLalala(Collection<String> c) 
    {
        for (Iterator<String> i = c.iterator(); i.hasNext();) {
            String s = i.next();
            if(s.equals("lalala")) {
                c.remove(s);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是下面的示例(仅在内容中有所不同)Collection执行时没有任何异常:

public class Evil {
    public static void main(String[] args) 
    {
        Collection<String> c = new ArrayList<String>();
        c.add("lalala");
        c.add("lalala");
        removeLalala(c);
        System.err.println(c);
    }
    private static void removeLalala(Collection<String> c) {
        for (Iterator<String> i …
Run Code Online (Sandbox Code Playgroud)

java concurrentmodification

17
推荐指数
1
解决办法
1050
查看次数

为什么列表的反向子列表的List.addAll导致ConcurrentModificationException

我一直在尝试获取列表子列表,将其反转,然后将反转的列表放回起始位置。例如,假设我们拥有列表[1, 2, 3, 4, 5, 6],然后从索引2反转到索引4将得到[1, 2, 5, 4, 3, 6]

我为此编写了一些代码,但是ConcurrentModificationException每次都给出一个代码(除非startIndex == endIndex)。下面提供了一个最小的可重现示例:

int startIndex = 2;
int endIndex = 4;
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);

List<Integer> toReverse = list.subList(startIndex, endIndex+1);
Collections.reverse(toReverse);
list.removeAll(toReverse);
list.addAll(startIndex, toReverse);
Run Code Online (Sandbox Code Playgroud)

异常线程“main” java.util.ConcurrentModificationException
在java.util.ArrayList中的$ SubList.checkForComodification(来源不明)
在java.util.ArrayList的$ SubList.size(来源不明)在
java.util.AbstractCollection.toArray(来源不明)在 test.ConcurrentExample.main(ConcurrentExample.java:64)处
java.util.ArrayList.addAll(Unknown Source

错误所指的实际行是list.addAll(startIndex, toReverse);

我不确定是什么问题,因为迭代过程中似乎没有任何变化。如果有人能解释为什么会这样和/或如何解决它,将不胜感激。

java collections arraylist concurrentmodification

16
推荐指数
2
解决办法
145
查看次数

尽管使用synchronized,ConcurrentModificationException

 public synchronized X getAnotherX(){ 
  if(iterator.hasNext()){
   X b = iterator.next();
   String name = b.getInputFileName();
  ...
   return b;
  }
  else{return null;}
 }
Run Code Online (Sandbox Code Playgroud)

尽管声明头中的synchronized语句,我仍然在我使用iterator.next()的行中得到一个ConcurrentModificationException异常; 什么错了?

java concurrency iterator

15
推荐指数
2
解决办法
2万
查看次数