HashMap相关问题

    xiaoxiao2023-10-21  163

    有关HashMap的相关知识点

    JDK8中的HashMap有哪些改动

    引入红黑树优化HashMap的性能,通过数组+链表+红黑树实现;

    在JDK1.8中,优化了高位运算的算法,通过hashCode()的高16位异或低16位实现:(h = k.hashCode()) ^ (h >>> 16)

    为什么重写Equals方法时需要重写HashCode方法,与HashMap有什么关系

    equals方法

    equals方法在Object类中默认的实现方式是: return this == obj  。也就是说只有this 和 obj引用同一个对象,才会返回true。

    而我们往往需要用equals来判断 2个对象是否等价,而非验证他们的唯一性。这样我们在实现自己的类时,就要重写equals。

    hashCode方法

    这个方法返回对象的散列码,返回值是int类型的散列码。

    重写hashCode时注意事项

    重写hashCode方法时除了上述一致性约定,还有以下几点需要注意:

    (1)返回的hash值是int型的,防止溢出。

    (2)不同的对象返回的hash值应该尽量不同。(为了hashMap等集合的效率问题)

    如果两个对象根据equals方法比较是相等的,那么调用这两个对象的任意一个hashcode方法都必须产生相同的结果。

    如果不重写hashcode在我们调用HashSet和HashMap的时候可能会造成歧义,也就是用equals方法判断的两个对象相等,但是hashcode不相等,会造成hashmap散列到不同数组下标,导致了哈希表中有两个相同的key。

    重写 hashcode 方法是为了让我们能够正常使用 HashMap 等集合类,因为 HashMap 判断对象是否相等既要比较 hashcode 又要使用 equals 比较。HashMap 的链表结构中遍历判断的时候,特定情况下重写的 equals 方法比较对象是否相等的业务逻辑比较复杂,循环下来更是影响查找效率。所以这里把 hashcode 的判断放在前面,只要 hashcode 不相等就玩儿完,不用再去调用复杂的 equals 了。这样的实现是为了提高 HashMap 的效率。

    HashMap是线程安全的么?出现ConcurrentModificationException时如何处理

    HashMap并非线程安全,多线程使用时,会导致值覆盖,会导致ConcurrentModificationException异常。

    如果modCount不等于expectedModCount,则抛出ConcurrentModificationException异常

    处理方法:

    1、在使用iterator迭代的时候使用synchronized或者Lock进行同步;

    2、使用并发容器。

    Java中线程安全的map的实现方式:

    HashTableSynchronized MapConcurrentHashMap

    使用HashMap需要注意哪些问题?

    1、注意线程安全,避免出现ConcurrentModificationException异常;

    2、重写equals方法后需要同时改写hashcode方法;

    HashMap工作原理

     HashMap是基于哈希表的Map接口的非同步实现。

    1、利用key的hashCode重新hash计算出当前对象的元素在数组中的下标

    2、存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value放入链表中

    3、获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。

    4、HashMap是解决hash冲突的核心是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。

    HashMap中的“死锁”

    在并发的情况下,发生扩容时,可能会产生循环链表,在执行get的时候,会触发死循环,引起CPU的100%问题。

    HashMap可以put两个相同的Key么?为什么

    不可以

    put操作调用putval方法,先判断Hash是否一致,然后在判断传入key和当前集合中是否有相同的key。如果key相同,则新值替换旧值。

    如果想要实现在HashMap中插入两个相同的Key,需要重写HashMap的put方法或者重写对象的equals方法和hashcode方法。

    这里记录一个通过创建新的MyHashMap类实现插入两个相同的key的功能的方法。

    MyHashMap类继承HashMap类,重写put方法:

    import java.util.HashMap; public class MyHashMap<O, O1> extends HashMap { @Override public Object put(Object key, Object value) { String newV = value.toString(); if (containsKey(key)) { String oldV = get(key).toString(); newV = oldV + "---" + newV; } return super.put(key, newV); } }

    测试:

    import java.util.*; public class Test { public static void main(String[] args) { Map<Object, Object> map = new MyHashMap<Object, Object>(); map.put(1, 12); map.put(1, 13); map.put("长沙", "出美女"); map.put("长沙", "风景美"); Iterator it = map.entrySet().iterator(); while(it.hasNext()){ Map.Entry entry = (Map.Entry) it.next(); System.out.println(entry.getKey()+" "+ entry.getValue()); } } }

    结果:

    HashMap中的键值可以为null么;为什么

    1、HashMap计算key的hash值时调用单独的方法,在该方法中会判断key是否为null,如果是则返回0;而Hashtable中则直接调用key的hashCode()方法,因此如果key为null,则抛出空指针异常;

    2、HashMap将键值对添加进数组时,不会主动判断value是否为null;而Hashtable则首先判断value是否为null。

    3、以上原因主要是由于Hashtable继承自Dictionary,而HashMap继承自AbstractMap。

    4、虽然ConcurrentHashMap也继承自AbstractMap,但是其也过滤掉了key或value为null的键值对。

    hashMap的扩容原理是什么?JDK8与JDK7有什么区别

    hashmap中的元素个数超过数组大小*loadFactor(负载因子)时,就会进行数组扩容,loadFactor的默认值为0.75,如果过小,比如0.5,那么当存放的元素超过一半时就进行扩容,会造成资源的浪费;如果过大,比如1,那么当元素满的时候才进行扩容,会使get,put操作的碰撞几率增加。

     JDK1.8引入红黑树大程度优化了HashMap的性能;

     JDK1.8中的HashMap存储结构是由数组、链表、红黑树这三种数据结构形成,红黑树查询删除快新增慢。根据key的hash与table长度确定table位置,同一个位置的key以链表形式存储,超过一定限制链表转为树。

    参考链接:

    https://www.jianshu.com/p/75d9c2c3d0c1

    https://www.cnblogs.com/ouym/p/8963219.html

    https://blog.csdn.net/xjh1997/article/details/81368371

    https://www.cnblogs.com/dolphin0520/p/3933551.html

    https://www.cnblogs.com/yuanblog/p/4441017.html

    https://www.cnblogs.com/aflyun/p/10733029.html

    https://blog.csdn.net/qq_29373285/article/details/84999671

    https://blog.csdn.net/shenjianzhuang/article/details/79033054

    https://blog.csdn.net/gaozongjian/article/details/82911141

    https://blog.csdn.net/u012156116/article/details/81206649

    https://blog.csdn.net/wanderlustLee/article/details/80747860

    http://www.importnew.com/20386.html

    这些东西内容还是相当多的。。。。。

    最新回复(0)