Estoy tratando de encontrar una implementación de java.util.List
y java.util.Set
al mismo tiempo en Java. Quiero que esta clase permita solo elementos únicos (como Set
) y preserve su orden (como List
). ¿Existe en JDK 6?
Es importante tenerlo List<T>#add(int, T)
para poder insertarlo en una posición específica.
java
collections
yegor256
fuente
fuente
Comparator
? ¿También quieres la semántica de laList
interfaz?Respuestas:
TreeSet
está ordenado por orden de elementos;LinkedHashSet
conserva la orden de inserción. Con suerte, uno de esos es lo que buscabas.Ha especificado que desea poder insertar en una ubicación arbitraria , sospecho que tendrá que escribir la suya propia, simplemente cree una clase que contenga una
HashSet<T>
y unaArrayList<T>
; al agregar un elemento, verifique si está o no en el conjunto antes de agregarlo a la lista.Alternativamente, las ofertas commons-collections4 de Apache
ListOrderedSet
ySetUniqueList
, que se comportan de manera similar y deben cumplir con los requisitos dados.fuente
LinkedHashSet es la respuesta.
Orden de iteración y singularidad.
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
fuente
List
interfaz, vea mis cambios a la pregunta¿Quieres decir como
LinkedHashSet
? Esto conserva el orden de entrada, pero no permite duplicados.En mi humilde opinión, es un requisito inusual, pero puede escribir una lista sin duplicados.
class SetList<T> extends ArrayList<T> { @Override public boolean add(T t) { return !super.contains(t) && super.add(t); } @Override public void add(int index, T element) { if (!super.contains(element)) super.add(index, element); } @Override public boolean addAll(Collection<? extends T> c) { boolean added = false; for (T t : c) added |= add(t); return added; } @Override public boolean addAll(int index, Collection<? extends T> c) { boolean added = false; for (T t : c) if (!super.contains(t)) { super.add(index++, t); added = true; } return added; } }
fuente
List
interfaz, vea mis cambios a la preguntaO(n)
complejidad de inserción, hay una compensación que se debe considerar entre el almacenamiento doble y laO(log(n))
operación de inserción.No se puede implementar
List
ySet
de inmediato sin violación del contrato. Ver, por ejemplo, elSet.hashCode
contrato:Por otro lado, aquí está el contrato de
List.hashCode
:Por lo tanto, es imposible implementar una clase única que garantice el cumplimiento de ambos contratos. El mismo problema de
equals
implementación.fuente
Si no se limita a JDK 6, puede usar la biblioteca de colecciones comunes de Apache, que ofrece una correspondencia exacta para sus necesidades: ListOrderedSet . Es como
List
ySet
combinado juntos :)fuente
List
interfazTuve un problema similar, así que escribí el mío. Vea aquí . Se
IndexedArraySet
extiendeArrayList
e implementaSet
, por lo que debe admitir todas las operaciones que necesita. Tenga en cuenta que insertar elementos en ubicaciones en el medio de unaArrayList
puede ser lento para listas grandes porque es necesario mover todos los elementos siguientes. MiIndexedArraySet
no cambia eso.fuente
Otra opción (menos el
List
requisito de interfaz) es la de GuavaImmutableSet
, que conserva el orden de inserción. Desde su página wiki :fuente