2010-06-15 101 views
6

在Java中,我正在尋找一種將多個鍵映射到相同值的方法。比方說,我有數字0-9的按鍵,而「x」,「y」和「Z」的值如下:用於將多個鍵映射到相同值的Java數據結構

0->y 
1->y 
2->y 
3->x 
4->x 
5->y 
6->z 
7->y 
8->z 
9->z 

現在x,y和z是很長的字符串,我有數百萬個密鑰,所以我無法多次存儲這些字符串。你會怎麼做呢?

我想到的一個想法是創建兩個數組:生成一個人爲的第二個鍵,將原始鍵映射到該鍵,而另一個數組中的鍵是實際值的關鍵。這樣,該值僅存儲一次和原始關鍵仍然可以間接地映射到值:

0->k1 
1->k1 
2->k1 
3->k2 
4->k2 
5->k1 
6->k3 
7->k1 
8->k3 
9->k3 

k1->y 
k2->x 
k3->z 

問題,但:有沒有更好的數據結構呢?

回答

19

任何Map<Integer,String>會做的 - 你只存儲到字符串,而不是它的一個副本的引用,所以沒關係它有多長。

如果您要多次構建相同的字符串值,請使用intern()每次都爲該值獲取相同的String對象。

+0

這很有道理。謝謝。 – eikes 2010-06-15 15:32:07

+3

+1 for'intern()' – 2010-06-15 23:07:17

+0

皮特,夠公平的。我真的沒有時間寫一篇論文,所以我剛剛刪除了評論。 – 2010-06-17 21:52:42

1

我真的不明白這個問題。如果你有一個字符串數組:String[] arr然後只是設置不同的索引到同一個對象 - 也就是使引用相同。

String[] map = new String[10]; 
String x = "foo"; 
String y = "bar"; 
String z = "baz"; 
map[0] = x; 
map[1] = y; 
map[2] = x; 
//... 
2

爲什麼不反轉鍵/值配對?使用設置或數組變量的值:

x->{3, 4} 
y->{0, 1, 2, 5, 7} 
z->{6, 8, 9} 
-1

Java將自動鞏固字符串引用了你,所以你不需要做手工,以節省內存。您可以將鍵/值放在HashMap中。

+1

這不是事實。如果它是一個字面值,編譯器將實習字符串,以便相同的字面值被相同的String對象替換,並且可以手動調用intern(),但Java永遠不會在運行時隱式/自動執行任何操作。一旦你有一個字符串的引用,Java不會將該引用改爲指向幕後的其他引用,並且可以使用'new'關鍵字始終擁有相同字符串的唯一實例。因此,例如,對於從輸入流或用戶輸入讀取的字符串而言,沒有發生這種情況。 – 2010-06-15 15:33:08

1

如果你不喜歡Pete Kirkham的建議(這將是最好的方式,IMO),你可以使用Google Collections(er ... Guava現在)MultiMap

+4

我打算建議MultiMap,但他正在尋找多個映射到相同值而不是相反的鍵。 – Stevko 2010-06-15 15:34:33

0

每個映射條目將使用幾百位代表在理論上可以保持在2

如果密鑰不低於每幾百整數1的訂單上的數量更加密集的值,這將是更快,更小,根本不使用地圖,而是一個數組 - 像Trove TByteArrayList - 其中字節值映射到您的字符串。如果您想要獲得4倍以上的密度,請將4個值組合成一個字節。

這隻有在你得到大量數據時纔有意義 - 但是你說了數百萬個密鑰,所以我認爲它很合適。

相關問題