¿Existe un recopilador que recopile en un conjunto de conservación de pedidos?

107

Collectors.toSet()no conserva el orden. En su lugar, podría usar Listas, pero quiero indicar que la colección resultante no permite la duplicación de elementos, que es exactamente para lo Setque sirve la interfaz.

gvlasov
fuente
No creo que exista tal cosa. Sé que también necesitaba uno y tenía que escribir el mío.
espacio de calificación
¿ SortedSetFuncionaría? Si no, la costumbre es el camino a seguir.
AntonH
@AntonH No, preferiría las operaciones O (1) a O (log n).
gvlasov
1
Publiqué ese código, no es exactamente lo que necesita, pero podría ayudarlo a comenzar.
espacio de calificación

Respuestas:

203

Puede utilizar toCollectiony proporcionar la instancia concreta del conjunto que desee. Por ejemplo, si desea mantener el orden de inserción:

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

Por ejemplo:

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.
fuente
Bien, eso es exactamente lo que necesito, pero creo que Guava's ImmutableSetsería aún mejor en mi caso. ¿Alguna idea sobre cómo puedo hacer un coleccionista que recolecte ImmutableSet? Sus instancias están construidas con un ImmutableSet.Builderque no es un Collection, por lo que no puedo entender cómo harías un Supplierpara Collectors.toCollection()en ese caso.
gvlasov
@Susei Intentaré investigarlo. Una alternativa sería devolver un conjunto no modificable. Ej .:Set<String> linkedSet = list.stream().collect(Collectors.toCollection(LinkedHashSet::new)); linkedSet = Collections.unmodifiableSet(linkedSet);
Alexis C.
@Susei Lo más cercano que encontré: Set<String> set = list.stream().collect( ImmutableSet.Builder<String>::new, ImmutableSet.Builder<String>::add, (builder1, builder2) -> builder1.addAll(builder2.build())).build();No estoy seguro de si es un mejor enfoque envolviendo el conjunto resultante con Collections.unmodifiableSet.
Alexis C.
Aquí hay una pregunta dedicada, ya que ya está fuera del tema (y para obtener más representantes para obtener excelentes respuestas, por supuesto): stackoverflow.com/questions/27612165/…
gvlasov