Использование массива символов в качестве ключа Hashtable

Я работаю с Hashtable в своей Java-программе. Я просто удивлен, увидев ненормальное поведение Hastable. Ниже приведен мой код (это не мой окончательный код, я просто создал новый простой проект с кодом, который работает ненормально)

    Hashtable<char[], char[]> h1 = new Hashtable<char[], char[]>();
    char[] key = Integer.toString(12).toCharArray();
    char[] val = Integer.toString(21).toCharArray();
    h1.put(key, val);
    System.out.println(h1.containsKey(Integer.toString(12).toCharArray()));// Should print true, since 12 is there in Hashtable

person Ravi Joshi    schedule 14.04.2012    source источник
comment
какая-то конкретная причина, по которой вы используете char[] вместо String?   -  person blejzz    schedule 15.04.2012
comment
возможный дубликат Использование массива байтов в качестве ключа HashMap (Java)   -  person MK.    schedule 15.04.2012
comment
Вы даже не можете использовать StringBuffer/Builder в качестве ключа в Hashmap vs stringbuffer как ключ hashmap"> stackoverflow.com/questions/23790423/   -  person Kanagavelu Sugumar    schedule 20.08.2019


Ответы (3)


Вы не можете использовать массивы, подобные этому, в качестве ключей карты, потому что массивы имеют стандартные, основанные на ссылочном равенстве Object реализации equals и hashCode. Вместо этого использование String в качестве ключа заставит вашу программу работать так, как нужно.

person Louis Wasserman    schedule 14.04.2012
comment
Но я использовал массивы целых чисел. Я не сталкивался с какими-либо проблемами. - person user; 15.04.2012
comment
@crucified Да, возможно, вы просто этого не заметили .. Но поскольку основное утверждение (массивы имеют ссылочное равенство) верно для любого массива, так оно и есть. - person Voo; 15.04.2012
comment
@Voo прав. int[] a = {1}; int[] b = {1}; System.out.println(a == b) печатает false. - person Louis Wasserman; 15.04.2012

Равенство массивов основано на ссылочном равенстве («Эти две ссылки на один и тот же объект?»), а не на глубоком равенстве («Эти два объекта семантически идентичны?»). Смотреть:

char[] one = Integer.toString(12).toCharArray();
char[] two = Integer.toString(12).toCharArray();
System.out.println(one == two); // false

http://ideone.com/YwEjV

person Matt Ball    schedule 14.04.2012
comment
Они не относятся к одному и тому же объекту. В приведенном выше коде я использовал Integer.toString(). Но в моем реальном коде я работаю с char[]. Итак, что можно сделать сейчас? - person Ravi Joshi; 15.04.2012
comment
Используйте Strings, а не char[]s, в качестве ключей карты. Кроме того, вам, вероятно, следует использовать HashMap вместо устаревшего Hashtable. ...Также было бы лучше писать код "12".toCharArray() или new char[]{'1', '2'} вместо Integer.toString(12).toCharArray(). - person Matt Ball; 15.04.2012

если a и b - 2 массива, чем a.equals(b), если a == b. Таким образом, хэш-код a == хэш-код b, если a == b. Поскольку здесь это не так, он не будет найден в хеш-таблице. Использование массивов в качестве ключей хэш-таблицы — плохая идея. Также использование любого изменяемого объекта в качестве ключа хеш-таблицы — плохая идея.

person MK.    schedule 14.04.2012
comment
Ваша логика не полностью верна, поскольку (на практике) реализации методов .equals() и .hashCode() независимы. - person Matt Ball; 15.04.2012
comment
Часть контракта equals и hashCode должна быть согласована друг с другом. Я бы предположил, что Java следует собственному контракту. - person MK.; 15.04.2012