Почему String, Integer и другие классы-оболочки считаются хорошими ключами в HashMap?

Почему String, Integer и другие классы-оболочки считаются хорошими ключами?

Я нашел ниже ответы -

String, Integer и другие классы-оболочки являются естественными кандидатами на ключ HashMap, а String также является наиболее часто используемым ключом, поскольку String является неизменяемым и окончательным и переопределяет методы equals и hashcode().

Другой класс-оболочка также имеет аналогичное свойство. Требуется неизменяемость, чтобы предотвратить изменения в полях, используемых для вычисления hashCode(), потому что, если ключевой объект возвращает другой hashCode во время вставки и извлечения, невозможно будет получить объект из HashMap. Неизменяемость лучше всего, поскольку она предлагает другие преимущества, а также безопасность потоков. Если вы можете сохранить свой хэш-код одинаковым, только сделав определенные поля окончательными, то вы также пойдете на это. Поскольку методы equals() и hashCode() используются при извлечении объекта значения из HashMap, важно, чтобы ключевой объект правильно переопределял эти методы и следовал контакту. Если неравный объект возвращает другой хэш-код, вероятность столкновения будет меньше, что впоследствии улучшит производительность HashMap.


person Faizal    schedule 05.06.2014    source источник
comment
Согласен, другой вопрос, почему это вообще работает. Этот вопрос о том, почему строки являются хорошими ключами.   -  person Jens Schauder    schedule 05.06.2014
comment
Это не классы-оболочки.   -  person Boann    schedule 05.06.2014
comment
@Boann это классы-оболочки.   -  person Luiggi Mendoza    schedule 05.06.2014
comment
Поскольку я не могу ответить: 1. Строки работают, потому что они являются объектами-значениями, что, среди прочего, означает, что две строки с одинаковым значением будут считаться равными. 2. Строки неизменяемы (как и все объекты с хорошими значениями). 3. Строки имеют эффективные и разумные реализации hashCode. 4. То же самое верно и для «классов-оболочек».   -  person Jens Schauder    schedule 05.06.2014
comment
@LuiggiMendoza Они не обертывают никакие другие классы.   -  person Boann    schedule 05.06.2014
comment
@Boann Integer класс обертывает int, Boolean класс обертывает boolean и далее...   -  person Luiggi Mendoza    schedule 05.06.2014
comment
@Boann java.lang.Integer: Класс Integer оборачивает значение примитивного типа int в объект. Он есть в официальном javadoc.   -  person Luiggi Mendoza    schedule 05.06.2014
comment
@LuiggiMendoza Не имеет значения. Это просто ограничение дженериков Java. На самом деле мы не хотим использовать целые числа или логические значения в качестве ключей сопоставления. Мы действительно хотим использовать int и boolean. Причина, по которой это хорошие ключи, заключается в том, что они являются типами значений (т. е. неизменяемыми).   -  person Boann    schedule 05.06.2014
comment
@Боанн, не упрямься. Это задокументировано самой S̶u̶n̶ Oracle.   -  person Luiggi Mendoza    schedule 05.06.2014
comment
@LuiggiMendoza При дальнейшем размышлении я признаю, что Integer и Boolean являются классами-оболочками, хотя они существуют для несколько иной цели, чем другие классы-оболочки, которые можно написать. Я (неправильно) прочитал вопрос как подразумевающий, что OP считает String классом-оболочкой, что меня сбило с толку. Я все еще не уверен в цели вопроса: спрашивает ли OP, почему эти конкретные классы хороши в качестве ключей, или почему любые классы хороши в качестве ключей, если они обертывают другие объекты, или вопрос, почему мы не можем сделать Map<int,int>?   -  person Boann    schedule 05.06.2014
comment
@Boann OP спрашивает, почему String и Integer и другие классы-оболочки считаются подходящими для ключей в HashMap. И я согласен с вами, что String вообще не является классом-оболочкой. По сути, это для хорошей реализации методов hashCode и equals, которые являются основными методами, используемыми в ключах в HashMap, и поскольку они уже есть для работы, нет необходимости изобретать велосипед.   -  person Luiggi Mendoza    schedule 05.06.2014
comment
@LuiggiMendoza Вы должны сформулировать это в ответ. Это лучше, чем текущие ответы.   -  person Boann    schedule 05.06.2014


Ответы (2)


В большинстве реализаций Map записи сохраняются в зависимости от состояния ключа. Если ключ изменится, невозможно получить запись с данным ключом.

HashMap имеет дело со значением hashCode() ключа. Если значение hashCode() этого ключа генерируется из неизменного состояния, оно будет постоянным. Поскольку эти типы неизменяемы, их (внешние) свойства неизменны, а их hashCode() генерируются из этих свойств, ключ любого из этих типов не может измениться, и эта проблема перестает быть проблемой.

person Sotirios Delimanolis    schedule 05.06.2014
comment
Тот факт, что они неизменны, не является основной причиной. Я могу иметь другой класс с полями final и использовать только эти поля final для создания hashCode и оценки того, являются ли экземпляры equals и будут ли они выполнять такое же поведение. - person Luiggi Mendoza; 05.06.2014
comment
@LuiggiMendoza, но то, что есть другие классы с этим свойством, не означает, что строки менее подходят. - person Jens Schauder; 05.06.2014
comment
@JensSchauder Я не утверждаю, что String не подходят, но тот факт, что сам класс immutable, не является основной причиной. - person Luiggi Mendoza; 05.06.2014
comment
@LuiggiMendoza Отредактировано, чтобы уточнить, что это неизменность свойств, используемых в алгоритме сопоставления ключей. - person Sotirios Delimanolis; 05.06.2014
comment
Одно из преимуществ неизменности строк заключается в том, что хеш-код можно кэшировать (и это действительно делается!). Таким образом, поиск с использованием строки особенно эффективен по сравнению со сложными и/или изменяемыми объектами, где хэш-код должен повторно вычисляться для каждого вызова hashCode(). - person Marco13; 05.06.2014

Я вижу следующие причины:

  1. Строки работают, потому что они являются объектами-значениями, что, среди прочего, означает, что две строки с одинаковым значением будут считаться равными.

  2. Строки неизменяемы (как и все объекты с хорошими значениями).

  3. Строки имеют эффективные и разумные реализации hashCode. Это означает, что их использование в HashMaps эффективно.

То же самое относится и к «классам-оболочкам».

person Jens Schauder    schedule 05.06.2014