Guava apiを使用して、リストから重複を削除するにはどうすればよいですか?
現在、私はこれに従っています:
private List<T> removeDuplicate(List<T> list){
return new ArrayList<T>(new LinkedHashSet<T>(list));
}
おそらく最も効率的な方法はImmutableSet.copyOf(list).asList()
、重複を排除し、反復順序を維持する です。
(ただし、 を使用した実装LinkedHashSet
はほぼ同じくらい効率的であり、コレクションに実際に null が必要な場合でも、null でスローされることはありません。)
Louis の回答はその単純さから気に入っていますが (2 回の完全な反復を必要としない唯一の回答であるため)、残念ながら現実の世界では、実際に発生する状況に遭遇することがよくnull
あります。少し長い null セーフ バージョンを次に示します。
ImmutableSet.copyOf(
Iterables.filter(
list, Predicates.not(Predicates.isNull()))).asList();
または、静的インポートの場合:
copyOf(filter(list, not(isNull()))).asList();
もちろん、すべてのnull
値がリストから失われることに注意する必要があります。
ジェネリック述語付き
class DuplicateRemover<T> implements Predicate<T> {
private final Set<T> set = new HashSet<>();
@Override
public boolean apply(T input) {
boolean flag = set.contains(input);
if (!flag) {
set.add(input);
}
return !flag;
}
}
グアバを任意の価格で使用したい場合は、
return new ArrayList<T>(HashMultiSet<T>.create(list).elementSet())
上記のOPで通常行われるタスクを実行するために使用することは本当にお勧めしません-通常のJavaプログラマーにとっては読みにくく、(おそらく)効率が低下し(Linked)HashMultiSet
ます。ArrayList
(Linked)HashSet
代わりに、少なくとも次のような静的ファクトリ コンストラクタを使用して、これらすべてnewArrayList
をnewLinkedHashSet
回避します<T>
。
private static <T> List<T> removeDuplicate(final List<T> list) {
return Lists.newArrayList(Sets.newLinkedHashSet(list));
}
ただし、 null を回避し、不変のコレクションを使用することで、より「グアバの方法」でそれを行うことができます。
したがって、コレクションに null 要素を含めることができない場合は、変更可能で効率の悪いものではなく、変更不可のセットを使用することをお勧めします。
private static <T> List<T> removeDuplicate(final List<T> list) {
return Lists.newArrayList(ImmutableSet.copyOf(list));
}
まだオブジェクトを 2 回コピーしているため、完全に不変であり、メソッド シグネチャを return に変更することを検討してImmutableList
ください。
private static <T> ImmutableList<T> removeDuplicate(final List<T> list) {
return ImmutableSet.copyOf(list).asList();
}
ImmutableCollection.asList()
ビューを返すため、この方法ではコピーが 1 回だけ行われます。
Guava の MultiSet API を試して重複を削除できます。リストを追加してセットを実行し、count メソッドを使用するだけです。