特定の条件を満たす場合、JavaのArrayList
から要素を削除したいと考えています。特定の条件に基づいてArrayListからオブジェクトを削除する
すなわち:
for (Pulse p : pulseArray) {
if (p.getCurrent() == null) {
pulseArray.remove(p);
}
}
これが動作しない理由を私は理解することができますが、これを行うには良い方法は何ですか?
特定の条件を満たす場合、JavaのArrayList
から要素を削除したいと考えています。特定の条件に基づいてArrayListからオブジェクトを削除する
すなわち:
for (Pulse p : pulseArray) {
if (p.getCurrent() == null) {
pulseArray.remove(p);
}
}
これが動作しない理由を私は理解することができますが、これを行うには良い方法は何ですか?
あなたが反復するIterator
を使用する必要がありますし、(ないリストの)イテレータのremove
機能:
Iterator<Pulse> iter = pulseArray.iterator();
while (iter.hasNext()) {
Pulse p = iter.next();
if (p.getCurrent()==null) iter.remove();
}
それはでを実現していますArrayListのイテレータ。
はこちらArrayList.javaからこの具体的な機能のコードです:あなたが反復しながら、それを使用する場合、それは例外をスローしない理由
765 public void remove() {
766 if (lastRet < 0)
767 throw new IllegalStateException();
768 checkForComodification();
769
770 try {
771 ArrayList.this.remove(lastRet);
772 cursor = lastRet;
773 lastRet = -1;
774 expectedModCount = modCount;
775 } catch (IndexOutOfBoundsException ex) {
776 throw new ConcurrentModificationException();
777 }
778 }
779
780 final void checkForComodification() {
781 if (modCount != expectedModCount)
782 throw new ConcurrentModificationException();
783 }
784 }
expectedModCount = modCount;
線です。
技術的には、イテレータを使用して、enhanced-for-loop _is_です。彼は何をしなければならないかの例を挙げることができますか?また、すべてのイテレータが実際にremoveメソッドを実装するわけではなく、実装されていない例外がスローされることに注意してください。 –
@ Clockwork-Museはい、内部ArrayListのイテレータはそれを実装しています。 –
コレクションのメソッドを使用して、反復処理中のコレクションを変更することはできません。ただし、イテレータ(ArrayList
のイテレータを含む)の中には、イテレートする順序でメソッドを削除できるようにするremove()
メソッドがあります。
Iterator<Pulse> iterator = pulseArray.iterator();
while (iterator.hasNext()) {
Pulse p = iterator.next();
if (p.getCurrent() == null) {
iterator.remove();
}
}
あなたは同じリストから要素を削除するある場合は、インデックスが乱れます。別々に以下のように少しを試してみてください:Iteratorを使用すると、あなたのイテレータを使用する代替としてのArrayListを通じて
、あなたはGuavaコレクションライブラリを使用することができます。 (あなたがそういったことにしている場合)これはfunctional以上であることの利点を持っていない:
Predicate<Pulse> hasCurrent = new Predicate<Pulse>() {
@Override public boolean apply(Pulse input) {
return (input.getCurrent() != null);
}
};
pulseArray = Lists.newArrayList(Collections2.filter(pulseArray, hasCurrent));
を反復しながら、リストを変更する力を与えるだろう
for (int i=0; i < pulseArray.size(); i++) {
Pulse p = (Pulse)pulseArray.get(i);
if (p.getCurrent() == null) {
pulseArray.remove(p);
i--;//decrease the counter by one
}
}
あなたがここに、Collection::removeIf(Predicate filter)を使用することができますが、簡単な例です:
final Collection<Integer> list = new ArrayList<>(Arrays.asList(1, 2));
list.removeIf(value -> value < 2);
System.out.println(list); // outputs "[2]"
これは私のために働く –
これは仕事に失敗するだけでなく、それは仕事をした場合でも、それはひどい性能を持つだろう。これはO(n^2)アルゴリズムです。なぜなら、配列のすべての要素を削除する必要があるからです。最適なアルゴリズムはO(n)です。 –
@MarkByers "配列のすべての要素をチェックする"はO(n)ですが、なぜこれがO(n^2)だと思いますか? – jlordo
@jlordo: 'list.remove(object)'はO(n)操作です。ループしているので、O(n)回実行されます。それはO(n * n)を与える。 –