-1

我正在尝试根据所有其他值检查 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);
    }
  }
}

寻找最干净和最有效的方法来做到这一点。

[为清楚起见编辑]

4

2 回答 2

3

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

在迭代集合时从集合中删除任何内容是一个冒险的想法(恕我直言),将其替换为向另一个集合添加内容要安全得多。

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

集合是轻量级对象,因此创建它们不会占用太多资源。

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

像这样的东西:

        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;
于 2013-01-17T22:29:29.073 回答
0

当您从数组中删除并同时迭代它时,您会得到(并隐藏)很多java.util.ConcurrentModificationExceptionand 。java.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);
于 2013-01-17T22:05:14.243 回答