我有一个有3个属性的类。其中一个属性用作唯一键,因此我在equals
和hashcode
方法中使用了一个键。
现在一旦构建了集合,在查找期间,我只有主键(唯一键),我将不得不用唯一键构造一个虚拟对象,并将其他两个值设置为0(默认值)然后我说
Chapter myObject = new Chapter(uniqueKey,0,0);
hashSet.contains(myObject); // This will work.
这是Hashset查找的正确用法吗?还有其他更好的方法,因为我不喜欢在对象上设置虚假值。
答案 0 :(得分:4)
使这个更简洁的一种方法是定义一个Chapter()
构造函数,该构造函数接受uniqueKey
参数并填充其余参数,然后使用:
hashSet.contains(new Chapter(uniqueKey));
因为你正在扔掉这个物体。
但是,由于您有一个uniqueKey
,我认为Chapter
的每个实例都是HashMap
,您是否考虑使用uniqueKey
?然后你可以使用hashMap.containsKey(uniqueKey);
作为密钥,你只需要检查密钥是否存在(例如:使用HashMap.containsKey()
)或不是:
.get()
使用HashMap,您还可以使用Chapter c = hashMap.get(uniqueKey);
获取所需的对象:
Chapter
如果提供的uniqueKey
映射到某个对象,则会为您提供null
对象,如果没有,则为{{1}}。
答案 1 :(得分: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);
...只需创建一个Key实例即可查询地图:
if (foosByKey.contains(new Foo.Key("Hello", 5))) {
System.err.println("BOOM!");
}
答案 2 :(得分:1)
如果你想要查找,你可能最好使用HashMap而不是HashSet。然后你可以使用主键作为地图中的键,并将对象作为值,然后就可以了
MyObject o = map.get(myKey);
答案 3 :(得分:1)
你的方法似乎有点圆了。为什么不保留一组钥匙?或者,如果您需要通过密钥访问该对象,则应使用HashMap
,而不是HashSet
。