from - jlist java eclipse
¿Hay un orden de inserción que preserva Set que también implementa List? (7)
Estoy intentando 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 tener List<T>#add(int, T)
para poder insertarlo en una posición específica.
¿Te LinkedHashSet
a 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;
}
}
No puede implementar List
and Set
a la vez sin violación de contrato. Ver, por ejemplo, el contrato Set.hashCode
:
El código hash de un conjunto se define como la suma de los códigos hash de los elementos en el conjunto, donde el código hash de un elemento nulo se define como cero.
Por otro lado, aquí está el contrato de List.hashCode
:
El código hash de una lista se define como el resultado del siguiente cálculo:
int hashCode = 1; for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
Por lo tanto, es imposible implementar una sola clase que garantice que ambos contratos se cumplan. El mismo problema para la implementación de equals
a equals
.
Otra opción (menos el requisito de interfaz de List
) es el ImmutableSet de Guava, que preserva el orden de inserción. De su página wiki :
A excepción de las colecciones ordenadas, el orden se conserva desde el momento de la construcción. Por ejemplo,
ImmutableSet.of("a", "b", "c", "a", "d", "b")
iterará sobre sus elementos en el orden "a", "b", "c", "d".
Si no se limita a JDK 6, puede utilizar la biblioteca de colecciones comunes Apache que ofrece una coincidencia exacta para su necesidad: ListOrderedSet . Es como List
and Set
combinados juntos :)
Tuve un problema similar, así que escribí el mío. Mira here . IndexedArraySet
extiende ArrayList
e implementa Set
, por lo que debe admitir todas las operaciones que necesite. Tenga en cuenta que la inserción de elementos en ubicaciones en el medio de una ArrayList
puede ser lenta para listas grandes porque todos los siguientes elementos deben moverse. Mi IndexedArraySet
no cambia eso.
TreeSet
está ordenado por orden de elementos; LinkedHashSet
retiene el orden de inserción. Con suerte, uno de esos es lo que estabas buscando.
Has especificado que quieres poder insertar en una ubicación arbitraria , sospecho que tendrás que escribir la tuya; solo crea una clase que contenga un HashSet<T>
y una ArrayList<T>
; al agregar un elemento, verifique si está o no en el conjunto antes de agregarlo a la lista.