Is it proper for equals() to depend only on an ID?

落花浮王杯 提交于 2019-12-03 04:30:24

Whether you should do this depends on the semantics of your class. That is, what does it mean to say that two objects of your class are equivalent? The most important distinction is between objects with value semantics and objects with entity semantics. Entity objects are not equivalent even if they have equivalent attributes (colour, length, etc.). In many cases, including when the object has been read from a database table that has a primary key, entity objects will have an ID field that is unique. Comparing only the ID field in that case is the right thing to do.

It's fine. As long as no two different users can have the same ID your equals function is sufficient. There could be a problem if one user can be represented twice with a different ID (for whatever reason) and you do want to consider them equal.

your equals() method dosen't look like it was generated by IDE as it doesn't check for 'id' null value as stated by @Eric..

this is what my equals()/hashCode() method looked like using same 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;
}

we should always use automatic generation for boilerplate code where possible, as it is a lot less error prone.

also, regarding your point regarding uniqueness of 'id' prop, that depends on your preference and how you want to use you equals method (business requirement) i.e. if two User's name are same are they to be considered same when comparing two User Objects later on..

It's ok to use id for equals method as long as you don't have to compare an entity that wasn't persisted yet to the DB. If you want to compare entities that weren't saved yet, you'll have to compare their attributes.

I agree it is on the id. But I had trouble when getting data that should update the database. With this example with User where equals only looked on ID I created this.

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;
   }
}

With this we can have this.

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);
        }
    }
 }
}

Then we can do this

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

Do you agree this is a way to do this. ??????

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!