首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要帮助修改基于比较值的列表(ConcurrentModification)

需要帮助修改基于比较值的列表(ConcurrentModification)
EN

Stack Overflow用户
提问于 2015-07-07 17:12:26
回答 4查看 37关注 0票数 0

我正在试图看看有什么可能(不要告诉我没有,这是我的失败的项目)通过一个点的安排和他们的距离。

代码语言:javascript
复制
for (Point p1 : results) {
    remove.clear();
    for (Point p2 : results) {
        if (Math.sqrt(
            Math.pow(p1.getX() - p2.getX(), 2)
            + Math.pow(p1.getY() - p2.getY(), 2)
        ) % 1 > 0) {
            results.remove(p2);
        }
    }
}

基本上,我试着检查两个点是否有一个整数距离,如果没有,将其从集合中移除,并对所有的点(剩下的)执行此操作。

然而,我得到了一个ConcurrentModificationException,我不知道如何重构它以完成相同的任务,而不只是以另一种方式引发错误。

有什么办法可以解决这个问题吗?还是它只是Java的一个限制?

编辑:虽然重复的建议链接提供洞察力,但答案的焦点放在单个循环上有多余的泊位,是不适用的。如果这个问题是重复的,它的前提是使用一个Iterator只是答案。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-07-07 17:26:54

一些Collection实现使用“快速失败”迭代器。当直接从Collection中删除项(使用Collection#remove)时,迭代它将导致该异常。

增强的for-循环使用集合的迭代器遍历集合.

您可以将增强循环更改为正则循环:

代码语言:javascript
复制
for(int i = 0; i < results.size(); i++) {
    for(int j = 0; j < results.size(); j++) {
    Point result = results.get(j);
        if(...) {
            //results.remove(j); or
            //results.remove(result);
        }
    }
}

正如注释中提到的,这将不适用于Set。在这种情况下,您只需保留对集合的迭代器的引用,并使用它删除项:

代码语言:javascript
复制
Iterator<Point> firstIter = results.iterator();
while(firstIter.hasNext()) {
    Point p1 = iterator.next();

    Iterator<Point> secondIter = results.iterator();
    while(secondIter.hasNext()) {
        Point p2 = secondIter.next();

        if(...) {
            secondIter.remove();
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2015-07-07 17:22:06

你可以这样做:

代码语言:javascript
复制
Iterator<Point> iterator = results.iterator();
while (iterator.hasNext()) {
  Point p1 = iterator.next();
  boolean shouldBeRemoved = false;
  for(Point p2 : results) {
    if (p2 != p1 && (Math.sqrt(Math.pow(p1.getX() - p2.getX(), 2)
                             + Math.pow(p1.getY() - p2.getY(), 2))
                     % 1 > 0)) {
      shouldBeRemoved = true;
      break;
    }
  }
  if (shouldBeRemoved) {
    iterator.remove();
  }
}

区别是p1显然被移除而不是p2,但是由于我们在这里处理的是一个Set .

将其从中删除

..。点菜并不重要,对吧?

票数 1
EN

Stack Overflow用户

发布于 2015-07-07 17:25:54

这似乎正在发生,因为您正在尝试删除相同的Point结构。考虑第一点的情况。p1和p2都引用了结果中的第一点。p1和p2之间的距离为零,因为它们指的是同一点。然后,您将尝试删除实际上是p2本身的p1。请参阅链接http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html,了解为什么即使在一个线程试图访问和修改某些结构时也可以获得此异常。

您可以修改上述代码如下:

代码语言:javascript
复制
boolean[] if_deleted = new boolean[results.size()];

for (int i = 0; i < results.size(); ++i) {
    if_deleted[i] = false;
}

for (int i = 0; i < results.size(); ++i){
    for(int j = i + 1; j < results.size(); ++j)
            Point p1 = (Point)results.get(i);
            Point p2 = (Point)results.get(j);
            if (!if_deleted[i] && !if_deleted[j]) { 
                if (Math.sqrt(
                    Math.pow(p1.getX() - p2.getX(), 2)
                            +
                            Math.pow(p1.getY() - p2.getY(), 2))
                    % 1 > 0){
                        if_deleted[j] = true;
                        results.remove(p2);
                }
            }    
    }
}

for (int i = 0; i < results.size(); ++i) {
    if (if_deleted[i]) {
        results.remove(i);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31275182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档