Czy istnieje Kolekcjoner, który zbiera do zestawu zachowującego zamówienia?


107

Collectors.toSet()nie zachowuje porządku. Mógłbym zamiast tego użyć List, ale chcę wskazać, że wynikowa kolekcja nie pozwala na powielanie elementów, a dokładnie do tego Setsłuży interfejs.


Myślę, że coś takiego nie istnieje. Wiem, że też go potrzebowałem i musiałem napisać własny.
— markspace

Czy SortedSetzadziała? Jeśli nie, wybór należy do niestandardowych.
— AntonH

@AntonH Nie, wolałbym operacje O (1) zamiast O (log n).
— gvlasov

1
Opublikowałem ten kod, nie jest to dokładnie to, czego potrzebujesz, ale może ci zacząć.
— markspace

Odpowiedzi:


203

Możesz użyć toCollectioni podać konkretną instancję zestawu, który chcesz. Na przykład, jeśli chcesz zachować zamówienie reklamowe:

Set<MyClass> set = myStream.collect(Collectors.toCollection(LinkedHashSet::new));

Na przykład:

public class Test {    
    public static final void main(String[] args) {
        List<String> list = Arrays.asList("b", "c", "a");

        Set<String> linkedSet = 
            list.stream().collect(Collectors.toCollection(LinkedHashSet::new));

        Set<String> collectorToSet = 
            list.stream().collect(Collectors.toSet());

        System.out.println(linkedSet); //[b, c, a]
        System.out.println(collectorToSet); //[a, b, c]
    }
}

Fajnie, dokładnie tego potrzebuję, ale myślę, ImmutableSetże w moim przypadku guawa byłaby jeszcze lepsza. Jakieś pomysły, jak mogę zrobić kolekcjonera, który zbiera ImmutableSet? Jego instancje są zbudowane z rozszerzeniem, ImmutableSet.Builderktóre nie jest a Collection, więc nie mogę dowiedzieć się, jak w takim przypadku utworzyłbyś Supplierfor Collectors.toCollection().
— gvlasov

@Susei Spróbuję się temu przyjrzeć. Alternatywą byłoby zwrócenie niemodyfikowalnego zestawu. Np .:Set<String> linkedSet = list.stream().collect(Collectors.toCollection(LinkedHashSet::new)); linkedSet = Collections.unmodifiableSet(linkedSet);
— Alexis C.

@Susei Najbliższe, które znalazłem: Set<String> set = list.stream().collect( ImmutableSet.Builder<String>::new, ImmutableSet.Builder<String>::add, (builder1, builder2) -> builder1.addAll(builder2.build())).build();Nie jestem pewien, czy jest to lepsze podejście, zawijając wynikowy zestaw Collections.unmodifiableSet.
— Alexis C.

Oto dedykowane pytanie, ponieważ jest już poza tematem (i oczywiście dla większej liczby przedstawicieli za świetne odpowiedzi): stackoverflow.com/questions/27612165/ ...
— gvlasov
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.