Existe-t-il un collecteur qui collecte dans un ensemble de conservation des commandes?


107

Collectors.toSet()ne préserve pas l'ordre. Je pourrais utiliser des listes à la place, mais je veux indiquer que la collection résultante ne permet pas la duplication d'éléments, ce qui est exactement à quoi Setsert l'interface.


Je ne pense pas qu'une telle chose existe. Je sais que j'en avais besoin aussi, et j'ai dû écrire le mien.
markspace

Serait SortedSettravailler? Sinon, la coutume est la voie à suivre.
AntonH

@AntonH Non, je préférerais les opérations O (1) à O (log n).
gvlasov

1
J'ai posté ce code, ce n'est pas exactement ce dont vous avez besoin, mais cela pourrait vous aider à démarrer.
markspace

Réponses:


203

Vous pouvez utiliser toCollectionet fournir l'instance concrète de l'ensemble souhaité. Par exemple, si vous souhaitez conserver l'ordre d'insertion:

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

Par exemple:

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]
    }
}

Bien, c'est exactement ce dont j'ai besoin, mais je pense que celui de Guava ImmutableSetserait encore meilleur dans mon cas. Des idées sur la façon dont je peux faire un collectionneur qui collectionne ImmutableSet? Ses instances sont construites avec un ImmutableSet.Builderqui n'est pas un Collection, donc je ne peux pas comprendre comment vous feriez un Supplierpour Collectors.toCollection()dans ce cas.
gvlasov

@Susei Je vais essayer de l'examiner. Une alternative serait de renvoyer un ensemble non modifiable. Ex:Set<String> linkedSet = list.stream().collect(Collectors.toCollection(LinkedHashSet::new)); linkedSet = Collections.unmodifiableSet(linkedSet);
Alexis

@Susei Le plus proche que j'ai trouvé: Je Set<String> set = list.stream().collect( ImmutableSet.Builder<String>::new, ImmutableSet.Builder<String>::add, (builder1, builder2) -> builder1.addAll(builder2.build())).build();ne sais pas si c'est une meilleure approche en enveloppant l'ensemble résultant avec Collections.unmodifiableSet.
Alexis C.

Voici une question dédiée car elle est déjà hors sujet (et pour plus de représentants pour de bonnes réponses, bien sûr): stackoverflow.com/questions/27612165
...
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.