2016-05-17 2 views
-1

Согласно официальной документации для класса Java Hashtable (https://docs.oracle.com/javase/7/docs/api/java/util/Hashtable.html), операция get() вернет одно из записанных значений, если указанное значение имеет ключ, который возвращает true, если параметр подается в opals() equals этого ключа.Операция Hashtable get() не работает согласно документации

Итак, теоретически следующий код должен возвращать «Hello!» для обоих ГЭТ Хеш (в) запросы:

public static class Coordinates implements Serializable { 

    private int ex; 
    private int why; 

    public Coordinates(int xCo, int yCo) { 
     ex = xCo; 
     why = yCo; 
    } 

    public final int x() { 
     return ex; 
    } 

    public final int y() { 
     return why; 
    } 

    public boolean equals(Object o) { 
     if(o == null) { 
      return false; 
     } else if(o instanceof Coordinates) { 
      Coordinates c = (Coordinates) o; 
      return this.x() == c.x() && this.y() == c.y(); 
     } else { 
      return false; 
     } 
    } 
} 

Hashtable<Coordinates, String> testTable = new Hashtable<Coordinates, String>(); 
Coordinates testKey = new Coordinates(3, 1); 
testTable.put(testKey, "Hello!"); 
testTable.get(testKey); //This will return the "Hello" String as expected. 
testTable.get(new Coordinates(3, 1)); //This will only return a null value. 

Однако, получить() не работает, как это предполагается. Кажется, что он работает, только если вы переполняете его точно таким же объектом, как и исходный ключ.

Есть ли способ исправить это и заставить Hashtable функционировать так, как описано в документации? Нужно ли вносить какие-либо коррективы в пользовательскую equals() opperation в классе Coordinates?

+7

С документация: 'Чтобы успешно хранить и извлекать объекты из хеш-таблицы, объекты, используемые в качестве ключей, должны реализовывать метод hashCode и метод equals.« Вы также должны переопределить метод hashCode. –

+0

И если объекты равны, то их значение hashCode должно быть равно. – ntalbs

+0

Можете ли вы включить реализацию для 'hashCode()'? BTW Ваша IDE сможет генерировать 'hashCode()' и 'equals (Object)' для вас. –

ответ

2

Чтобы иметь возможность хранить и извлекать объекты из коллекций, основанных на хеше, вы должны реализовать/oeverride equals(), а также hashCode() методы класса Object. В вашем случае вы переопределили equals() и оставили метод hashCode() по умолчанию, унаследованный от Object.

Here is the general contract из hashCode() метода необходимо учитывать при его реализации:

  • Всякий раз, когда он вызывается на одном объекте более чем один раз в течение выполнения приложения Java, метод хэш-код должен последовательно возвращать одно и то же целое число, при условии, что информация, используемая при равных сравнениях с объектом, не изменяется. Это целое число не должно оставаться согласованным с одним исполнением приложения на другое выполнение одного и того же приложения.

  • Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен приводить к одному и тому же целочисленному результату.

  • Не требуется, чтобы, если два объекта неравны в соответствии с методом equals (java.lang.Object), то вызов метода hashCode для каждого из двух объектов должен производить различные целочисленные результаты. Тем не менее, программист должен знать, что получение отдельных целых результатов для неравных объектов может улучшить производительность хеш-таблиц.

А вот пример реализации, который генерируется из моего IDE (как alread упомянутой @Peter в области комментария), который можно изменить в соответствии с вашими требованиями:

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ex; 
    result = prime * result + why; 
    return result; 
} 
+1

С Java 7 этот код примера можно записать как 'return Objects.hash (ex, why);'. См. [Objects.hash] (https://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#hash-java.lang.Object...-). – VGR

+0

@VGR Спасибо! Я попробую. – ujulu

+0

Спасибо, @ujulu & @VGR! :) – Cambot

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