[英]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");
}
});
我需要一種方法來比較HashMap
鍵和ArrayList
元素。 如果密鑰相等,則應將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
接口( TreeMap
、 LinkedHashMap
等)的任何實現。 此方法返回 class UnmodifiableMap
的一個實例,它實現Map
接口(即它覆蓋了所有必需的方法)並維護了一個類型為Map
的變量(作為參數傳遞的包裝的 map )並委托調用它。 本質上UnmodifiableMap
和HashMap
是兄弟姐妹,它們都實現Map
,但它們不相互擴展,因此您不能在這些類型之間進行轉換。
補救措施:針對接口而不是具體類型編寫代碼,您會沒事的。 CONSTANT_MAP
的類型應該是Map
,而不是HashMap
(順便說一下,我建議使用更有意義的名稱,比如ganreById
)。 同樣,您的方法的參數應該是List
,而不是ArrayList
。
我需要一種方法來比較
HashMap
鍵和ArrayList
元素。 如果密鑰相等,則應將Hashmap
值放入單獨的ArrayList
並返回。
首先,從 map 的內容來看,我相信你拼錯了方法名稱,你的意思是genre
,而不是gender
。 在下面的代碼中,我更改了它以及參數名稱(當然,名稱完全取決於您,這只是一個示例,但請記住它們對代碼的可讀性有巨大影響,因此很重要) 和參數類型更改為接口類型List
和Map
。
處理此任務的最有效方法是遍歷列表並檢查特定元素是否包含在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;
}
旁注:
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());
}
另請注意抽象類型(例如List
、 Map
等)優先於具體類型(例如ArrayList
、 HashMap
等)的使用:參見里氏替換原則 (LSP)
還要注意將方法名稱中的拼寫錯誤從getGender
更正為getGenres
,更正語義和復數形式——返回集合的方法應以復數形式命名。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.