簡體   English   中英

將 Map 中的鍵與 java 中列表中的元素進行比較

[英]Compare keys in a Map with elements in a List in java

我有一個 static HashMap <Integer, String>和一個Arraylist<Integer>

public static final HashMap<Integer, String> CONSTANT_MAP =
    (HashMap<Integer, String>) Collections.unmodifiableMap(new HashMap<Integer, String>() {
        {
            put(28, "Action");
            put(12, "Adventure");
            put(16, "Animation");
            put(35, "Comedy");
            put(80, "Crime");
            put(99, "Documentary");
            put(18, "Drama");
            put(10751, "Family");
            put(14, "Fantasy");
            put(36, "History");
            put(27, "Horror");
            put(10402, "Music");
            put(9648, "Mystery");
            put(10749, "Romance");
            put(878, "Science Fiction");
            put(10770, "TV Movie");
            put(53, "Thriller");
            put(10752, "War");
            put(37, "Western");
        }
    });

我需要一種方法來比較HashMapArrayList元素 如果密鑰相等,則應將Hashmap值放入單獨的ArrayList並返回。

我嘗試了以下,但它不起作用。 我得到ExceptionInInitializerError

public static ArrayList<String> getGender(ArrayList<Integer> arrayList, HashMap<Integer, String> hashMap) {
    ArrayList<String> resultList = new ArrayList<String>();
    for (Map.Entry m : hashMap.entrySet()) {
        if (arrayList.contains(m.getValue()))
            resultList = (ArrayList<String>) m.getValue();
    }
    return resultList;
} 

我得到ExceptionInInitializerError

此錯誤由static字段初始化期間或執行static 初始化程序塊時發生的異常觸發。 來自Javadoc的引述:

拋出ExceptionInInitializerError以指示在評估 static 初始化程序或 static 變量的初始化程序期間發生異常。

在這種情況下,您試圖將unmodifiableMap()返回的 map 類型轉換為HashMap ,但此轉換失敗。 它無法成功,因為unmodifiableMap()旨在包裝Map接口( TreeMapLinkedHashMap等)的任何實現。 此方法返回 class UnmodifiableMap的一個實例,它實現Map接口(即它覆蓋了所有必需的方法)並維護了一個類型為Map的變量(作為參數傳遞的包裝的 map )並委托調用它。 本質上UnmodifiableMapHashMap兄弟姐妹,它們都實現Map ,但它們不相互擴展,因此您不能在這些類型之間進行轉換。

補救措施:針對接口而不是具體類型編寫代碼,您會沒事的。 CONSTANT_MAP的類型應該是Map ,而不是HashMap (順便說一下,我建議使用更有意義的名稱,比如ganreById )。 同樣,您的方法的參數應該是List ,而不是ArrayList

我需要一種方法來比較HashMap鍵和ArrayList元素。 如果密鑰相等,則應將Hashmap值放入單獨的ArrayList並返回。

首先,從 map 的內容來看,我相信你拼錯了方法名稱,你的意思是genre ,而不是gender 在下面的代碼中,我更改了它以及參數名稱(當然,名稱完全取決於您,這只是一個示例,但請記住它們對代碼的可讀性有巨大影響,因此很重要) 和參數類型更改為接口類型ListMap

處理此任務的最有效方法是遍歷列表並檢查特定元素是否包含在map中。

不像你在代碼中所做的那樣相反,因為contains()檢查在列表上是昂貴的(你需要遍歷所有元素以找出匹配元素是否存在),如果你是O(n)時間熟悉大 O符號。 相反, containsKey()檢查HashMap幾乎是即時的 - O(1)

如果匹配的鍵存在,與之關聯的值將被添加到結果列表中。

public static List<String> getGenre(List<Integer> ids, 
                                    Map<Integer, String> genreById) {

    List<String> result = new ArrayList<>();
    for (Integer id: ids) {
        if (genreById.containsKey(id))
            result.add(genreById.get(id));
    }
    return result;
}

旁注:

  • 如果此方法駐留在相同的 class 中,其中map被定義為 static 字段,則將其作為參數傳遞是多余的。
  • 您可以用 static 方法 Map.ofEntries() 替換雙花括號初始化(這被認為不是一個好習慣Map.ofEntries()可通過 Java 訪問 9. 它返回一個 map,它已經不可修改,因此不需要用Collections.unmodifiableMap()包裝它。

好吧,如果你只是想檢查 hashmap 中的鍵是否等於 arraylist,你可以使用hashMap.keySet().equals(new HashSet<Integer>(arrayList)) ,然后使用hashMap.values()來獲取所有的值。

Alexander Ivanchenko 的回答正確地確定了您所看到的異常的原因(因此您應該接受他的回答。)。 我的回答在下面討論了您的代碼的其他問題。


您的 hashmap 包含字符串值:

    HashMap<Integer, String> hashMap

所以

    m.getValue()

是一個字符串,因此您不能將它轉換為 ArrayList 個字符串

    resultList = (ArrayList<String>) m.getValue();

我認為您想要的是在結果列表中累積值:

   resultList.add(m.getValue());

此外,正如@racraman 所指出的,這種比較是有問題的:

   if (arrayList.contains(m.getValue())

列表arrayList包含整數; m.getValue() 是一個字符串; 我很驚訝這個編譯。 我認為從你的意思描述

    if (arrayList.contains(m.getKey())

所以寫這篇文章時可能是轉錄錯誤?

長話短說,使用 collections 庫為您完成工作:

public static List<String> getGenres(List<Integer> list, Map<Integer, String> map) {
    return map.entrySet().stream()
        .filter(e -> list.contains(e.getKey()))
        .map(Map.Entry::getValue)
        .collect(Collectors.toList());
}

另請注意抽象類型(例如ListMap等)優先於具體類型(例如ArrayListHashMap等)的使用:參見里氏替換原則 (LSP)

還要注意將方法名稱中的拼寫錯誤從getGender更正為getGenres ,更正語義和復數形式——返回集合的方法應以復數形式命名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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