Java Hashtable <Object, Someclass>, если ключ является строкой? если строка одинакова, она удалит все значения с одинаковой строкой - PullRequest
0 голосов
/ 11 апреля 2011

Мне нужно значение Someclass на основе ключа. И ключ может быть строкой, логическим или другим объектом, поэтому я использовал объект в качестве ключа. Но у меня есть проблема, когда объект представляет собой строку. и у меня есть два объекта строки, который равен, но он должен возвращать другое значение, потому что это другой объект.

Код, который у меня есть:

Object k = new String("action");
Object l = new String("action");
Hashtable<Object,SomeClass> map = new Hashtable<Object, SomeClass>();

map.put(k,anObject1);
map.put(l,anObject2);

map.remove(k); // it is removing both with k and l.

когда я проверяю hashCode () обоих объектов, он возвращает одно и то же значение, что в конечном итоге не то, что я хочу.

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

Отредактировано: Я делаю это, потому что мне нужно выполнить другое действие в зависимости от того, какая строка, но действие будет отличаться значением, возвращаемым картой с ключом.

Обновлено: Хорошо, вот вся история, почему мне нужна эта странная вещь.

У меня есть экземпляр игрока и 3 экземпляра земли. Поэтому я хотел, чтобы игрок пахал land1, land2, land3. Если игрок хотел вспахать землю, эта земля создала бегущую нить, которая велит игроку перейти на позицию X и выполнить работу action и wait() с помощью объекта action, а когда другой нить notify эта нить по объекту action, земля затем модифицирует себя. Затем игрок делает анимацию на основе объекта action. У меня есть ArrayList<Position> destination и «ArrayList action», чтобы получить его. Может быть, вы можете прочитать мой другой вопрос об этом здесь .

Итак, я хотел сделать действие отменяемым. Я реализую это, также передавая объект action. У меня есть кнопка, которая отображается для каждого действия, и каждая кнопка отменит это действие. Я пропускаю action здесь тоже. Поэтому, когда я нажму кнопку, земля получит notify. Проблема в том, что я не могу заставить ArrayList<Position> удалить пункт назначения с помощью Action, потому что он не знает, где находится индекс. Я новичок в Java, но много использую C ++, поэтому я подумал об использовании Hashtables, потому что O (1) отличается от C ++ O (log n), и отчасти удобно, потому что в моем текущем коде не так много изменений.

Это понятно?

Ответы [ 4 ]

5 голосов
/ 11 апреля 2011

Вместо этого вы можете использовать IdentityHashMap , хотя это может помочь, если вы сможете объяснить, что именно вы пытаетесь сделать здесь.Это не очень распространенное требование, и если у вас нет веских причин для этого, возможно, вам стоит заняться чем-то другим.

Кстати, Map может содержать только одинзначение для одного ключа.Поэтому после вашего второго вызова map.put первое введенное вами значение уже исчезло.

Редактировать:

Хорошо, я прочитал ваше объяснение и... ну, я до сих пор не совсем понимаю, что ты делаешь.Вот мое лучшее предположение из того, что вы сказали:

  • У вас есть действие под названием "плуг", представленное как String.
  • Вы говорите игроку "пахать".«3 разные земли.
  • Вы хотите иметь возможность отменить это действие для одной земли, не отменяя его для других.
  • Для этого вы пытаетесь отобразить 3 разных экземпляраString «пахать» на Position из 3-х разных земель.

Если это (или что-то подобное) это то, что вы пытаетесь сделать, вот мои мысли:

  • Действие String не должно быть уникальным ... "плуг" - это "плуг", на какой бы земле он ни был сделан.То, что является уникальным, - это сочетание действия, подобного «плугу», и земли, на которой должно выполняться действие.
  • Учитывая, что «плуг» следует рассматривать как нечто вроде «действия»тип".Было бы хорошо использовать enum или что-то подобное для представления типов действий.
  • Класс Action должен содержать "тип действия" и Position.Когда вы нажмете, чтобы отменить это Action, у вас есть необходимые данные прямо здесь.
2 голосов
/ 11 апреля 2011

Класс String переопределяет equals () и hashCode (), так что две строки с одинаковыми символами имеют одинаковый hashCode () и равны.Но сам класс Object имеет метод equals (), который never возвращает true для двух разных объектов.На самом деле не обязательно (и не возможно!), Чтобы хеш-коды были уникальными;они просто должны быть красиво распределены по диапазону возможных значений.

Так что в любом случае: строка не подходит для ваших требований, я согласен;но объект любого другого класса, который не переопределяет equals () и hashCode (), должен быть в порядке.

1 голос
/ 11 апреля 2011

Это очень семантика для Hashmap: ключи уникальны, и каждое значение из домена ключей отображается в самое большее одно значение в Hashmap.

Думайте об этом как о массиве, только о том, что массив индексируется не числами, а произвольными объектами. Вы не можете иметь более одного другого значения с одним и тем же индексом в массиве.

0 голосов
/ 11 апреля 2011

Вы можете рассмотреть возможность создания своего собственного класса для представления ключа и определения собственного хеш-кода по некоторому уникальному идентификатору, возможно, с использованием AtomicLong

...