gpt4 book ai didi

java - 有没有办法选择 "unspecified behavior"而不是 ConcurrentModificationException?

转载 作者:行者123 更新时间:2023-11-30 02:40:09 27 4
gpt4 key购买 nike

我知道这样的代码

for ( Object o: collection){
if (condition(i)){
collection.remove(i);
}
}

将抛出 ConcurrentModificationException,我明白为什么:直接修改集合可能会干扰迭代器跟踪其位置的能力,例如,留下对不再是集合一部分的元素的引用。集合,或导致它跳过刚刚添加的集合。对于上面这样的代码,这是一个合理的担忧,但是,我想写一些类似的东西

for (Object o: set){// set is an instance of java.util.LinkedHashSet
if (condition(o)){
set.remove(other(o));
}
}

其中 other(o) 保证在集合的排序中距离 o “远”。在我的特定实现中,它与 o 的距离永远不会少于 47“步”。此外,如果条件(o)为真,则所讨论的循环将保证在到达其他(o)所在位置之前短路。因此,迭代器访问的集合的整个部分与被修改的部分完全解耦。此外,LinkedHashSet 的特殊优势(快速随机访问插入和删除、保证迭代顺序)似乎特别适合这种类型的操作。

我想我的问题是双重的:首先,考虑到上述限制,这样的操作仍然危险吗?我认为可能的唯一方法是提前预加载迭代器值并进行缓存,我认为这会提高许多应用程序的性能,但似乎也会减少许多其他应用程序的性能,因此是一个对于 java.util 中的通用类来说,这是一个奇怪的选择。但也许我的想法是错的。当谈到缓存之类的事情时,我对效率的直觉常常受到怀疑。其次,假设这种事情至少在理论上是安全的,那么除了完全重新实现 LinkedHashSet 或牺牲效率之外,有没有一种方法可以实现这种操作?我可以告诉 Collections 忽略我正在修改 Set 的不同部分这一事实,而照常进行其业务吗?我当前的解决方法是首先将元素添加到中间集合,然后在循环完成后将它们添加到主集合,但这是低效的,因为它必须添加值两次。

最佳答案

抛出 ConcurrentModificationException 是因为您的集合可能无法始终处理删除(或添加)。例如,如果您执行的删除意味着您的 LinkedHashSet 必须减少/增加底层 HashMap 所占用的空间,该怎么办?它必须进行大量更改,这可能会使迭代器变得无用。

您有两个选择:

使用Iterator来迭代元素并删除它们,例如调用 Iterator iter = linkedHashSet.iterator() 获取迭代器,然后通过 iter.remove() 删除元素

使用java.util.concurrent包下可用的并发集合之一,这些集合旨在允许并发修改

This question包含有关使用 Iterator

的详细信息

评论后更新:

您可以使用以下模式来删除您想要删除的元素,而不会导致 ConcurrentModificationException:在循环访问 List 时收集您想要删除的元素。 LinkedHashSet 元素。然后,循环遍历列表中的每个 toBeDeleted 元素并将其从 LinkedHashSet 中删除。

关于java - 有没有办法选择 "unspecified behavior"而不是 ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41995278/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com