理由はありますか
Lists.transform()
しかし、
Lists.filter()
?
リストを正しくフィルタリングするにはどうすればよいですか?使用できます
new ArrayList(Collection2.filter())
もちろんですが、この方法では、正しく理解していれば、注文が同じであるとは限りません。
理由はありますか
Lists.transform()
しかし、
Lists.filter()
?
リストを正しくフィルタリングするにはどうすればよいですか?使用できます
new ArrayList(Collection2.filter())
もちろんですが、この方法では、正しく理解していれば、注文が同じであるとは限りません。
List.newArrayList(Iterables.filter(...))
、と言うべきLists.newArrayList(Iterables.filter(...))
です。
回答:
返されたリストビューの#get(index)など、危険な多数の低速メソッドが公開されるため、実装されませんでした(パフォーマンスのバグを招きます)。また、ListIteratorも実装するのが面倒です(パッチを提出しましたがをカバーするために数年前に)。
インデックス付きのメソッドは、フィルター処理されたリストビューでは効率的ではないため、フィルター処理されたIterableを使用することをお勧めします。
filter
一貫しているのかどうか(意味の行動と一緒に)ビューを意味しIterables.filter
、Sets.filter
などがあるのでIterables.filter
簡単でコンバインcopyOf
の任意のImmutableCollection
、私が見つけ、この優れた設計のトレードオフ(のような余分なメソッド&名、を考え出す対filteredCopy
またはその他もろもろ、単純なユーティリティの組み合わせの場合)。
使用できます Iterables.filter
。これにより、確実に順序が維持されます。
新しいリストを作成すると、要素(もちろん参照のみ)がコピーされることに注意してください。そのため、元のリストへのライブビューにはなりません。ビューの作成にはかなり注意が必要です。次の状況を考慮してください。
Predicate<StringBuilder> predicate =
/* predicate returning whether the builder is empty */
List<StringBuilder> builders = Lists.newArrayList();
List<StringBuilder> view = Lists.filter(builders, predicate);
for (int i = 0; i < 10000; i++) {
builders.add(new StringBuilder());
}
builders.get(8000).append("bar");
StringBuilder firstNonEmpty = view.get(0);
それは、すべてにフィルターを適用して、元のリスト全体を反復処理する必要があります。ビューの存続期間中に述語の一致が変化しないことが必要になる可能性があると思いますが、それでは完全に満足できるものではありません。
(これは単なる推測です、気をつけてください。たぶん、グアバのメンテナの1人が本当の理由でチップインするでしょう:)
Collections2.filter.iterator
を呼び出すだけなIterables.filter
ので、結果は同じです。
Iterables.filter
、わかりやすくするためにバージョンを使用します。
view.size()
コードの後半で必要な場合を除いて:)
new List(Collection2.filter())
もちろん使用することもできますが、この方法では、注文が同じであるとは限りません。
これは真実ではありません。 Collections2.filter()
は遅延評価された関数です。フィルタリングされたバージョンへのアクセスを開始するまで、実際にはコレクションをフィルタリングしません。たとえば、フィルター処理されたバージョンを反復処理すると、フィルター処理された要素は、元のコレクションと同じ順序でイテレーターからポップアウトされます(明らかにフィルター処理された要素を除く)。
おそらく、事前にフィルタリングを実行し、その結果を何らかの形式の任意の順序付けられていないコレクションにダンプすると考えていたのかもしれませんが、そうではありません。
したがって、の出力をCollections2.filter()
新しいリストへの入力として使用すると、元の順序が保持されます。
静的インポート(およびLists.newArrayList
関数)を使用すると、かなり簡潔になります。
List filteredList = newArrayList(filter(originalList, predicate));
注しばらくはことをCollections2.filter
熱心に基になるコレクションを反復処理しません、Lists.newArrayList
します-それは、フィルター処理されたコレクションのすべての要素を抽出し、新しいにそれらをコピーしますArrayList
。
List filteredList = newArrayList(filter(originalList, new Predicate<T>() { @Override public boolean apply(T input) { return (...); } }));
またはすなわち。List filteredList = newArrayList(filter(originalList, Predicates.notNull()));
Jonが述べたように、Iterables.filter(..)
またはCollections2.filter(..)
を使用できます。ライブビューが必要ない場合は、ImmutableList.copyOf(Iterables.filter(..))
またはLists.newArrayList( Iterables.filter(..))
を使用できます。はい、順序は維持されます。
なぜその部分に
本当に興味がある場合は、https://github.com/google/guava/issues/505にアクセスして詳細を確認できます。