List.remove奇怪的行为 [英] List.remove strange behaviour

查看:53
本文介绍了List.remove奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:此问题不可重复:为什么我没有得到Java?在这个示例中是.util.ConcurrentModificationException?.问题是,为什么未抛出异常 .

Note: Not a duplicate of this question: Why am I not getting a java.util.ConcurrentModificationException in this example?. The question is, why the exception is not being thrown.

如果我们在 List< String> 上使用 foreach 并尝试从中删除任何元素,那么它将抛出 java.util.ConcurrentModificationException ,但是为什么下面的代码不会引发相同的异常,也不会处理 User 的第二个对象?

If we use foreach on List<String> and try to remove any element from it then it throws java.util.ConcurrentModificationException but why following code is not throwing the same exception and also not processing 2nd object of User?

public class Common {

    public static void main(String[] args) {
        User user1 = new User();
        user1.setFirstname("Vicky");
        user1.setLastname("Thakor");

        User user2 = new User();
        user2.setFirstname("Chirag");
        user2.setLastname("Thakor");

        List<User> listUser = new ArrayList<User>();
        listUser.add(user1);
        listUser.add(user2);

        int count = 0;
        for (User user : listUser) {
            System.out.println(count + ":" + user.getFirstname()+" "+ user.getLastname());
            count++;
            listUser.remove(user);
        }
    }
}

输出为:

0:Vicky Thakor

0:Vicky Thakor

推荐答案

尽管问题并非完全相同,但链接的问题:

Although the question is not an exact duplicate, the linked question: Why am I not getting a java.util.ConcurrentModificationException in this example? contains the answer.

在调用迭代器的 next()方法时进行检查是否抛出异常,但这仅在 hasNext()返回 true .在您的情况下,当列表包含两个元素并且您在第一次迭代中删除了第一个条件时:

The check that verifies whether to throw the exception is made when the next() method of the iterator has called, but this happens only if hasNext() returns true. In your case, when the list has two elements and you remove the first one in the first iteration the condition:

public boolean hasNext() {
        return cursor != size(); // 1 != 1 after first iteration
}

偶然是 false ,因为 cursor 位于 1 ,而这正是 size()所在的位置片刻.因此,不会调用 next(),并且不会引发异常.

is accidentally false, because cursor is at 1 and that's what size() is, at the moment. So next() is not called, and the exception is not being thrown.

添加第三个元素:

listUser.add(user2);

,将引发异常.但是,您不应依赖该行为,因为作为文档解释,并不能保证:

and the exception will be thrown. However, you should not rely on that behavior, because, as the documentation explains, it is not guaranteed:

请注意,不能保证快速故障行为,因为通常来说,在存在不同步的并发修改的情况下,不可能做出任何严格的保证.快速失败操作会尽最大努力抛出ConcurrentModificationException.因此,编写依赖于此异常的程序的正确性是错误的:ConcurrentModificationException应该仅用于检测错误.

Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

这篇关于List.remove奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆