[英]Using an interface as a key in a hashmap
我嘗試使用接口作為hashMap
中的鍵,以便為多種類型的鍵提供 1 個 map。 以下似乎有效。
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));
}
我不確定是否有一些角落案例會破壞這個 map?
是否存在將接口作為鍵會崩潰的情況? 我可以使用 generics 做得更簡單嗎?
唯一有點不尋常的是equals方法必須比較Bar和Baz對象。 當 Map 只有一種類型的對象時,equals 方法中的this.getClass() == that.getClass
的檢查永遠不會返回 false。 不過,您已經正確地實現了這一點,因此您無需擔心任何事情。
您可能會遇到比您預期更多的 hash 沖突。 假設您有兩個類,它們都有一個 int id 字段並使用Objects.hash(id)
實現 hashCode - 現在具有相同 ID 的不同類的對象具有相同的 hash 代碼。 如果預期會出現此用例,您可以以每個 class 獨有的方式干擾 hash,例如通過將特定於類的常量與 hash 混合:
@Override
public int hashCode() {
return Objects.hash(1, id);
}
...
@Override
public int hashCode() {
return Objects.hash(2, name);
}
理論上,由於hashCode
的不同實現,可能存在更多 hash 沖突導致性能不佳的問題,因此您需要小心,並使用真實數據進行測試。 除此之外,它是一個有效的用例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.