迭代ArrayList并检查所有其他元素

时间:2013-01-17 21:50:19

标签: java arraylist compare distance loops

我正在尝试检查ArrayList中的所有值与所有其他值,如果它们的值太近,则删除一个值。这是一个例子:

// make an ArrayList of random numbers
ArrayList<Integer> nums = new ArrayList<Integer>();
for (int i=0; i<25; i++) {
  int rand = int(random(255));
  nums.add(rand);
  println(rand);  
}

// go through all numbers and compare
// (loop backwards to prevent ConcurrentModificationException)
for (int i = nums.size()-1; i >= 0; i--) {
  int current = nums.get(i);
  println("Current #: " + current);

  // how to do this?
  // not sure if there's a faster way that
  // would avoid running through the entire 
  // ArrayList for every element...
  for (Integer other : nums) {
    if (abs(current - other) < 5) {
      nums.remove(current);
    }
  }
}

寻找最干净,最有效的方法。

[为清晰起见而编辑]

2 个答案:

答案 0 :(得分:3)

您最好以不同的方式进行,以避免并发修改和/或超出限制的异常。

在迭代过程中从集合中删除任何东西,这是一个冒险的想法(imho),将其添加到另一个集合中会更安全。

因此,将代码替换为等效代码,但将对象添加到新集合中。

集合是轻量级对象,因此创建它们并不需要太多资源。

最后将原始集合变量分配给新集合。

这样的事情:

        final ArrayList<Integer> nums = new ArrayList<Integer>();
        final ArrayList<Integer> result = new ArrayList<Integer>();
        for (int i = 0; i < 25; i++) {
            final int rand = Double.valueOf(Math.random() * 255).intValue();
            nums.add(rand);
        }
        System.out.println(nums);
        outer: for (Integer current : nums) {
            // result collection is reevaluated here 
            // and is not modified inside the inner for loop
            // so, accessing it is safe
            for (Integer other : result) {
                if (Math.abs(current - other) < 5) {
                    // there is a too close value, do not put, skip the check
                    continue outer;
                }
            }
            // a too close value doesn't exist - add object
            result.add(current);
        }
        // here you may assing new collection to the old reference, uncomment next line
        // nums = results;

答案 1 :(得分:0)

当您从数组中删除并同时迭代它时,您正在获取(并隐藏)大量java.util.ConcurrentModificationExceptionjava.lang.IndexOutOfBoundsException

为了避免你需要使用迭代器:

final ArrayList<Integer> nums = new ArrayList<Integer>();
    for (int i = 0; i < 25; i++) {
        final int rand = Double.valueOf(Math.random() * 255).intValue();
        nums.add(rand);
    }
    System.out.println(nums);

    for (int i = nums.size() - 1; i >= 0; i--) {
        final int current = nums.get(i);
        // println(current);
        try {
            for (final Iterator<Integer> iterator = nums.iterator(); iterator.hasNext();) {
                final Integer other = iterator.next();
                if (Math.abs(current - other) < 5) {
                    iterator.remove();
                    i--;
                }
            }
        } catch (final Exception cme) {
            System.out.println(cme);
        }
    }

    System.out.println(nums);