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

时间:2017-03-14 09:10:32

标签: java arraylist hashmap

如果我有一个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的效率如何。

如果确实存在从键到值的指针(当它们重复时),那么地图肯定是更好的方法。

2 个答案:

答案 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");

ListMap都包含对同一String对象(“cat”)的多个引用。但是Map需要更多内存,因为它还必须存储密钥。

此外,由于i,您无法轻松获得给定随机String Map的{​​{1}}'iHashMap没有订单。

因此,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。

中实现