Estoy tratando de encontrar una implementación de java.util.Listy java.util.Setal 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 laListinterfaz?Respuestas:
TreeSetestá ordenado por orden de elementos;LinkedHashSetconserva 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
ListOrderedSetySetUniqueList, 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
Listinterfaz, 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
Listinterfaz, 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
ListySetde inmediato sin violación del contrato. Ver, por ejemplo, elSet.hashCodecontrato: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
equalsimplementació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
ListySetcombinado juntos :)fuente
ListinterfazTuve un problema similar, así que escribí el mío. Vea aquí . Se
IndexedArraySetextiendeArrayListe implementaSet, por lo que debe admitir todas las operaciones que necesita. Tenga en cuenta que insertar elementos en ubicaciones en el medio de unaArrayListpuede ser lento para listas grandes porque es necesario mover todos los elementos siguientes. MiIndexedArraySetno cambia eso.fuente
Otra opción (menos el
Listrequisito de interfaz) es la de GuavaImmutableSet, que conserva el orden de inserción. Desde su página wiki :fuente