如果我有一个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的效率如何。
如果确实存在从键到值的指针(当它们重复时),那么地图肯定是更好的方法。
答案 0 :(得分:2)
查看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都指向相同的参考。
答案 1 :(得分:1)
在我看来,您正在考虑的两个选项是:
List<String> words = new ArrayList<>();
words.add("cat");
words.add("cat");
...
words.add("cat");
VS
Map<Integer,String> words = new HashMap<>();
words.put(0,"cat");
words.put(1,"cat");
...
words.put(99,"cat");
List
和Map
都包含对同一String对象(“cat”)的多个引用。但是Map
需要更多内存,因为它还必须存储密钥。
此外,由于i
,您无法轻松获得给定随机String
Map
的{{1}}'i
值HashMap
没有订单。
因此,List
解决方案优于您建议的Map<Integer,String>
替代方案。
也就是说,您可以构建一个更高效的TreeMap
,以便根据其出现次数获得随机String
。
我能想到的一种方式:
TreeMap<Integer,String> map = new TreeMap<>();
map.put(0,"cat");
map.put(100,"dog");
此TreeMap
代表100次出现的“猫”和20次出现的“狗”。现在,如果你绘制一个从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
s。