关于集合框架Map,你所不知道的知识!

    技术2024-10-03  55

    目录

    前言常用Map有哪些对比HashMap和Hashtable 的区别hashCode()和equals()的含义与使用场景实际应用中如何选择HashMap和TreeMap解析Set和Map的关系常见Map的排序规则是怎样的线程安全且效率高的Map是哪个为什么Collections.synchronizedMap是线程安全的从源码分析HashMapHash碰撞链表的长度大于8之后为什么会转换成红黑树为什么ConcurrentHashMap性能比hashtable高结语

    前言

    相信很多同学都了解集合框架Map。但不少同学对Map的了解仅仅限于HashMap,那不妨看看我的这篇文章,或许你会有所收获!

    常用Map有哪些

    答:HashMap、Hashtable、LinkedHashMap、TreeMap、ConcurrentHashMap

    对比HashMap和Hashtable 的区别

    答: HashMap:底层是基于数组+链表实现,属于非线程安全,默认容量是16,允许有空的健和值。

    Hashtable:底层是基于哈希表实现,属于线程安全(加了synchronized),默认容量是11,不允许有null的健和值。

    hashCode()和equals()的含义与使用场景

    答: hashcode():顶级类Object里面的方法,所有的类都是继承Object,返回是一个int类型的数。根据一定的hash规则(存储地址,字段,长度等),映射成一个数组,即散列值。

    equals() :顶级类Object里面的方法,所有的类都是继承Object,返回是一个boolean类型。根据自定义的匹配规则,用于匹配两个对象是否一样,一般逻辑如下:1.判断地址是否一样、2.非空判断和Class类型判断、3.强转、4.对象里面的字段一一匹配。 代码实战如下:

    import java.util.Date; import java.util.Objects; public class User { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int hashCode() { return Objects.hash(age,name); } @Override public boolean equals(Object obj) { if(this == obj) return true; if(obj == null || getClass() != obj.getClass()) return false; User user = (User) obj; return age == user.age && Objects.equals(name, user.name) ; } }

    实际应用中如何选择HashMap和TreeMap

    答: hashMap: 使用散列桶实现(即数组+链表结构),可以实现快速的存储和检索,但是包含无序的元素,适用于在map中插入、删除和定位元素。 ​ treeMap:使用存储结构是一个平衡二叉树,具体实现是红黑树,可以自定义排序规则,要实现Comparator接口,能便捷的实现内部元素的各种排序,但是一般性能比HashMap差,适用于自定义排序规则。

    解析Set和Map的关系

    答:set的核心就是集合中元素不可重复,存储一组唯一的对象。 set中的每一种实现都是对应Map里面的一种封装,HashSet对应的就是HashMap,TreeSet对应的就是TreeMap。

    常见Map的排序规则是怎样的

    答:按照添加顺序排序使用LinkedHashMap,按照自然排序与自定义排序用TreeMap。

    线程安全且效率高的Map是哪个

    答:多线程环境下可以用concurrent包下的ConcurrentHashMap或者使用Collections.synchronizedMap。ConcurrentHashMap虽然是线程安全,但是他的效率比Hashtable要高很多.

    为什么Collections.synchronizedMap是线程安全的

    答:使用Collections.synchronizedMap包装后返回的map是加锁的。

    从源码分析HashMap

    答:HashMap底层是数组+链表+红黑树实现(jdk8才有红黑树)。数组中的每一项都是一个链表,即数组与链表的结合体。在JDK1.8中,链表的长度大于8,链表会转换成红黑树。

    Entry元素是一个key-value的键值对,它持有一个指向下个Entry的引用,每个Entry元素同时也作为当前Entry链表的首节点,也指向了该链表的下个Entry元素。

    Hash碰撞

    答:Hash碰撞是指不同key计算得到的Hash值相同,需要放到同个bucket中。

    链表的长度大于8之后为什么会转换成红黑树

    答:因为数据量少的时候操作数据,遍历线性表比红黑树所消耗的资源少,所以前期采用线性表,等到一定数之后变换到红黑树。

    为什么ConcurrentHashMap性能比hashtable高

    答:ConcurrentHashMap是线程安全的Map, Hashtable类基本上所有的方法都是采用synchronized进行线程安全控制,高并发情况下效率就会降。而ConcurrentHashMap是采用了分段锁的思想提高性能,锁粒度更细化。

    结语

    欢迎大家纠正与补充!

    Processed: 0.014, SQL: 9