【问题标题】:Java Loop Arraylist and remove when necessaryJava Loop Arraylist 并在必要时删除
【发布时间】:2012-03-25 18:27:16
【问题描述】:

我有一个带有坐标(经度和纬度)的 ArrayList。我想计算坐标之间的距离。

for(Winkel winkel: winkels){
            Projection projection = mv.getProjection();
            ArrayList<Winkel> cluster = new ArrayList<Winkel>();

            winkels.remove(winkel);

            for(Winkel item: winkels){                      
                //GetLocations
                if(Math.sqrt(Math.pow((point.x - point1.x), 2) + Math.pow((point.y - point1.y), 2)) < 100){
                    cluster.add(item);
                    winkels.remove(item);
                }       
            }
        }

编辑:我编辑了代码。如果我得到第二次到第一次。我收到一个错误:

03-08 10:01:27.419: E/AndroidRuntime(10572): 
 java.lang.RuntimeException: Unable to start activity ComponentInfo{be.oww.app/be.oww.app.WinkelsTabActivity}: 
   java.lang.RuntimeException: Unable to start activity ComponentInfo{be.oww.app/be.oww.app.MapsTabActivitiy}: 
     java.util.ConcurrentModificationException

03-08 10:01:27.419: E/AndroidRuntime(10572):    
 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1821)

...

【问题讨论】:

  • 您可能不太了解 Java 中的 Collection Framework
  • 作为风格点(与您的问题无关),您可能应该在 Winkel 上编写将 X 和 Y 坐标返回为 Doubles 的方法,其中包含代码 Double.parseDouble(item.getCoordinaten().split(",")[0]) * 1E6,这样您就不必重复每次您需要该信息时,该 sn-p。
  • 为什么没有问题的帖子有这么多答案?

标签: java arrays for-loop arraylist while-loop


【解决方案1】:

您可能希望为第二个 while 循环获取第二个迭代器:

 Iterator<Winkel> iItems = winkels.iterator();
 while(iItems.hasNext()){
        Winkel item = iItems.next();

使用您当前的代码,winkel 设置为集合的第一项,然后内部循环从第二项运行到最后一项。这可能不是你想要的。

顺便说一句:- 你可以用 for 循环做同样的事情:

for (Winkel winkel:winkels) {
  Projection projection = mv.getProjection();
  ArrayList<Winkel> cluster = new ArrayList<Winkel>();
  for(Winkel item:winkels){
     Double itemLat = Double.parseDouble(item.getCoordinaten().split(",")[0]) * 1E6;
     // ...
  }
  if(cluster.size()==0){
    // ...
}            

【讨论】:

    【解决方案2】:

    事实上,next() 并没有删除任何东西。 remove() 函数被移除。 next() 只是给你下一个项目。

    如果您不想前进到下一项,请不要调用next(),而是记住变量中的上一个值。

    【讨论】:

      【解决方案3】:

      您不希望在同一个迭代器上有嵌套循环。

      您似乎想将集合中的每个元素与集合中的每个其他元素进行比较。在这种情况下,您的外部循环应该像目前一样在winkels 上使用迭代器。在外循环的主体中,您应该在winkels 上获得一个不同的迭代器,并在内循环中循环第二个迭代器。

      (啊...其他人已经发布了相同的答案)

      如果使用增强的 for 循环,结构会更容易查看:

      for (Winkel winkel : winkels) {
      
          Projection projection = mv.getProjection();
          ArrayList<Winkel> cluster = new ArrayList<Winkel>();
      
          for (Winkel otherWinkel : winkels) {
              // do what you need to compare the two Winkels
              // this will be executed N*N times where N is collection size
          }
      }
      

      (编辑:我似乎在这里克隆了别人的想法)

      【讨论】:

      • 我尝试了您的解决方案。我改变了我的问题。你能看看吗?
      • 啊,是的。当您使用迭代器时,如果基础集合发生更改,它将失败,而不是通过该迭代器的 remove() 方法。在这种情况下,您通过在同一集合上的不同迭代器上调用 remove() 来更改基础集合。你想做一些类似于 user1242756 建议的事情。
      【解决方案4】:

      我不知道你使用的逻辑,但我会这样循环:

      List<Winkel> toRemove = new ArrayList<Winkel>();
      for (int i = 0; i < winkels.size(); i++) {
          Winkel winkel = winkels[i];
          // you don't have to compare a point with itself
          for (int j = i+1; j < winkels.size(); j++) {
              Winkel item = winkels[j];
              // do item stuff here
              if (distance < 100) {
                  toRemove.add(winkel);
                  break;
              }
          }
          // do winkel stuff here
      }
      winkels.removeAll(toRemove); // items are removed after the loop
      

      PS:我认为在迭代期间从列表中删除对象不是一个好主意。

      【讨论】:

      • 删除实际上是我的问题。需要删除这些项目,因为如果 2 点之间的距离较小。对于该坐标,不再需要计算该点与所有其他点之间的距离。
      • 我更新了代码。您可以使用帮助列表来标记要删除的项目。我只是说在迭代期间删除元素不是一个好主意。 :)
      • 在所有元素与所有其他元素进行比较之前,它不会删除所有元素。所以 removeAll 没用吧?
      • 不。这就是'break'语句的用途。您在列表中添加要删除的元素,它将不再进行比较。
      • 实际上,迭代器的remove() 方法设计用于在迭代期间从列表中删除元素。
      【解决方案5】:

      在循环中从集合中删除项目的唯一安全方法是通过迭代器,否则你会遇到麻烦。所以,试试这个:

      Iterator<Winkel> iterator = winkels.iterator();
      while(iterator.hasNext()) {
          Winkel winkel = iterator.next();
          // do something with winkel
          if (condition) {
              iterator.remove(); // removes current winkel from the collection
      

      【讨论】:

        猜你喜欢
        • 2014-03-28
        • 1970-01-01
        • 2020-03-05
        • 2013-03-17
        • 2014-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多