18.java 容器都有哪些?
有List,Set和Map
List中有ArrayList、LinkedList、Vector
Set中有HashSet、TreeSet
Map中有HashMap、TreeMap、HashTable
List和Set的父类接口为Collection
19.Collection 和 Collections 有什么区别?
Collection是一个接口,它提供了对集合对象的进行基本操作的接口,子类有List和Set等
Collections是一个包装类,包含很多静态方法,不能被实例化
20.List、Set、Map 之间的区别是什么?
List:有序可重复
Set:无序不可重复
Map:无序,Key唯一,Value可重复
21.HashMap 和 HashTable 有什么区别?
HashMap的key和value可以为null,而HashTable的key和value不可为null。
HashMap为非线程安全的Map,HashTable为线程安全的Map
HashTable是直接再操作方法上添加synchronized关键字,锁住table数组,粒度大,效率低,不建议使用。单线程环境下使用HashMap,多线程环境下建议使用ConcurrentHashMap。
22.如何决定使用 HashMap 还是 TreeMap?
HashMap的增删查操作效率高
TreeMap对key进行遍历效率高
23.说一下 HashMap 的实现原理?
HashMap底层在JDK1.7及之前是数组+链表实现的,在JDK1.8后为数组+链表+红黑树实现,有桶数组和哈希函数,哈希函数负责调用hashCode()方法得到32位的hash散列码,然后将这32位散列码的高16位和低16位进行异或得到一个新的哈希码,然后将新的哈希码和数组长度-1进行或操作,得到数组的下标,进行put会先看该下标是否有值,如果没有直接存入,如果该下标有值且为链表结构则加在链表的后面,如果链表长度大于8则会将链表改为红黑树进行数据存储,当所有的元素处理完成后,判断是否超过阈值,超过则扩容。
上面提到的高16位和低16位异或操作是为了减少hash碰撞。
在之前Map的链表结构是头插法,但是在并发的情况下,链表的头插法可能会发生反转,从而产生环,所有JDK1.8后改为尾插法解决这个问题。
当链表长度大于8改为红黑树可以大大提高检索效率,当红黑树节点小于6的时候会改回链表。
24.说一下 HashSet 的实现原理?
HashSet底层是基于HashMap实现的,HashSet的源码非常少,除了实现了一些方法之外,其他方法都是直接调用HashMap中的方法。
25.ArrayList 和 LinkedList 的区别是什么?
ArrayList和LinkedList都实现了接口List
ArrayList底层是基于数组,ArrayList数组有下标,在插入删除的时候会使数组下标前移或者后移,所以适合从尾部插入和检索
LinkedList底层基于双向链表,LinkedList在进行增删操作的时候,只需要更改前驱节点和后继节点,因此比较适合增删操作。
但是ArrayList的效率比LinkedList高,有一位博士说:如果不知道用什么的时候,就用ArrayList,在实际的开发中ArrayList的使用度远远高于LinkedList。
26.如何实现数组和 List 之间的转换?
数组->List:使用Arrays的asList()方法进行转换。
List->数组:使用List的toArray()方法进行转换。