[英]What's the idiomatic way to build a HashMap from a Set of keys (all of which have the same value)
[英]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");
List
和Map
都包含對同一String對象(“cat”)的多個引用。 但是, Map
需要更多內存,因為它還必須存儲密鑰。
此外,由於HashMap
沒有順序,因此您無法輕松獲取給定隨機i
的Map
的第i
個String
值。
因此,您的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.