1. Java 中常用的容器有哪些?
两大类:collection和map
collection:
list:ArrayList,LinkedList,Vector,Stack
set:HashSet,LinkedHashSet,TreeSet
queue
map:HashMap,TreeMap,ConcurrentHashmap,HashTable
2. ArrayList 和 LinkedList 的区别?
ArrayList是基于数组实现的,是一个可以动态修改的数组,没有固定的大小限制,可以添加或删除元素。
LinkedList底层是基于链表实现的,是一种线性表。
ArrayList更适合于查找,LinkedList适合于删除和添加。
3. ArrayList 实现 RandomAccess 接口有何作用?为何 LinkedList 却没实现这个接口?
RandomAccess接口是一个标志接口
只要List集合实现这个接口,就能支持快速随机访问,主要目的是允许泛型算法在应用于随机或顺序访问列表时改变其行为以提供良好的性能。
如果一个 List
的子类实现了 RandomAccess
接口,则表示该类支持快速随机访问集合类中的元素。
LinkedList的底层是链表,查询速度慢,而且需要顺序访问。RandomAccess
接口时用来标记可以随机访问的集合,底层要由数组来实现的集合。
4. ArrayList 的扩容机制?
使用ArrayList()创建ArrayList对象时,不会定义底层数组的长度,当第一次调用add(E e) 方法时,初始化定义底层数组的长度为10,之后调用add(E e)时,如果需要扩容,则调用grow(int minCapacity) 进行扩容,长度为原来的1.5倍。
5. Array 和 ArrayList 有何区别?什么时候更适合用 Array?
Array:数组
ArrayList:动态数组,提供了动态的增加和减少元素,可以灵活的设置数组的大小
如果列表的大小已经指定,大部分情况下是存储和遍历他们;
对于遍历基本数据类型,尽管Collection使用自动装箱来减轻编码任务,在指定大小的基本类型的列表上工作也会变得很慢;
如果使用多维数组,使用 [ ] [ ] 比List<<>>更容易。
6. HashMap 的实现原理/底层数据结构?JDK1.7 和 JDK1.8
1.7:数组+链表
1.8:数组+链表/数组+红黑树
7. HashMap 的 put 方法的执行过程?、
1,判断键值对数组是否为空,是的话就执行resize()扩容
2,不为空就根据键值key计算hash值得到插入的数组索引。
3,判断table[i]==null,如果true,就建立节点添加,否则需要判断table[i]的首元素是否和key相同,相同就覆盖。
4、判断table[i]是否为treenode,即判断是否是红黑树,如果是红黑树,直接在树中插入键值对。
5、如果不是treenode,开始遍历链表,判断链表长度是否大于8,如果大于8就转成红黑树,在树中执行插入操作,如果不是大于8,就在链表中执行插入;在遍历过程中判断key是否存在,存在就直接覆盖对应的value值。
6、插入成功后,就需要判断实际存在的键值对数量size是否超过了最大容量threshold,如果超过了,执行resize方法进行扩容。
8. HashMap 的 get 方法的执行过程?
返回一个数据节点,如果不存在就返回空
先通过哈市获取key对应数据节点的hash
判断首节点是否为空,为空就直接返回
判断是否与可以相同,相同就直接返回
判断首届点的next。
9. HashMap 的 resize 方法的执行过程?
判断当前数组是初始化还是扩容,初始化就根据情况设置数组长度并创建数组;如果是扩容,需要双倍扩容并转移上面的元素。
10. HashMap 的 size 为什么必须是 2 的整数次方?
未来将hash值均匀的发布在数组的索引上。
11. HashMap 多线程死循环问题?
多线程put操作,个体操作导致的死循环。
多线程put非null元素后,get操作得到null值。
多线程put操作,导致元素丢失
hashmap时采用链表来解决哈市冲突,因为时链表的形式,所以很容易出现死循环。
12. HashMap 的 get 方法能否判断某个元素是否在 map 中?
不能,因为get返回null有可能是不包含key,也有可能该key对应的value为null,因为hashmap允许key为null,也允许value为null。
13. HashMap 与 HashTable 的区别是什么?
HashMap的key和value都允许为null,而HashTable的key和value都不允许为null。
HashTable是线程安全的,HashMap不是线程安全的
14. HashMap 与 ConcurrentHashMap 的区别是什么?
HashMap不是线程安全的,而ConcurrentHashMap是线程安全的。
15. HashTable 和 ConcurrentHashMap 的区别?
HashTable:同一把锁,效率低
ConcurrentHashMap:分段锁
16. ConcurrentHashMap 的实现原理是什么?
JDK 7 中:ConcurrentHashMap采用了数组 + Segment + 分段锁的方式实现。
JDK 8 中:ConcurrentHashMap参考了JDK 8 HashMap的实现,采用了数组+链表+红黑树的实现方式来设计,内部大量采用CAS操作。
17. HashSet 的实现原理?
HashSet的实现是依赖于HashMap的,HashSet的值都是存储在HashMap中的。在HashSet的构造法中会初始化一个HashMap对象,HashSet不允许值重复因此,HashSet的值是作为HashMap的key存储在HashMap中的,当存储的值已经存在时返回FALSE。
18. HashSet 怎么保证元素不重复的?
HashSet的值是作为HashMap的key存储在HashMap中的,而HashMap中的key是不能重复的,所以HashSet的元素固然不会重复。
19. Collection 和 Collections 有什么区别?
Collection:是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。他的直接继承接口有List,Set和Queue。
Collections:是不属于Java的集合框架的,它是集合类的一个工具类/帮助类。此类不能被实例化,服务于Java的Collection框架。它包含有关集合操作的静态多态方法,实现对各种集合的搜索、排序、线程安全等操作。