una son objetos listas lista iguales elementos comparar buscar atributos arreglo java collections

java - objetos - comparar si dos listas son iguales c#



Compruebe si una colección contiene un objeto, comparando por referencia (6)

El método Collection.contains() verifica si una colección contiene un objeto dado, usando el método .equals() para realizar la comparación.

Desde Java7 Javadoc:

booleano contiene (objeto o)

Devuelve true si esta colección contiene el elemento especificado. Más formalmente, devuelve verdadero si y solo si esta colección contiene al menos un elemento e tal que (o == null? E == null: o.equals (e)).

¿Hay una forma inteligente de verificar si una colección contiene un objeto o , pero comparando por referencia (es decir, o==e )?

Por supuesto que puedo recorrer la colección y hacer la comprobación, estoy buscando una función existente que pueda hacer eso.

Aclaraciones:

  • Quiero realizar esta operación independientemente de la implementación equals() del objeto en la colección.
  • No quiero cambiar los objetos de la colección ni la colección en sí.

Editar:

Aunque mi pregunta es sobre una solución general para las implementaciones de la Collection , también se apreciarán los casos específicos de las subinterfaces de la Collection .


Cuando creas una clase deberías anular los métodos de al menos equals (y hashCode ).
Si implementa su método de equals para comparar por referencia, logrará su objetivo.


Debería poder hacerlo envolviendo el objeto en su propio objeto que implemente los equals que está buscando.

Algo como:

private class Identical<T> { final T held; Identical (T hold) { held = hold; } public boolean equals(Object it) { return it != null && held == it; } }

Obviamente, deberías tomar el control de agregar elementos a la colección y envolver cada uno en uno de estos.

Podrías envolver el mapa así:

static class ReferenceHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> { private final Map<K, Identical<V>> map = new HashMap<>(); private static class Identical<T> { final T held; Identical(T hold) { held = hold; } @Override public boolean equals(Object it) { return it != null && held == it; } @Override public int hashCode() { return held.hashCode(); } } @Override public V get(Object key) { Identical<V> value = map.get(key); return value == null ? null : value.held; } @Override public V put(K key, V value) { Identical<V> replaced = map.put(key, new Identical<>(value)); return replaced == null ? null : replaced.held; } private class MyEntry implements Map.Entry<K, V> { private final K key; private V value; public MyEntry(K key, V value) { this.key = key; this.value = value; } @Override public K getKey() { return key; } @Override public V getValue() { return value; } @Override public V setValue(V value) { V old = this.value; this.value = value; return old; } } @Override public Set<Entry<K, V>> entrySet() { Set<Entry<K, V>> entries = new HashSet<>(); for (Entry<K, Identical<V>> entry : map.entrySet()) { entries.add(new MyEntry(entry.getKey(), entry.getValue().held)); } return entries; } }


Hay algún tipo de solución ...

Puede usar un IdentityHashMap , con Void como valores (o cualquier otra cosa, su elección). A continuación, usaría el contains() en su .keySet() para verificar la presencia de un elemento (o .containsKey() en el mapa directamente).

Una segunda solución sería usar Guava y Equivalence.identity() ; sin embargo, su Collection tendrá que tener elementos de tipo Equivalence.Wrapper<X> y tendrá que wrap antes de verificar ...

Curiosamente, el JDK no proporciona un IdentityHashSet . Esto es bastante extraño teniendo en cuenta que la implementación interna de HashSet utiliza un HashMap , por lo que uno tiene que preguntarse por qué no hicieron lo mismo para IdentityHashMap ...

Nota al margen: la documentación de la Collection es engañosa; no todas las implementaciones de Collection basan en .equals() . Ver, por ejemplo, SortedSet o SortedMap . Y, por supuesto, IdentityHashMap .


Las respuestas señalan que no es posible realizar de forma limpia la comprobación deseada.

Así que esta es una posible implementación de dicha función solicitada:

/** * Returns {@code true} if the collection contains the specified element. * <p> * More formally, returns {@code true} if and only if this collection * contains at least one element {@code x} such that {@code x == element}. * <p> * Note: {@link Collection#contains(Object)} works differently because uses * {@link Object#equals(Object)} for comparison * * @param collection * collection where to look for the element * @param element * element whose presence in this collection is to be tested * @return {@code true} if this collection contains the specified element * @throws NullPointerException * if {@code collection} is null */ public static <T> boolean containsReferenceTo(Collection<T> collection, T element) { if (collection == null) throw new NullPointerException("collection cannot be null"); for (T x : collection) { if (x == element) { return true; } } return false; }

NOTA: esto puede optimizarse para algunas implementaciones específicas de la Collection .


No hay manera de verificar que la forma en que está tratando de hacer. Sin iterar a través de la colección, no puede verificar si el objeto apunta a la misma referencia o no.

AFAIK, No ( al menos una forma limpia ).


Para aquellos de nosotros que usamos Java 8, Collection#stream() es una opción limpia:

collection.stream().anyMatch(x -> x == key)