Есть ли коллектор, который собирает набор для сохранения порядка?

108

Collectors.toSet()не сохраняет порядок. Вместо этого я мог бы использовать списки, но хочу указать, что результирующая коллекция не допускает дублирования элементов, а именно для этого и предназначен Setинтерфейс.

гвласов
источник
Я не думаю, что такое существует. Я знаю, что мне тоже нужен был такой, и мне пришлось написать свой собственный.
markspace
Будет SortedSetработать? Если нет, то можно пойти на заказ.
AntonH
@AntonH Нет, я бы предпочел O (1) операции O (log n).
gvlasov
1
Я опубликовал этот код, это не совсем то, что вам нужно, но может помочь вам начать.
markspace

Ответы:

204

Вы можете использовать toCollectionи предоставить конкретный экземпляр того набора, который хотите. Например, если вы хотите сохранить порядок размещения:

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

Например:

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]
    }
}
Алексис С.
источник
Хорошо, это именно то, что мне нужно, но я думаю, ImmutableSetчто в моем случае Guava будет даже лучше. Есть идеи, как сделать коллекционера, который собирает ImmutableSet? Его экземпляры построены с использованием, ImmutableSet.Builderкоторое не является a Collection, поэтому я не могу понять, как вы могли бы создать Supplierfor Collectors.toCollection()в этом случае.
gvlasov
@Susei Я постараюсь разобраться в этом. Альтернативой может быть возврат неизменяемого набора. Пример:Set<String> linkedSet = list.stream().collect(Collectors.toCollection(LinkedHashSet::new)); linkedSet = Collections.unmodifiableSet(linkedSet);
Alexis C.
@Susei Самое близкое, что я нашел: Set<String> set = list.stream().collect( ImmutableSet.Builder<String>::new, ImmutableSet.Builder<String>::add, (builder1, builder2) -> builder1.addAll(builder2.build())).build();Не уверен, что это лучший подход, заключив полученный набор в Collections.unmodifiableSet.
Alexis C.
Вот специальный вопрос, поскольку он уже не по теме (и, конечно, для получения дополнительных ответов для отличных ответов): stackoverflow.com/questions/27612165/…
gvlasov
безупречный ответ!
Гаурав