如何解决使用接口作为哈希图中的键
我试图在hashMap
中使用接口作为键,以便为多种类型的键提供1个映射。以下似乎有效。
interface Foo {
void function();
}
static class Bar implements Foo {
private int id;
public Bar(int id) {
this.id = id;
}
@Override
public void function() {
System.out.println("this is bar");
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Bar bar = (Bar) o;
return id == bar.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
public static Map<Foo,Integer> map = new HashMap<>();
static class Baz implements Foo {
String name;
public Baz(String name) {
this.name = name;
}
@Override
public void function() {
System.out.println("this is Baz");
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Baz baz = (Baz) o;
return name.equals(baz.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public static void main(String[] args) {
Bar bar = new Bar(123);
Baz baz = new Baz("some name");
map.put(bar,10);
map.put(baz,20);
System.out.println(map.get(bar));
}
我不确定是否有一些极端情况会破坏这张地图?
是否存在接口作为键会失效的情况?我可以使用泛型更简单吗?
解决方法
理论上,由于hashCode
的不同实现,散列冲突可能会导致更多问题,从而导致性能下降,因此您需要格外小心,并使用真实数据进行测试。除此之外,这是一个有效的用例。
唯一与众不同的是equals方法必须比较Bar和Baz对象。当Map仅具有一种类型的对象时,equals方法中的校验this.getClass() == that.getClass
永远不会返回false。不过,您已经正确实施了此操作,因此您无需担心任何事情。
您可能会得到比预期更多的哈希冲突。假设您有两个类都具有一个int id字段,并使用Objects.hash(id)
实现hashCode-现在,具有相同ID的不同类的对象具有相同的哈希码。如果预期会出现这种用例,则可以通过每个类唯一的方式来干扰哈希,例如,将特定于类的常量混合到哈希中:
@Override
public int hashCode() {
return Objects.hash(1,id);
}
...
@Override
public int hashCode() {
return Objects.hash(2,name);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。