Как сделать класс пригодным для использования в различных HashMaps в Java - PullRequest
0 голосов
/ 01 ноября 2011

У меня есть Атрибут класса , который имеет 2 переменные, скажем int a, b ;

Я хочу использовать атрибут класса в двух разных HashSet.

Первый набор хеш-кодов рассматривает объекты как равные, когда значение a одинаково. Но второй хэш-набор считает объекты равными, когда значение b одинаково.

Я знаю, что если I переопределить метод равен , хэш-набор будет использовать переопределенную версию equals для сравнения двух объектов, но в этом случае мне потребуются две разные реализации equals ()

Один из способов состоит в создании двух подклассов атрибута и предоставлении им другого метода равно, но я хочу знать, есть ли лучший способ сделать это так, что мне не нужно создавать подкласс Attribute.

Спасибо.

Ответы [ 6 ]

3 голосов
/ 01 ноября 2011

Одним из возможных решений является не использовать HashSet, а вместо этого использовать TreeSet. Это тот же интерфейс Set, но есть конструктор TreeSet, который позволяет вам передавать Comparator. Таким образом, вы можете оставить класс Attribute без изменений - просто создайте два разных компаратора и используйте его как

Set<Attribute> setA = new TreeSet<Attribute>(comparatorForA);
Set<Attribute> setB = new TreeSet<Attribute>(comparatorForB);

Компаратор выполняет проверку на равенство (например, если compare возвращает 0, объекты равны)

1 голос
/ 03 ноября 2011

Я сделал что-то другое, Вместо использования HashSet , я использовал HashMap , где я использовал int в качестве ключа в первом HashMap, и объект сохраняется как значение. А в другом HashMap я сохранил ключ как int b , а объект как значение.

Это дает мне возможность хешировать обе переменные a и b , поэтому мне не нужно создавать какие-либо подклассы.

А также я получаю O (1) раз вместо O (log n). Но я знаю, что расплачиваюсь, используя больше памяти, но моей главной заботой было время, поэтому я выбрал HashMap вместо TreeSet.

Спасибо всем за ваши комментарии и предложения.

1 голос
/ 01 ноября 2011

К сожалению, нет класса "Эквалайзер", который может переопределить логику equals. Есть такая вещь для сортировки, где вы можете либо использовать естественную сортировку на основе реализации Comparable, либо предоставить собственную Comparator. Я действительно задавался вопросом, почему нет такой вещи для проверок на равенство.

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

РЕДАКТИРОВАТЬ: просто подумал о чем-то ... вы могли бы использовать два Map экземпляра, например, HashMap, первый из которых использовал бы a в качестве ключа, а второй - b в качестве ключа. Это позволит вам обнаружить столкновения. Затем вы можете просто связать атрибут со связанным экземпляром.

0 голосов
/ 01 ноября 2011

Я могу предложить немного хакерское, но менее трудоемкое решение :) Поменяйте местами значения a и b при сохранении во втором хэш-наборе, чтобы уникальность определялась значением b, а затем при чтении класса из hashset меняли значениеи б снова, чтобы сохранить исходное состояние.Таким образом, те же методы equals / hascode будут служить цели.

0 голосов
/ 01 ноября 2011

Простое решение - обойти HashSet и использовать HashMap напрямую. Для первого сохраните каждый Attribute, используя его свойство a в качестве ключа, а для другого используйте b.

0 голосов
/ 01 ноября 2011

Было бы очень легко изменить HashMap и HashSet для принятия стратегий хеширования и проверки на равенство.

public interface Hasher {
    int hashCode(Object o);
}

public interface Equalizer {
    int areEqual(Object o1, Object o2);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...