簡體   English   中英

如果hashmap的所有鍵具有相同的值,那么它如何工作?

[英]How does a hashmap work if all its keys have the same value?

如果我有一個hashmap,請說HashMap<Integer, String> map = new HashMap<>(); 如果我擁有所有值,例如1到100,則全部存儲相同的對象。 在內存中,這將是該對象的100個實例或100個指向一個對象的指針。

為什么?
那么,如果你有一個地圖HashMap<String, Integer> (注意在仿制葯的交換)和字符串是一個字和整數出現的次數,如果我需要在不過等隨機挑選一個詞,這是成正比它的出現次數然后快速的方法就是用“cat”這個詞填充一個arraylist 100次,其余相應的(將hashmap“轉換”成arraylist)這樣當使用list選擇一個隨機數時.get(i)然后它與它的出現成正比。

因此,這將取n個單詞* m出現,這意味着一個巨大的列表。 那么使用HashMap的效率如何呢?

如果確實會有從鍵到指針的指針(當它們重復時),那么地圖肯定是更好的方法。

在查看Map實現之后,Map#put()使用正在處理引用的靜態類Node<K,V>

    static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    V value;
    Node<K,V> next;

    Node(int hash, K key, V value, Node<K,V> next) {
        this.hash = hash;
        this.key = key;
        this.value = value;
        this.next = next;
    } 

例:

    final Map<Integer, Point> map = new HashMap<>();

    final Point xPoint = new Point(0, 0);
    map.put(1, xPoint);
    map.put(2, xPoint);
    map.put(3, xPoint);
    System.out.println(map);
    // modify the point
    System.out.println(xPoint);
    xPoint.setX(555);
    System.out.println(xPoint);
    System.out.println(map);

我試着定義一個自定義的MAp Integer,Point,(自定義點)

    Map<Integer, Point> map = new HashMap<>();

    Point xPoint = new Point(0, 0);
    map.put(1, xPoint);
    map.put(2, xPoint);
    map.put(3, xPoint);
    System.out.println(map);
    // modify the point
    System.out.println(xPoint);
    xPoint.setX(555);
    System.out.println(xPoint);
    System.out.println(map);

正如您所看到的,修改點會影響孔圖,因為所有nodes.V都指向同一個ref。

在我看來,您正在考慮的兩個選項是:

List<String> words = new ArrayList<>();
words.add("cat");
words.add("cat");
...
words.add("cat");

Map<Integer,String> words = new HashMap<>();
words.put(0,"cat");
words.put(1,"cat");
...
words.put(99,"cat");

ListMap都包含對同一String對象(“cat”)的多個引用。 但是, Map需要更多內存,因為它還必須存儲密鑰。

此外,由於HashMap沒有順序,因此您無法輕松獲取給定隨機iMap的第iString值。

因此,您的List解決方案優於您建議的Map<Integer,String>替代方案。

也就是說,您可以構建一個更高效的TreeMap ,它允許您根據其出現次數獲取隨機String

我能想到的一種方式:

TreeMap<Integer,String> map = new TreeMap<>();
map.put(0,"cat");
map.put(100,"dog");

TreeMap表示100次出現的“cat”和20次出現的“dog”。 現在,如果你繪制一個從0到119的隨機數,你可以很容易地檢查它是否落在“貓”或“狗”的范圍內。

例如,如果您繪制數字105,則獲得相應的String

String randomStr = map.ceilingEntry(105).getValue();

剩下的就是將包含出現次數的HashMap<String, Integer>轉換為相應的TreeMap<Integer, String>

HashMap<String, Integer> occurrences = ...
TreeMap<Integer, String> map = new TreeMap<>();
int count = 0;
for (Map.Entry<String,Integer> entry : occurrences.entrySet()) {
    map.put (count, entry.getKey());
    count += entry.getValue();
}

請注意,我使用的是TreeMap而不是HashMap ,以便能夠有效地獲得密鑰大於或等於給定密鑰的條目(無需迭代所有條目)。 這只能在NavigableMap

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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