Java Set retener el orden?


179

¿Un Java Set retiene el orden? Un método me devuelve un Set y supuestamente los datos están ordenados pero iterando sobre el Set, los datos están desordenados. ¿Hay una mejor manera de manejar esto? ¿Es necesario cambiar el método para devolver algo distinto de un conjunto?


3
"Los elementos se devuelven en ningún orden en particular (a menos que este conjunto sea una instancia de alguna clase que proporcione una garantía)". es lo que dice el método iterador para un conjunto. encontrado aquí
keyser

Respuestas:


256

La Setinterfaz no ofrece ninguna garantía de pedido.

Su subinterfaz SortedSetrepresenta un conjunto que se ordena según algún criterio. En Java 6, hay dos contenedores estándar que se implementan SortedSet. Son TreeSety ConcurrentSkipListSet.

Además de la SortedSetinterfaz, también está la LinkedHashSetclase. Recuerda el orden en que se insertaron los elementos en el conjunto y devuelve sus elementos en ese orden.


21
Además, debido al diferente hashing de cadenas en Java 8, el orden predeterminado (sin clasificar) en Conjuntos y mapas cambiará. Si confía en pedidos sin clasificar, su código se comportará de manera diferente en Java 8.
rustyx

Entiendo que la clase que no ordena es normal, pero el comportamiento que esperaba era dejarlos tal como fueron introducidos y no alterar el orden, sino que simplemente baraja los elementos cada vez que se agrega uno. Su solución no es óptima porque entonces tendré que implementar una estructura completa para que se ordenen DE LA MISMA FORMA en que se introdujeron: S
White_King

@White_King: un conjunto es un concepto matemático que no contiene la noción de "orden de inserción", por lo que tiene sentido que la interfaz Java siga sus convenciones. Hay conjuntos ordenados, pero el orden se especifica mediante una relación (comparador en Java), que nuevamente coincide con la definición en teoría de conjuntos con la definición en Java. Su expectativa de mantener el orden de inserción probablemente proviene de listas, pero los conjuntos no son listas.
Konrad Höffner el

103

LinkedHashSet es lo que necesitas.


43
A Listno es un Set(no garantiza la unicidad de membresía).
Expiación limitada el

10
En muchos casos comerciales únicos, la Lista no se puede usar solo para retener el orden en lugar de Establecer. LinkedHashSet mantiene el orden y las tiendas son únicas.
Gubs

18

Como muchos de los miembros sugirieron usar LinkedHashSet para retener el orden de la colección. U puede envolver su conjunto utilizando esta implementación.

La implementación de SortedSet se puede usar para el orden ordenado, pero para su propósito use LinkedHashSet .

También de los documentos,

"Esta implementación ahorra a sus clientes el pedido no especificado, generalmente caótico, proporcionado por HashSet, sin incurrir en el mayor costo asociado con TreeSet. Se puede utilizar para producir una copia de un conjunto que tenga el mismo orden que el original, independientemente del original. implementación del conjunto: "

Fuente : http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html


9

Set es solo una interfaz. Para retener el orden, debe usar una implementación específica de esa interfaz y la subinterfaz SortedSet, por ejemplo TreeSet o LinkedHashSet. Puedes envolver tu Set de esta manera:

Set myOrderedSet = new LinkedHashSet(mySet);

7

Aquí hay un resumen rápido de las características de orden de las Setimplementaciones estándar disponibles en Java:

  1. mantenga el orden de inserción: LinkedHashSet y CopyOnWriteArraySet (seguro para subprocesos)
  2. mantenga los elementos ordenados dentro del conjunto: TreeSet , EnumSet (específico para las enumeraciones) y ConcurrentSkipListSet (seguro para subprocesos)
  3. no mantiene los elementos en ningún orden específico: HashSet (el que probó)

Para su caso específico, puede ordenar los elementos primero y luego usar cualquiera de 1 o 2 (muy probablemente LinkedHashSeto TreeSet). O de manera alternativa y más eficiente , simplemente puede agregar datos sin clasificar a un TreeSetque se encargará de la clasificación automáticamente por usted.


7

Para retener la orden use Listo a LinkedHashSet.


1
Es LinkedHashSet, no ... Map.
Marko Topolnik

Necesito un conjunto no es una lista, necesito un conjunto que conserva también el orden de inyección de los objetos supongo
White_King

5

LinkedHashSet es una versión ordenada de HashSet que mantiene una lista doblemente vinculada en todos los elementos. Use esta clase en lugar de HashSet cuando le importe el orden de iteración.


3

Del javadoc para Set.iterator():

Devuelve un iterador sobre los elementos de este conjunto. Los elementos se devuelven en ningún orden en particular (a menos que este conjunto sea una instancia de alguna clase que proporcione una garantía).

Y, como ya dijo shuuchan , a TreeSetes una implementación Setque tiene un orden garantizado:

Los elementos se ordenan utilizando su ordenamiento natural o mediante un comparador proporcionado en el momento de creación establecido, según el constructor utilizado.


3

Normalmente, set no mantiene el orden, como HashSet para encontrar rápidamente un emelent, pero puede probar LinkedHashSet, mantendrá el orden que ingresó.


1

Hay 2 cosas diferentes.

  1. Ordenar los elementos en un conjunto. Para lo cual tenemos SortedSet e implementaciones similares.
  2. Mantener el orden de inserción en un conjunto. Para lo cual se pueden usar LinkedHashSet y CopyOnWriteArraySet (seguro para subprocesos).



-2

Solo se SortedSetpuede ordenar elSet


La pregunta se trata de retener el orden de inserción (que está ordenado).
Assylias
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.