2017-06-21 15 views
5

私はこのコードをリストから項目を削除することができますKotlinでリストをインプレースでフィルタリングする方法は? Javaでは

private void filterList(List<Item> items) { 
    Iterator<Item> iterator = items.iterator(); 
    while (iterator.hasNext()) { 
     if (checkItem(iterator.next())) { 
      iterator.remove(); 
     } 
    } 
} 

(すなわち、再作成せずにListにいくつかの項目を削除)Kotlinで同じことを行うためにどのように?

+0

なぜAndroidのタグを使用しMutableListを続行したい場合は? – user7294900

+3

このコードをkotlinファイルにコピーするだけで、IDEが自動的に行います。 – chandil03

答えて

12

ジャストインプレース、それをフィルタリングするために、両方の述語を受け入れ、.retainAll { ... }または.removeAll { ... }を使用:itemsは、そのためのMutableList<T>なければならないことを

items.retainAll { shouldRetain(it) } 

items.removeAll { shouldRemove(it) } 

注意だけでなく、List<T>これはKotlinの読み取り専用リストであり、したがって、変更機能を公開しません(言語リファレンスのCollectionsを参照)。ところで

は、これらの二つの関数は、ランダムアクセスをサポートするリストに効率的に実装されている各項目が除去された後、リストが圧縮されていない(O(N )時間ワーストケース)、および代わりに、アイテムが処理されるときにリスト内で移動され、O(n)時間が与えられます。


そして、あなたは元のリストを変更したくない場合は、あなたが.filter { ... }.filterNot { ... }を使用して保持したい項目のみで分別収集を生成することができ、これは、同様に、読み取り専用List<T>のために動作します:

val filtered = items.filter { shouldRetain(it) } 

val filtered = items.filterNot { shouldRemove(it) } 
+1

これには機能がないと私は驚いたでしょう。標準ライブラリは素晴らしいです。 – zsmb13

+1

あなたは 'removeAll'を意味しましたか?質問では、述語*が渡されたときに項目が削除されるためです。 – Ilya

+0

@Ilya、ありがとう、ちょうど 'checkItem'という名前が私を混乱させました。一定。 – hotkey

2

Kotlinは、きちんとした組み込み関数をたくさん持っています。 filterをここで使用できます。

val filteredItems = items.filter { checkItem(it) } 

残念ながら、リストは再作成されます。このAPIは、余分な変更を避けるために設計されています。

しかし、あなたはまだretainAll方法

items.retainAll { checkItem(it) } 
関連する問題