2016-03-29 4 views
1

Если два объекта имеют одинаковое значение ele в классе A, то эти два объекта равны. Поэтому я переопределил toString и hashCode для возврата объекта ele (не считая значения s в любом месте).Java - переопределение hashCode и toString

public class A { 
    private int ele; 
    private String s; 

    public int getEle() { 
     return ele; 
    } 

    public void setEle(int ele) { 
     this.ele = ele; 
    } 

    public String getS() { 
     return s; 
    } 

    public void setS(String s) { 
     this.s = s; 
    } 

    @Override 
    public int hashCode(){ 
     return ele; 
    } 

    @Override 
    public String toString() { 
     return String.valueOf(ele); 
    } 
} 

public static void main(String[] args) { 

    Map<A, String> map = new HashMap<>(); 
    A a1 = new A(); 
    a1.setEle(10); 
    a1.setS("abc"); 

    A a2 = new A(); 
    a2.setEle(10); 
    a2.setS("efg"); 

    map.put(a1, "val1"); 
    map.put(a2, "val2"); 

    System.out.println(map.get(a1)); 
    System.out.println(map.get(a2)); 

} 

Выход:

val1 
val2 

Но если я ставлю значение a1 и a2 в карте, я ожидал, либо val1 или val2 должен быть возвращен для обоих map.get(a1) и map.get(a2).

ответ

7

Конечно, a1 и a2 имеют одинаковый хэш-код, но они не считаются равными, потому что вы не переопределяете equals рассмотреть два A объектов с одинаковыми ele быть равными. Карта будет использовать equals для окончательной линейки по равенству после использования хеш-кода. Карта поместит оба объекта в одно и то же ведро, но поскольку они не равны, он сохранит оба.

Override equals так, что она возвращает true, если другой объект является A, и они оба имеют один и тот же ele. Затем вы увидите, что val2 будет возвращен как для звонков get.

+0

О, я .. Мой плохой. Я думал, что он использует toString для получения строкового представления, а затем сравнивает – Ashwin

+0

Но я предполагаю, что он использует список при цепочке. Но я сначала вхожу в val1. Но я получаю val2 для обоих. Зачем? – Ashwin

+0

Когда вы кладете '' a2' в карту, карта считает ее равной 'a1', потому что' equals' возвращает 'true'. Затем карта _replaces_ пара ключ-значение («запись»), которая была там, «a1 ->» val1 »', с 'a2' ->" val2 ". И ваши вызовы 'get' приведут к тому, что' equals' вернут 'true', поэтому текущее значение' 'val2' 'будет получено каждый раз. – rgettman

0

каждый раз, когда вы используете new ключевое слово, оно делает новый object в heap Память. Итак, a1 и a2 оба разных объекта в действительности.

Пожалуйста, обратитесь это для получения дополнительной информации о new ключевом слове What New keyword do Internally in Java

1

Вы должны реализовать Equals(), чтобы принять ele значения во внимание при добавлении к карте, то есть:

public class A { 

    private int ele; 
    private String s; 

    public int getEle() { 
     return ele; 
    } 

    public void setEle(int ele) { 
     this.ele = ele; 
    } 

    public String getS() { 
     return s; 
    } 

    public void setS(String s) { 
     this.s = s; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     A a = (A) o; 

     return ele == a.ele; 

    } 

    @Override 
    public int hashCode() { 
     return ele; 
    } 
} 

Это сделает вас вернуть только одно значение, как вы хотите.

Смежные вопросы