集合相关面试题
文章目录
一、JAVA中集合和数组的区别
数组:既可以存储基本数据类型,又可以存储引用数据类型,固定长度
集合:集合只能存储引用数据类型(对象),集合也能存储基本数据类型,但是在存储的时候会自动装箱变成对象。长度可变,随元素增加而增长。
二、Collection和Collections的区别
Collection: 是集合类的顶级接口,继承与他的接口主要有 Set 和 List.
Collections:是一个工具类,它包含有各种有关集合操作的静态多态方法,里面包含一些对集合的排序,搜索以及序列化的操作。
三、ArrayList和LinkedList 和Vector的区别
ArrayList:底层实现是数组,不同步,非线程安全,效率高,增删慢,查询快。
LinkedList :底层实现是双向链表,不同步,非线程安全,效率高,增删快,查询慢。
Vector:底层实现是数组,同步,线程安全,效率低,增删慢,查询快。
四、list/set/map的区别
List:一个有序容器,可重复,可插入多个null元素。继承collection接口,查询快,增删慢。
Set:一个无序容器,不可重复,只允许存入一个 null 元素。继承collection接口,查询慢,增删快。
Map:一个无序容器,与collection接口并列,以键值对方式存储,键不可重复,值可重复,允许存入一个null键,多个null值。查询快,增删快;
遍历方式 :(Iterator:EntrySet、KeySet、Values)
五、HashSet和TreeSet和LinkedHashSet区别
HashSet:基于HashMap实现,无序集合,集合元素可以是null,但只能存入一个null
TreeSet:基于TreeMap实现,底层是红黑树,有序集合,根据元素的自然顺序进行排序,不能存放null元素。
LinkedHashSet:基于LinkedHashMap实现,底层是数组+双向链表。有序集合,元素严格按照放入的顺序排列,可以有一个null元素。
六、HashMap和Hashtable的比较
HashMap:线程不安全的,key、value都可以为null,添加元素时,是使用自定义的哈希算法,HashMap默认的容量大小是16;扩容时,每次将容量变为“原始容量x2”。
Hashtable:是线程安全的,key、value都不可以为null,添加元素时,直接采用的key的hashCode()。Hashtable默认的容量大小是11;扩容时,每次将容量变为“原始容量x2 + 1”。
七、HashMap和ConcurrentHashMap区别
HashMap:底层数组+链表实现,可以存储一个null键和多个null值,非线程安全
ConcurrentHashMap:底层采用分段的数组+链表实现,然后在每一个分段上都用 lock 锁进行保护,线程安全,并发性能更好,键值对不允许有 null。
八、HashMap 底层实现原理
1.HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,可以存储一个null键和多个null值。并且不保证映射的顺序。
2.HashMap的底层主要是基于数组和链表来实现的,结合数组和链表的优点。当链表长度超过8时,链表转换为红黑树。
3.HashMap的底层工作原理:HashMap底层是通过采用Entry数组来存储key-value对,每一个键值对组成了一个Entry实体,Entry类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Entry实体,依次来解决Hash冲突的问题,因为HashMap是按照Key的hash值来计算Entry在HashMap中存储的位置的,如果hash值相同,而key内容不相等,那么就用链表来解决这种hash冲突。
1.3HashMap的put实现过程?
我们给put(key, value)方法传递键和值时,它先调用key.hashCode()方法,得到hash值,然后结合数组长度,计算得数组下标,用于找到bucket位置,来储存Entry对象。如果hash值在HashMap中不存在,则执行插入,若存在,则发生碰撞,则插入链表的尾部(尾插法)或者红黑树中(树的添加方式)。
1.4HashMap的get实现过程?
从HashMap中get元素时,首先计算key的hashCode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。
九、HashMap和LinkedHashMap的区别?
HashMap:无序集合,底层主要是基于数组和链表来实现的,遍历速度与容量相关
LinkedHashMap:有序集合,按照放入的顺序排列,遍历速度与实际数据量相关;LinkedHashMap是继承于HashMap,是基于HashMap和双向链表来实现的。
十、ArrayList/LinkedList /HashMap初始大小,add后是多少?(jdk1.8)
ArrayList:初始化大小是 0,第一次使用时大小变为10,扩容后的大小= 原始大小*1.5,若不够,则以最低容量进行扩容
LinkedList :是一个双向链表,没有初始化大小,也没有扩容的机制
HashMap:初始化容量为 16,扩容因子默认0.75,也就是元素达到12的时候会触发扩容,扩容大小是原来的2倍;