簡體   English   中英

如何獲取特定的 Map.Entry<k, v> 對於特定的鍵?</k,>

[英]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確實有兩個您應該注意的警告:

  • 不允許 null 密鑰,因此您的NavigableLinkedHashMap也需要不允許 null 密鑰
  • 是不可變的,因此您不能調用setValue

但除此之外,它會像你從支持LinkedHashMap內部獲得Map.Entry一樣工作,它確實履行了ceilingEntryfloorEntry等的合同,因為他們只要求一個“鍵值映射”,而不是不要求它必須像 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM