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.

gvlasov
la source
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]
    }
}
Alexis C.
la source
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
...