and java oop override equals hashcode

java - and - ¿Es correcto que equals() dependa solo de una ID?



override equals c# (5)

Está bien usar el método id para equals siempre que no tenga que comparar una entidad que aún no haya persistido con el DB. Si desea comparar entidades que aún no se guardaron, deberá comparar sus atributos.

Supongamos que tengo User clase:

public class User { private Long id; private String name; private Integer age; private BigDecimal account; // other fields, getters and setters }

¿Es apropiado anular el método igual de la siguiente manera?

@Override public boolean equals(Object ob) { if (ob == null) { return false; } if (this == ob) { return true; } if (ob instanceof User) { User other = (User) ob; return this.id.equals(other.getId()); } return false; }

Resulta que la unicidad de un objeto está determinada únicamente por su ID. Pero en mi aplicación, id siempre es único. Se proporciona en la base de datos. ¿Es mi implementación equals suficientemente competente como para explicar esto? ¿O esto no es la mejor práctica?

Por supuesto, entiendo que en este caso, la implementación de hashCode debería ser la siguiente:

@Override public int hashCode() { return id.intValue(); }


Está bien. Siempre que no haya dos usuarios diferentes que puedan tener la misma ID, su función equals es suficiente. Podría haber un problema si un usuario puede ser representado dos veces con una identificación diferente (por cualquier razón) y usted quiere considerarlos iguales.


Estoy de acuerdo en que está en la identificación. Pero tuve problemas al obtener datos que deberían actualizar la base de datos. Con este ejemplo con el usuario donde es igual solo se vio en la ID, creé esto.

interface DataEquals<T extends DataEquals> { public boolean isDataEquals(T other) } User implements DataEquals<User> { public boolean isDataEquals(User other) { boolean b1 = getName().equals(other.getName()); boolean b2 = getAge().equals(other.getAge()); boolean b3 = getAccount().equals(other.getAccount()); return b1 && b2 && b3; } }

Con esto podemos tener esto.

public class ListChanges<T extends DataEquals<T>> { private List<T> added = new ArrayList<T>(); private List<T> removed = new ArrayList<T>(); private List<T> changed = new ArrayList<T>(); private List<T> unchanged = new ArrayList<T>(); public ListChanges() { super(); } public List<T> getAdded() { return added; } public List<T> getChanged() { return changed; } public List<T> getRemoved() { return removed; } public List<T> getUnchanged() { return unchanged; } public boolean hasAnyChanges() { return added.size()>0 || removed.size()>0 || changed.size()>0; } public void parse(List<T> oldList,List<T> newList) { for (T oldObj : oldList) { int index =newList.indexOf(oldObj); if (index==-1) { removed.add(oldObj); } else { T newObj = newList.get(index); if (newObj.isDataEquals(oldObj)) { unchanged.add(oldObj); } else { changed.add(newObj); } } } for (T newObj : newList) { if (oldList.indexOf(newObj)==-1) { added.add(newObj); } } } }

Entonces podemos hacer esto

List<User> oldList = ....; List<User> newList = ...; ListChanges<User> listChanges = new ListChanges<User>(); listChanges.parseChanges(oldList,newList);

¿Estás de acuerdo? Esta es una manera de hacer esto. ??????


Si debes hacer esto depende de la semántica de tu clase. Es decir, ¿qué significa decir que dos objetos de tu clase son equivalentes? La distinción más importante es entre objetos con semántica de valor y objetos con semántica de entidad. Los objetos de entidad no son equivalentes incluso si tienen atributos equivalentes (color, longitud, etc.). En muchos casos, incluso cuando el objeto se ha leído de una tabla de base de datos que tiene una clave principal, los objetos de entidad tendrán un campo de ID que es único. Comparar solo el campo de ID en ese caso es lo correcto.


su método equals () no parece que fue generado por IDE, ya que no verifica el valor nulo de ''id'' como lo indica @Eric ..

esto es lo que parecía mi método equals () / hashCode () usando el mismo id prop

@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User11 other = (User11) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; }

Siempre que sea posible, debemos usar la generación automática para el código de repetición, ya que es mucho menos propenso a errores.

también, con respecto a su punto con respecto a la singularidad de la prop ''id'', eso depende de su preferencia y de cómo quiera usar su método igual (requisito comercial), es decir, si el nombre de dos usuarios es el mismo, ¿se considerarán iguales al comparar dos objetos de usuario más adelante en..