[英]How to get a specific Map.Entry<K, V> for a specific key?
我正在實現NavigableMap
-在 Java 中實現LinkedHashMap
。 ( LinkedHashMap
沒有實現NavigableMap
似乎沒有很多(任何?)原因,但我離題了......)
我通過迭代entrySet()
編寫了lowerKey()
、 lowerEntry()
、 higherKey()
和higherEntry()
)。 在這些情況下,我看不到任何方法可以避免迭代整個entrySet()
。
對於floorKey()
、 floorEntry()
、 ceilingKey()
和ceilingEntry()
,如果密鑰存在,我想避免迭代entrySet()
的費用,因為我已經可以使用普通的get()
。
有沒有辦法獲得Map.Entry
特定鍵,而不僅僅是值? 謝謝。
你可以做這樣的事情。
Map<String,Integer> map = Map.of("Foo", 123, "Bar", 234);
Function<String, Entry<String,Integer>> getEntry =
getEntryFnc(map);
System.out.println(getEntry.apply("Foo"));
System.out.println(getEntry.apply("Bar"));
System.out.println(getEntry.apply("Baz"));
印刷
Foo=123
Bar=234
Baz=null
返回一個 lambda,它使用提供的密鑰和 map 構建一個條目。
public static <K,V> Function<K, Entry<K,V>> getEntryFnc(Map<K,V> map) {
return key->
new AbstractMap.SimpleEntry<>(key, map.get(key));
};
}
您有密鑰,您可以使用get
與密鑰關聯的值,現在您要做的就是創建一個Map.Entry
,我們可以使用Map.entry
工廠方法來做到這一點:
var value = theBackingLinkedHashMap.get(key);
if (value == null) {
return null;
}
return Map.entry(key, value);
entry 返回的entry
確實有兩個您應該注意的警告:
NavigableLinkedHashMap
也需要不允許 null 密鑰setValue
。 但除此之外,它會像你從支持LinkedHashMap
內部獲得Map.Entry
一樣工作,它確實履行了ceilingEntry
、 floorEntry
等的合同,因為他們只要求一個“鍵值映射”,而不是不要求它必須像 map 本身或類似的東西那樣具有可變性。 例如,這是ceilingEntry
:
返回與大於或等於給定鍵的最小鍵關聯的鍵值映射,如果沒有這樣的鍵,則返回 null。
我會使用 TreeSet 將鍵保存在 NavigableMap class 中。 請參見下面的示例:
import java.util.*;
public class Main{
public static void main(String[] args) {
NavMap<Integer, String> map = new NavMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(4, "four");
map.put(10, "ten");
System.out.println(map.lowerKey(3)); //2
System.out.println(map.higherKey(3)); //4
System.out.println(map.ceilingKey(7)); //10
System.out.println(map.floorKey(7)); //4
}
}
class NavMap<K extends Comparable,V extends Comparable> extends LinkedHashMap<K,V>{
private TreeSet<K> keys = new TreeSet<>();
public K lowerKey (K key){ return keys.lower(key); }
public K higherKey (K key){ return keys.higher(key); }
public K floorKey (K key){ return keys.floor(key); }
public K ceilingKey(K key){ return keys.ceiling(key);}
public V put(K key, V value){
keys.add(key);
return super.put(key, value);
}
}
@Sweeper對他的回答的評論讓我思考。 我想出的解決方案是在我的 class 中從Key
to Entry
維護一個Map
。 這樣我就有了O(1)
訪問entrySet
的方法。 像這樣:
Map<K, Map.Entry<K, V>> entryMap = new HashMap<>();
for(final currentEntry : entrySet())
{
entryMap.put(currentEntry.getKey(), currentEntry);
}
每次運行更改keySet
的操作時,我只需要更新此Map
。 我只需要更新Map
中會受到影響的一個條目。 聽起來好像不會很貴。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.