ArrayList
特定の基準を満たしている場合、Javaから要素を削除したいと思います。
すなわち:
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();
}
Iterator#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;
行は、反復中に使用すると例外がスローされない理由です。
イテレータを使用する必要はありません。Java 8 (ストリーミングおよびフィルタリング機能とラムダ) を使用すると、1 行で実現できます。たとえば。指定した操作を実行するために必要なコードは次のとおりです。
pulseArray = pulseArray.stream().filter(pulse -> pulse != null).collect(Collectors.toList());
同じリストから要素を削除すると、インデックスが乱れます。以下のように少し違った方法で試してください。
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
}
}
イテレータを使用する代わりに、Guavaコレクション ライブラリを使用できます。これには、より機能的であるという利点があります(そのようなことに興味がある場合):
Predicate<Pulse> hasCurrent = new Predicate<Pulse>() {
@Override public boolean apply(Pulse input) {
return (input.getCurrent() != null);
}
};
pulseArray = Lists.newArrayList(Collections2.filter(pulseArray, hasCurrent));
コレクションのメソッドを使用して反復しているコレクションを変更することはできません。ただし、一部の反復子 ( ArrayList
s の反復子を含む) は、反復する順序でメソッドを削除できるメソッドをサポートしremove()
ています。
Iterator<Pulse> iterator = pulseArray.iterator();
while (iterator.hasNext()) {
Pulse p = iterator.next();
if (p.getCurrent() == null) {
iterator.remove();
}
}
Iterator を使用すると、arraylist を反復処理しながらリストを変更することができます。