2010-08-19 27 views
19

假設我有在Java中的地圖看起來像這樣:獲取Java中的鍵的值

{ 
39:"39 to 41", 
41:"41 to 43", 
43:"43 to 45", 
45:">=45" 
} 

如果密鑰是按排序順序(使用樹形圖或者LinkedHashMap)。現在,如果我嘗試得到> = 39和< 41.然後我應該得到字符串「39到41」。我該如何有效地做到這一點?

+0

你的意思是'<= 41'我猜。但是你會一直尋找'39,41,43,45'還是應該用'ex'40,42,50'來試試?中間總是隻有一個? – 2010-08-19 08:25:45

+0

[可將一系列鍵映射到值的數據結構]的可能重複(https://stackoverflow.com/questions/13399821/data-structures-that-map-a-range-of-keys-to - 值) – Vadzim 2017-05-24 11:17:03

回答

52

它看起來像你想要超過SortedMap;你想要一個NavigableMap!具體而言,您可以使用floorKey操作。

下面是一個例子:

NavigableMap<Integer,String> map = 
     new TreeMap<Integer, String>(); 

    map.put(0, "Kid"); 
    map.put(11, "Teens"); 
    map.put(20, "Twenties"); 
    map.put(30, "Thirties"); 
    map.put(40, "Forties"); 
    map.put(50, "Senior"); 
    map.put(100, "OMG OMG OMG!"); 

    System.out.println(map.get(map.floorKey(13)));  // Teens 
    System.out.println(map.get(map.floorKey(29)));  // Twenties 
    System.out.println(map.get(map.floorKey(30)));  // Thirties 
    System.out.println(map.floorEntry(42).getValue()); // Forties 
    System.out.println(map.get(map.floorKey(666))); // OMG OMG OMG! 

注意,也有ceilingKeylowerKeyhigherKey,也…Entry代替…Key操作以及返回一個Map.Entry<K,V>而不只是K

+2

我不知道這一點,顯然也沒有任何人在這裏。很酷! – 2010-08-19 09:53:20

+3

全部歡呼標準運行時! – 2012-06-18 10:32:18

+1

有時候我覺得我認識Java,然後遇到類似這樣的事情,我的頭腦被吹走了。 – Jyro117 2013-10-23 19:46:06

0

我不確定那會很容易。一個建議是「填補空白」,即輸入一個值40->"39 to 41"等等。我想這隻有在你知道地圖中可能的整個數字範圍時纔有可能。

或mabybe的東西,它會覆蓋get來檢查值是否在地圖中,並展開直到找到某些東西。我不確定這會以它當前的僞裝出現,因爲你必須最終解析值字符串。

0

您可以遞歸查找下邊界。

public String descriptionFor(int value) { 
    String description = map.get(value); 
    return description == null ? descriptionFor(value--) : description; 
} 

您將需要有一個最小邊界。

1

有了一個有序映射,你可以做這樣的事情:

SortedMap<Integer,String> head = map.headMap(value+1); 
if (head.isEmpty()) { 
    return null; 
} else { 
    return head.get(head.lastKey()); 
} 
0

你必須自己實現這樣的地圖,我相信。你是對的,它必須被排序; get的實現將不得不迭代通過鍵直到找到小於或等於參數的最大鍵。

如果你繼承TreeMap它最初似乎可以通過簡單覆蓋get()方法來獲得此工作。但是,爲了儘可能多地維護Map合約,您必須重寫其他方法以保持一致性。

那又如何呢? containsKey()?您的主要包含40的映射嗎?如果您返回false,則客戶可以決定不根據此信息致電get();由於這些原因(和正式的定義),你必須返回true。但是,這使得很難確定地圖是否「真正包含」給定的映射;如果你想要做一些更新而不覆蓋已經存在的東西。

remove()方法可能也很棘手。從我的閱讀界面,

// Calling map.remove "Removes the mapping for a key from this map if it is present." 
map.remove(x); 

// Now that the mapping is removed, I believe the following must hold 
assert map.get(x) == null; 
assert map.containsKey(x); 

代理一直在這裏會非常棘手。例如,如果你有一個35-40的映射,並且你打電話給remove(38),那麼據我所知,你必須返回null以獲得任何後續的密鑰38,但返回前面提到的密鑰35-37或39的映射-40。


因此,儘管你可以通過重載TreeMap的就這個一個開始,或許Map整個概念是不是你想要在這裏相當的東西。除非您需要此行爲才能插入採用Map的現有方法,否則您可能更容易將其創建爲獨特的類,因爲它不是完全是 a地圖,您定義它的方式。