簡體   English   中英

在HashMap中搜索子類的鍵

[英]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')));
}

其中AlienSectorSector的子類。

但是當我嘗試在另一堂課中這樣做時:

   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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM