#java #set
#java #установить
Вопрос:
У меня есть класс с 3 атрибутами. Один из атрибутов используется в качестве уникального ключа, поэтому я использую этот единственный ключ в своем методе equals
and hashcode
.
Теперь, когда набор собран, во время поиска у меня есть только первичный ключ (уникальный ключ), и мне придется создать фиктивный объект с уникальным ключом и установить два других значения равными 0 (значения по умолчанию), а затем я говорю
Chapter myObject = new Chapter(uniqueKey,0,0);
hashSet.contains(myObject); // This will work.
Правильно ли это использование для поиска по Hashset? Есть ли какой-либо другой лучший способ, потому что я не любитель устанавливать фиктивные значения для объекта.
Ответ №1:
Один из способов сделать это менее подробным — определить Chapter()
конструктор, который принимает uniqueKey
аргумент и заполняет остальные, а затем использовать:
hashSet.contains(new Chapter(uniqueKey));
Поскольку вы в любом случае выбрасываете объект.
Однако, поскольку у вас есть a uniqueKey
, который, я полагаю, уникален для каждого экземпляра a Chapter
, рассматривали ли вы возможность использования a HashMap
вместо этого? Тогда вы могли бы просто использовать uniqueKey
в качестве ключей, и вам просто нужно было бы проверить, присутствует ли ключ (например: используя HashMap.containsKey()
) или нет:
hashMap.containsKey(uniqueKey);
С помощью HashMap вы также можете просто получить нужный объект с помощью .get()
:
Chapter c = hashMap.get(uniqueKey);
Это даст вам Chapter
объект, если предоставленный uniqueKey
сопоставляется с объектом, или null
если нет.
Ответ №2:
Обычно в этой ситуации вам следует рассмотреть возможность рефакторинга ваших ключевых полей в отдельный класс ключей, а затем использовать HashMap
вместо HashSet
. Это позволяет избежать необходимости создавать весь фиктивный объект; все, что требуется, это создать экземпляр ключа.
Пример
public class Foo {
public static class Key {
private final String s;
private final int i;
public Key(String s, int i) {
this.s = s;
this.i = i;
}
// TODO: Implement equals / hashCode.
}
private final Key key;
private final double d;
public class Foo(String s, int i, double d) {
this(new Key(s, i), d);
}
public class Foo(Key key, double d) {
this.key = key;
this.d = d;
}
public Key getKey() { return key; }
// TODO: Implement equals / hashCode to delegate to Key.
}
Затем объекты создаются и добавляются на карту следующим образом:
Foo foo1 = new Foo("Hello", 5, 10.0);
Foo foo2 = new Foo("Goodbye", 10, 20.0);
Map<Foo.Key, Foo> foosByKey = new HashMap<Foo.Key, Foo>();
foosByKey.put(foo1.getKey(), foo1);
foosByKey.put(foo2.getKey(), foo2);
… и к карте можно запросить, просто создав экземпляр ключа:
if (foosByKey.contains(new Foo.Key("Hello", 5))) {
System.err.println("BOOM!");
}
Ответ №3:
Если вам нужен поиск, возможно, вам лучше использовать HashMap вместо HashSet. Затем вы можете использовать свой первичный ключ в качестве ключа на карте, а объект в качестве значения, тогда вы можете сделать
MyObject o = map.get(myKey);
Ответ №4:
Ваш подход кажется немного обходным. Почему бы просто не сохранить набор ключей? Или, если вам нужен доступ к объекту через ключ, тогда вам следует использовать HashMap
, а не HashSet
.