Do I need to implement hashCode() and equals() methods?

前端 未结 4 997
伪装坚强ぢ
伪装坚强ぢ 2021-01-14 07:47

If I have a map and an object as map key, are the default hash and equals methods enough?

class EventInfo{

    private String name;
    private Map

        
4条回答
  •  Happy的楠姐
    2021-01-14 08:11

    Depends on what you want to happen. If two different EventInfo instances with the same name and info should result in two different keys, then you don't need to implement equals and hashCode.

    So

    EventInfo info1 = new EventInfo();
    info1.setName("myname");
    info1.setInfo(null);
    EventInfo info2 = new EventInfo();
    info2.setName("myname");
    info2.setInfo(null);
    

    info1.equals(info2) would return false and info1.hashCode() would return a different value to info2.hashCode().

    Therefore, when you are adding them to your map:

    map.put(info1, "test1");
    map.put(info2, "test2");
    

    you would have two different entries.

    Now, that may be desired behaviour. For example, if your EventInfo is collecting different events, two distinct events with the same data may well want to be desired to be two different entries.

    The equals and hashCode contracts is also applicable in a Set.

    So for example, if your event info contains mouse clicks, it may well be desired that you would want to end up with:

    Set collectedEvents = new HashSet();
    collectedEvents.add(info1);
    collectedEvents.add(info2);
    

    2 collected events instead of just 1...

    Hope I'm making sense here...

    EDIT:

    If however, the above set and map should only contain a single entry, then you could use apache commons EqualsBuilder and HashCodeBuilder to simplify the implementation of equals and hashCode:

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof EventInfo) {
            EventInfo other = (EventInfo) obj;
            EqualsBuilder builder = new EqualsBuilder();
            builder.append(name, other.name);
            builder.append(info, other.info);
            return builder.isEquals();
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        HashCodeBuilder builder = new HashCodeBuilder();
        builder.append(name);
        builder.append(info);
        return builder.toHashCode();
    }
    

    EDIT2:

    It could also be appropriate if two EventInfo instances are considered the same, if they have the same name, for example if the name is some unique identifier (I know it's a bit far fetched with your specific object, but I'm generalising here...)

提交回复
热议问题