我使用 JavaHashSet
来存储唯一元素,但现在我想检索元素,但 HashSet 没有类似的东西,这是我想要解决的问题:
对于我的用例LinkInfo
哈希代码(( 和 equals(( 方法不使用 LinkInfo.id字段我想从集合中获取 linkinfo 实例并更新其所有字段,除了应该来自旧实例的 id 字段
Set<LinkInfo> fooSet = new HashSet<>()
public void updateFoo(LinkInfo linkInfo) {
LinkInfo temp = fooSet.get(linkInfo);
linkInfo.setId(temp.getId());
// now update set
fooSet.remove(linkInfo)
fooSet.add(linkInfo)
}
而不是
LinkInfo temp = fooSet.get(linkInfo);
下面的逻辑与你似乎想要的相同
if (fooSet.contains(linkInfo)) {
temp = linkInfo;
}
我不知道你为什么要这样做,但要回答这个问题,是的,你可以这样做,但你应该使用地图,就像这样:
import java.util.HashMap;
import java.util.Map;
public class Main {
static class Test {
public int a,b;
public Test(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public boolean equals(Object obj) {
Test that = (Test)obj;
return this.a == that.a && this.b == that.b;
}
@Override
public int hashCode() {
return a ^ b;
}
}
public static void main(String[] args) {
Map<Test,Test> map = new HashMap<>();
Test t = new Test(1,2);
System.out.println(System.identityHashCode(t));
map.put(t, t);
Test t2 = new Test(1,2);
System.out.println(System.identityHashCode(t2));
System.out.println(System.identityHashCode(map.get(t2)));
}
}
现在,您可以通过与该映射相等的实例检索最初放入该映射的实例。
程序打印:
475266352
1355531311
475266352
在我的电脑上。您可以使用 HashSet 并遍历它以获得相同的结果,但它不会是 O(1(。
你这里有一点逻辑问题。 为什么依赖equals()
的 API 应该提供方法getElementEqualTo(e)
? 为了使用这样的方法,您需要提供一个对象,就 API 而言,该对象等效于所需结果。 这有什么意义呢?
但这并不意味着你不走运。 我想你是说你的LinkInfo
类提供了hashCode()
和equals()
的方法,适合通过你可以获得的不同对象来识别你想要的对象。 在这种情况下,听起来HashMap
可以满足您的目的。 只需将每个键映射到自身即可。
HashMap<LinkInfo, LinkInfo> infos;
public void updateInfo(LinkInfo linkInfo) {
LinkInfo temp = infos.remove(linkInfo);
if (temp != null) {
linkInfo.setId(temp.getId());
}
infos.put(linkInfo, linkInfo);
}
我同意上面的 Scary 答案,但如果您想要存储在 Set 中的确切引用而不是类似的equal
对象,您可以使用以下代码:
public void updateFoo(LinkInfo linkInfo) {
LinkInfo temp = null;
for(LinkInfo curLinkInfo:fooSet) if (curLinkInfo.equals(linkInfo))temp = curLinkInfo;
if(temp!=null)
linkInfo.setId(temp.getId());
// now update set
fooSet.remove(linkInfo)
fooSet.add(linkInfo)
}