java容器关系图
一、基本概念
Java容器类库的主要用途是持有对象,通常两种不同的数据结构。一种是Collection(extends
Iterable),另一种是Map。
Collection:一个独立元素的序列,这些元素都服从一条或多条规则。常见的有List、SetMap:存储的是"键值对"对象,通过键来检索值。|Collection| ├List | │-├LinkedList | │-├ArrayList | │-└Vector | │ └Stack | ├Set | │├HashSet | │├TreeSet | │└LinkedSet | |Map ├Hashtable ├HashMap └WeakHashMap二、常见题集1.Java的容器有哪些?答:主要有Collection,List,Set,Map。List接口下有LinkedList,ArrayList,Vector,Stack等。Set接口下主要有HashSet和TreeSet这两个常用的类。Map接口下主要有HashMap和HashTable这两个类。
评论:这题主要考察你的代码能力,考察平常代码中有没有关注这些常用的集合类。往往最基本的,最常用的都是最容易被忽略的。
2.Collection和Collections的区别?
答:Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。
Collections则是集合类的一个工具类,它提供了一系列的静态方法,用于对集合中的元素进行操作。常用的有排序(sort),混排(Shuffling),反转(Reverse),拷贝(copy),返回Collections中最小的元素(min),返回最大的元素(max),返回指定源列表中最后一次出现指定目标列表的起始位置(lastIndexOfSubList),返回指定源列表中第一次出现指定目标列表的起始位置。
评论:这题如果毫无准备的话,肯定答不上来的
3.List,Set,Map之间的区别?
答:List和Set都是用于存储对象,不同的是List中的元素允许重复,Set中的元素不可以重复。Map用于存储键值对(key-value)这种类型的数据结构。
评论:这题深入的考察就会举一些具体的例子来考察你
4.HashMap和Hashtable的区别?
答:1.HashMap和Hashtable都实现了Map接口,HashMap可以接受null的键值对。2.HashMap是非synchronized而Hashtable是synchronized。3.HashMap的迭代器是Iterator,是fail-fast迭代器,而Hashtable是enumerator迭代器,是非fail-fast的。4.单线程下的效率Hashtable会低一些。5.HashMap不能保证随着时间的推移Map中的元素次序不变。
5.如何决定使用HashMap还是TreeMap?
答:HashMap是数组方式存储的key/value,线程非安全,允许有null作为key和value,key不可重复,value可以有重复。TreeMap是基于红黑二叉树的NavigableMap的实现,线程非安全,不允许有null,key不可以重复,TreeMap实现了Comparator接口,可以进行排序。通常需要对key-value进行排序时,会选择TreeMap.
6.HashMap的实现原理?
答:JDK1.8之前HashMap由数组+链表组成,数组是HashMap的主体,链表则是为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前 entry 的 next 指向 null ),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度依然为 O(1),因为最新的 Entry 会插入链表头部,急需要简单改变引用链即可,而对于查找操作来讲,此时就需要遍历链表,然后通过 key 对象的 equals 方法逐一比对查找。
JDK1.8之后的HashMap数据结构发生了改变,从单纯的数组加链表变成数组+链表+红黑树。当存储链表的长度大于8时转换为红黑树,当红黑树的节点小于6时就会转换成链表。具体的大家可以多读一下HashMap的源码。
7.ArrayList和LinkedList的区别?
答:主要有3点:1.ArrayList是基本动态数组,LinkedList是基于链表。2.对于随机的访问get和set,ArrayList的性能要优于LinkedList,因为LinkedList要移动指针。3.对于add和remove操作,LinkedList的性能要优化ArrayList,因为ArrayList要移动数据。
8.如何实现数组与List之间的转换?
答:List转数组的方法:1.for循环 2.list.toArray.
数组转List的方法:1.for循环 2.Arrays.asList 3.Collections.addAll
9.列举常用的线程安全集合类?
答:基本上concurrent包下的集合类都是线程安全的。常用的有ConcurrentHashMap,ArrayBlockingQueue,Hashtable等
10.Iterator是什么?怎么使用?有什么特点?
答:Iteratro是一个迭代器,主要用于遍历集合中的元素。主要有这几具特点:1.在遍历集合的过程中不允许对集合进行修改。2.在遍历的过程中不能删除元素。3.Iterator依附于Collection而存在。4.Iterator.remover删除的是上一次的Iterator.next方法返回的对象。5.Iterator.next()具有游标特性。
11.怎么确保一个集合不被修改?
答:利用final 和 private时行访问权限的控制
12.HashMap的长度为什么是2的幂次方?
答:当数组的长度为2的n次幂的时候,不同的key算得的index相同的概率小,分布更均匀。
评论:这是一个比较开发的问题,不同的人理解是不一样的,这个就要看自己的基本功和对计算机存储原理的理解了。
13.ConcurrentHashMap线程安全的具体实现方式
答:以jdk1.7为例,ConcurrentHashMap采用了数组+Segment+分段锁的方式实现。
concurrentHashMap内存结构
从上面的结构我们可以看出ConcurrentHashMap定位一个元素的过程需要进行两次hash操作。第一次hash定位到segment,第二次Hash定位到元素所在的链表的头部。