-1

ArrayList 内のすべての値を他のすべての値と照合して、値が近すぎる場合は 1 つ削除しようとしています。次に例を示します。

// 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

同時変更や範囲外の例外を避けるために、別の方法で行うことをお勧めします。

反復中にコレクションから何かを削除することは危険な考えです (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;
于 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 に答える