Stream
Java 8 では、各オブジェクトのプロパティの一意性をチェックすることで、APIを使用してコレクションをフィルター処理するにはどうすればよいですか?
たとえば、Person
オブジェクトのリストがあり、同じ名前の人を削除したい場合、
persons.stream().distinct();
オブジェクトのデフォルトの等価性チェックを使用するのでPerson
、次のようなものが必要です。
persons.stream().distinct(p -> p.getName());
残念ながら、このdistinct()
メソッドにはそのようなオーバーロードはありません。クラス内の等価性チェックを変更せずに、Person
これを簡潔に行うことは可能ですか?
ベストアンサー1
distinct
をステートフル フィルタとします。以下は、以前に見たものに関する状態を維持し、指定された要素が初めて表示されたかどうかを返す述語を返す関数です。
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
次のように記述できます。
persons.stream().filter(distinctByKey(Person::getName))
ストリームが順序付けられ、並列で実行される場合、最初の要素ではなく、重複の中から任意のdistinct()
要素が保持されることに注意してください。
(これは本質的に私の答えこの質問に対して:任意のキーに対する Java Lambda Stream Distinct() ?)