Чи є колектор, який збирає набір, що зберігає замовлення?


107

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


Я не думаю, що таке існує. Я знаю, що мені теж потрібен був, і мені довелося написати своє.
пробіл

Було б SortedSetпрацювати? Якщо ні, звичайним способом є шлях.
AntonH

@AntonH Ні, я вважаю за краще операції O (1) перед O (log n).
гвласов

1
Я опублікував цей код, він не є саме тим, що вам потрібно, але це може привести вас до роботи.
пробіл

Відповіді:


203

Ви можете використовувати 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що в моєму випадку Гуава буде ще кращим. Будь-які ідеї, як я можу зробити колекціонера, який збирає ImmutableSet? Його приклади побудовані з ImmutableSet.Builderяких не Collection, так що я не можу зрозуміти, як ви могли б зробити Supplierдля Collectors.toCollection()цього випадку.
гвласов

@Susei Я спробую розібратися в цьому. Альтернативою було б повернення немодифікованого набору. Напр .:Set<String> linkedSet = list.stream().collect(Collectors.toCollection(LinkedHashSet::new)); linkedSet = Collections.unmodifiableSet(linkedSet);
Алексіс К.

@Susei Найближчий я знайшов: Set<String> set = list.stream().collect( ImmutableSet.Builder<String>::new, ImmutableSet.Builder<String>::add, (builder1, builder2) -> builder1.addAll(builder2.build())).build();Не впевнений, що це кращий підхід, загортаючи отриманий набір Collections.unmodifiableSet.
Олексій К.

Ось спеціальний питання , так як це вже не по темі (і для отримання додаткової репутації для великих відповідей, звичайно): stackoverflow.com/questions/27612165 / ...
gvlasov
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.