2017-11-14 20 views
1

次のコードでは、最初の "forループ"でArrayListからarraylistのヌルまたはサイズが0の項目を削除したいとします。最初のループを実行した後、再び私は2番目のループを持っています。 2番目のループでは、nullまたはitemsのサイズがゼロの項目が含まれているかどうかをテストしました。最初のループで消去しますが、ArrayList BSにはリストから削除された項目が含まれています。ArrayListから項目を削除する<ArrayList<T> >>

ArrayList<ArrayList<Record>> BS = new ArrayList<>(); 
. 
.// some codes 
. 

for (int j = 0; j < BS.size(); j++) { 
    if(BS.get(j) == null || BS.get(j).size() == 0){ 
     BS.remove(j); 
    } 
} 


for (int j = 0; j < BS.size(); j++) { 
    if(BS.get(j) == null || BS.get(j).size() == 0){ 
      System.out.println("Again, fall into if condition"); 
    } 
} 

答えて

3

ここで問題になっているのは、削除したアイテムの直後にアイテムをチェックしないということです。

いずれか:

BS.removeIf(a -> a == null || a.isEmpty()); 

または逆にリストを反復:

for (int j = BS.size() - 1; j >= 0; j--) { ... } 

またはIteratorを使用し、remove()方法を使用します。効率的に多くの要素を削除する方法を知るために最適化されているよう

Iterator<? extends List<Record>> it = BS.iterator(); 
while (it.hasNext()) { 
    List<Record> list = it.next(); 
    if (list == 0 || list.isEmpty()) it.remove(); 
} 

removeIfは、最善のアプローチです:ArrayListの最後の要素以外のものを削除すると、内部に沿ってシフトさせることが大きなインデックスを持つすべての要素が必要です単純にremoveを呼び出すだけで要素を削除することは、時間の複雑さにおいて二次的なものになります。

ただし、Java 8以降でのみ使用できます。 (Javaの以前のバージョンでは、効率的な削除を非常に簡単に実装できますが、これはもう少しの作業です)。

0

問題は、アイテムが削除されたときに、そのアイテムが削除されないことです。そのためには、アイテムを削除するときにインデックスを減らす必要があります。

以下のように変更してください。配列から項目を削除する場合は

ArrayList<ArrayList<Record>> BS = new ArrayList<>(); 
. 
.// some codes 
. 

for (int j = 0; j < BS.size(); j++) { 
    if(BS.get(j) == null || BS.get(j).size() == 0){ 
     BS.remove(j); 
     j--; 
    } 
} 
1

は、通常、あなたのインデックスが1つの項目、削除を行うたびにジャンプしますotherwwise、最初の1に最後の項目から行きたいです。

これは、アイテムを削除すると、残りのアイテムが1つの位置、つまり位置「j + 1」から位置jに移動するためです。次のループでは、項目jをスキップします(これは前のループでj + 1の位置にあった項目です)。

これを試してみてください:

for (int j = BS.size() - 1; j >= 0; j--) { 
    if(BS.get(j) == null || BS.get(j).size() == 0){ 
     BS.remove(j); 
    } 
} 
関連する問題