Каков наилучший способ проверить, принадлежит ли объект другому (скажем, фиксированному) списку объектов? - PullRequest
4 голосов
/ 20 января 2009

В настоящее время я создаю HashMap с Object Id в качестве ключа и 1 в качестве значения. И метод запрашивает Object / Id и проверяет, есть ли соответствующий ключ.

Это нормально? Или есть (есть) лучшая альтернатива (ы)?

Ответы [ 7 ]

10 голосов
/ 20 января 2009

Это зависит от того, что вы подразумеваете под "есть".

Если вы имеете в виду идентичность объекта (т.е. object1 == object2), то вы можете использовать IdentityHashMap так, как вы описали.

Если вы имеете в виду равенство объектов (т. Е. object1.equals(object2)), тогда вы можете просто использовать HashSet вместо обезьяны с HashMap.

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

Phill Sacre напомнил мне кое-что, предложив List.contains(). У вас нет для использования реализации Set или Map. Вы можете использовать Список (например, ArrayList). Вы можете обнаружить, что выполнение содержит линейный поиск по списку short дешевле, чем поддержание хешированной структуры.

7 голосов
/ 20 января 2009

Будет ли List.contains (Объект) делать то, что вы хотите?

Помните, что, что бы вы ни делали, вы всегда должны реализовывать equals () и hashCode () .

5 голосов
/ 20 января 2009

Как уже отмечали другие, вы можете использовать HashSet для этого или любой другой тип Set. Если вы используете свои собственные объекты, убедитесь, что они переопределяют hashCode() (требуется для HashSet) и equals() (если они переопределяют оба, они будут работать с любым множеством).

3 голосов
/ 20 января 2009

Все в порядке. В качестве альтернативы вы можете использовать HashSet .

EDIT:

Вы можете сравнивать объекты двумя способами:

  1. По ссылке
  2. Custom

Сравнение Object по умолчанию выполняется по ссылке и реализовано в классе Object.

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

Учитывая это, ЕСЛИ вы хотите сравнивать объекты по ссылке, но есть пользовательская реализация равенства, тогда вам следует использовать IdentityHashMap ELSE используйте HashSet.

Если вы хотите сохранить текущую реализацию с HashMap, это тоже хорошо. HashSet внутренне реализован с помощью HashMap. Но вместо того, чтобы установить значение в 1, установите его с помощью null.

Существует также вопрос о правильной структуре данных . Вы можете использовать List вместо Hash структуры. Тип структуры данных, которую вы должны использовать, зависит от вас. Это зависит от того, как многие думают, например, сколько объектов вы собираетесь поместить в коллекцию, сколько будет доступа, вставок и т. Д.

2 голосов
/ 20 января 2009

По сути, это то, что делает HashSet, но я бы использовал HashSet вместо повторения реализации.

1 голос
/ 20 января 2009

Каково определение «из другого списка»? Это равенство объектов? Тогда то, что у вас есть, хорошо, но вы можете рассмотреть (хэш) набор для большей ясности.

Если вам нужно справочное равенство, найдите IdentityHashMap или используйте HashSet из IdentityHashcode

1 голос
/ 20 января 2009

Как предлагает Бруно, вы можете использовать набор для фиксированного списка объектов, а затем вызвать contains().

Если вы используете HashSet, убедитесь, что вы переопределяете реализацию hashCode() вашего объекта, которая используется в этом случае для проверки личности.

(В прошлый раз, когда я копался в JRE, ваш подход к использованию HashMap был именно тем, что HashSet сделал в любом случае!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...