2011-03-29 44 views
0

hi 我想創建一個存儲表達式的HashMap(java),這是我創建的一個小對象。 如何選擇使用哪種類型的密鑰?整數和String之間有什麼區別?我想我只是不完全理解HashMap背後的想法,所以我不確定使用什麼鍵。 謝謝!在HashMap中設置密鑰類型,怎麼樣?

回答

0

鍵和它們的相關值都是對象。當你從HashMap中獲取某些東西時,必須將其轉換爲它所表示的實際類型的對象(我們可以這樣做,因爲Java中的所有對象都繼承了Object類)。所以,如果你的鑰匙是字符串,你的價值觀是整數,你會做這樣的事情:

Integer myValue = (Integer)myMap.get("myKey");

但是,您可以使用Java泛型告訴編譯器,你只打算使用字符串和整數:

HashMap<String,Integer> myMap = new HashMap<String,Integer>();

關於HashMap的更多詳細信息,請參閱http://download.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html

3

爪哇HashMap依賴於兩件事情:

  • hashCode()方法,它返回被從密鑰生成和地圖
  • equals(..)方法內使用的整數,它應該是散列一致計算,這意味着如果兩個鍵具有相同的散列碼,而不是可以理解它們是相同的元素。

的具體要求,從Java API doc採取如下:

  • 每當它是一個Java應用程序的執行期間,在同一對象不止一次調用,hashCode方法必須一致地返回相同整數,只要修改了對象的等號比較中沒有使用的信息。該整數不需要從應用程序的一次執行到同一應用程序的另一次執行保持一致。
  • 如果兩個對象根據equals(Object)方法相等,則對這兩個對象中的每個對象調用hashCode方法必須產生相同的整數結果。
  • 根據equals(java.lang.Object)方法,如果兩個對象不相等,則不要求對兩個對象中的每個對象調用hashCode方法必須產生不同的整數結果。但是,程序員應該意識到,爲不相等的對象生成不同的整數結果可能會提高哈希表的性能。

如果您沒有提供任何種類的特定實現,那麼該對象的內存引用將用作哈希碼。這通常是在大多數情況下,好的,但如果你有,例如:

Expression e1 = new Expression(2,4,PLUS); 
Expression e2 = new Expression(2,4,PLUS); 

(其實我不知道你需要什麼你的HashMap所以我只是猜測裏面的地方)

而且,由於它們是兩個不同的對象,但具有相同的參數,它們將具有不同的哈希碼。這可能是或不是你的具體情況的問題。

如果不是隻使用hasmap而不關心這些細節,如果是這樣的話,您將需要提供一種更好的方式來計算您的類的哈希碼和平等。你可以通過遞歸的方式(通過計算哈希碼作爲兒童的哈希碼的結果)或以一種天真的方式(可以通過toString()表示計算哈希碼)來完成。最後,如果你打算只使用簡單的類型作爲鍵(就像你說的整數或字符串),不用擔心,沒有什麼區別。在這兩種情況下,兩個不同的項目將具有相同的哈希碼。一些例子:

assert(new String("hello").hashCode() == new String("hello").hashCode()); 
int x = 123; 
assert(new Integer(x).hashCode() == new Integer(123).hashCode()); 

記住,使用字符串的例子不是一般的真實,就像我之前解釋你,那是隻是因爲字符串的散列碼方法根據字符串本身的內容計算值。

+0

內部運作的很好的解釋,傑克。 – 2011-03-29 18:57:56

+0

「這意味着如果兩個鍵具有相同的哈希碼,而不是它們應該是相同的元素」 - 這個斷言是絕對不正確的。兩個不相等的對象(因此指向不同的值)可以具有相同的散列碼。 – 2011-03-29 19:10:31

+0

我用**應該**這個詞,每個人都知道這不可能是真實的,因爲散列碼中包含的信息不足以區分每一個對象。我們可以說**它是可取的**,即兩個相同的哈希碼指向同一個對象。 – Jack 2011-03-29 19:13:19

0

如果你不想查找表達式,你爲什麼要他們存儲在地圖中? 但是,如果你想,那麼關鍵是你用於查找的項目。

1

關鍵是你用什麼來識別對象。您可能會遇到想要通過名稱來識別數字的情況。

Map<String,Integer> numbersByName = new HashMap<String,Integer>(); 

numbersByName.put("one",Integer.valueOf(1)); 
numbersByName.put("two",Integer.valueOf(2)); 
numbersByName.put("three",Integer.valueOf(3)); 
... etc 

後來的後來,你可以通過做

Integer three = numbersByName.get("three"); 

取出來或者你可能有必要走另一條路。如果你知道你將有整數值,以及所需的名稱,你可以映射整數轉換爲字符串

Map<String,Integer> numbersByValue = new HashMap<String,Integer>(); 

numbersByValue.put(Integer.valueOf(1),"one"); 
numbersByValue.put(Integer.valueOf(2),"two"); 
numbersByValue.put(Integer.valueOf(3),"three"); 
... etc 

而且把它弄出來

String three = numbersByValue.get(Integer.valueOf(3));