[英]searching keys of subclass in HashMap
只是試圖做類似的事情:
public class GameMap {
protected HashMap<Sector, Integer[]> mapping;
protected void loadMapFromFile(String fileLocation, int numPlayers) {
.
//Other stuff
.
.
case "ALIENSECT":
Integer[] someValue = {5};
mapping.put(new AlienSector(row, col), someValue);
break;
}
public justATestMethod() {
System.out.println(mapping.containsKey(new Sector(6, 'L')));
}
其中AlienSector
是Sector
的子類。
但是當我嘗試在另一堂課中這樣做時:
mappa.justATestMethod();
結果為“假”。
相反,如果我這樣重寫方法“ justATestMethod()”:
System.out.println(mapping.containsKey(new AlienSector(6, 'L')));
結果為“ true”。
我也更改了“ loadMapFromFile”方法的這一行,獲得“ true”:
case "ALIENSECT":
Integer[] someValue = {5};
mapping.put(new AlienSector(row, col), someValue);
break;
這條路:
case "ALIENSECT":
mapping.put(new Sector(row, col), new Integer[1]);
Integer[] aCazzo = {5};
mapping.put(new AlienSector(row, col), aCazzo);
break;
那就是先用Sector
對象鍵填充HashMap,然后分配AlienSector
對象鍵。
有人可以解釋我為什么會這樣嗎? AlienSector
是的子類Sector
,為什么Java不識別存在Sector
在HashMap的鍵,如果我只要實現它的一個子類,而第一實例化超“部門”本身的istance的關鍵?
您正在將AlienSector存儲在HashMap中,然后嘗試使用使用相同參數創建的另一個Sector來檢索它。 當您嘗試從HashMap檢索對象時, 它正在尋找的對象與您存儲的對象“相等” 。 但是默認情況下,Java不會僅僅因為兩個對象具有相同的成員就將它們識別為“相等”。 默認情況下,僅當它們是相同的對象時它們才相等 (字符串,整數等是特殊情況)。
您需要做的是通過覆蓋'equals'方法來告訴Java具有相同參數的兩個對象是'equal'。 從測試結果看來,您已經為AlienSector完成了此操作。 但是您將需要對Sector和AlienSector都執行此操作,並對其進行安排,以便即使對象具有不同的類,也認為它們是相等的,即AlienSector被視為等於具有相同成員的Sector,而Sector被視為等於一個Sector。具有相同成員的AlienSector。 有關於如何執行此操作的教程。
您還需要重寫hashCode()方法 ,以確保將被視為“相等”的任何兩個對象也返回相同的hashCode。 HashMap使用hashCode過濾器,確定具有不同hashCodes的事物永遠不會相等。
所有這些細節太長了,無法給出這樣的答案。
順便說一句,如果您在containsKey調用中使用了相同的對象 ,而不是創建一個新的對象,您會發現它起作用。
您可以使用下面的類執行此行為。
需要注意的一點是,如果地圖很大,則性能可能不會特別好,但是在大多數情況下,地圖的大小會很小,因此不會對性能產生實際影響。
注意:JDK8 +代碼
本質上,我們為containsKey覆蓋了常規的hashmap類方法,並進行了適當的搜索。
import java.util.HashMap;
import java.util.Optional;
public class PolymorphicHashMap<K extends Class<?>,V> extends HashMap<K,V> {
@Override
public boolean containsKey(Object key) {
return findEntry((K)key).isPresent();
}
@Override
public V get(Object key) {
var entry = findEntry((K)key);
return entry.map(Entry::getValue).orElse(null);
}
private Optional<Entry<K,V>> findEntry(K key) {
return entrySet().stream()
.filter(e -> e.getKey().isAssignableFrom(key))
.findFirst();
}
}
HashMap
使用hashCode()
函數以查找和存儲鍵/值對。
我相信您需要使超類/子類都返回相同的哈希碼,以便能夠在HashMap中查找子類的鍵。
public class AlienSector {
public int hashcode() {
//
// Generate a hashcode unique to this AlienSector object here
//
}
}
public class Sector {
public int hashCode() {
return super.hashCode(); // Return the same hashcode as the super class
}
}
正如評論中指出的那樣,規則是,如果您覆蓋hashCode()
函數,則還需要覆蓋equals()
函數(反之亦然)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.