java集合面试题
java集合面试题
上图为整体的集合框架图,在理解下面的面试题的时候,这个图可以更好的帮助你理顺思路
java集合框架的基础接口有哪些?
集合分为单列集合和双列集合
单列集合的基础接口
Iterator、Collection、List、Set、Queue
List, Set, Map 是否继承自 Collection 接口
List,Set 是,Map 不是
List、Map、Set 三个接口,存取元素时,各有什么特点?
List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map 保
存 key-value 值,value 可多值。
你所知道的集合类都有哪些?主要方法?
最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,
它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。
单列集合Collection
作为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。Java平台不提供这个接口任何直接的实现。
Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素(Elements)
Collection为什么不继承Cloneable和Serializable?
collection接口是一个抽象表现,更重要的是让他的实现类来继承Cloneable和Serializable,这样才有意义。
反过来说,只有与具体实现打交道,克隆和序列化的含义与语义才能发挥出来作用。
Collection 和 Collections 的区别
Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List.
Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作
数组和链表分别适用于什么场景,为什么?
数组:查询多,增删少; 因为底层是动态数组,可以根据指针查询效率高
链表:查询少,增删多; 因为底层是链表结构增删方便.
List
特点:
- 有序集合
- 可以包含重复元素,可为空
- 可以通过它的索引来访问集合中的任一元素。
List更类似于一个长度可以动态变化的数组。
你知道的 List 都有哪些?
ArrayList、LinkedList、Vector 等。
List 和 Vector 有什么区别?
Vector 是 List 接口下线程安全的集合。
List 是有序的吗?
List 是有序的。
List 是线程安全的吗?如果要线程安全要怎么做?
List 中 的 Vector 才 是 线 程 安 全 的 , 其 他 要 实 现 线 程 安 全 使 用 工 具 类
Collections.synchronizedList(new ArrayList())方法。
怎么给 List 排序?
使用 List 自身的 sort 方法,或者使用 Collections.sort(list)方法;
如何对list集合中的数据进行去重
1.借助set集合
2.利用List的contains方法循环遍历
Arrays.asList 方法后的 List 可以扩容吗?
Arrays.asList 使用的是 final 数组,并且不支持 add 方法,不支持扩容。
List 和 Array 之间如何互相转换?
List>Array 使用 toArray 方法,Array>List 使用 Arrays.asList(array)方法,由于它是固定的,不固定的可以使用 new ArrayList(Arrays.asList(array))。
ArrayList
底层结构:数组
ArrayList 默认大小是多少,是如何扩容的?
Jdk1.7 之前 ArrayList 默认大小是 10,JDK1.7 之后是 0,JDK 差异,每次约按 1.5 倍扩容。
LinkedList
底层结构:双向链表
ArrayList 和 LinkedList 的区别?分别用在什么场景?
ArrayList 和 LinkedList 数据结构不一样,前者用在查询较多的场合,后者适用于插入较多的场合。
ArrayList 和 LinkedList 的底层数据结构是什么?
ArrayList 使用的是数组结构,LinkedList 使用的是链表结构。
说出 ArrayList,Vector, LinkedList 的存储性能和特性
1.ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,
2.Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差
3. LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
ArrayList和LinkedList有什么区别?
1.底层实现:
ArrayList的底层是动态数组;LinkedList的底层是双向链表
2.增加元素:
ArrayList将元素追加至最后,ArrayList数组的默认初始大小为10,如果新增元素后大小超过数组的容量,则会对数组进行扩容,默认扩容大小为1.5倍;同时需要讲旧数组中的元素copy到新数组中
LinkedList将元素添加到链表的末尾,新增的元素作为最后一个节点
3.删除元素
ArrayList根据index删除元素,index索引上的元素被删除,index索引后的元素向前平移一个单位,因此效率不高
LinkedList根据index删除元素,改变index前后元素的指向,效率高;
4.插入元素
ArrayList在index位置上插入元素,需将原先index及往后的元素向后平移一个单位,效率不高
LinkedList在index位置插入元素,只需改变前后元素指向,效率高
5.查询
ArrayList根据index能够直接定位到元素所在位置,效率高
LinkedList查询时,需要从首个元素沿着链表进行查找,直到找到index索引处的元素,然后返回,效率不高
Set
特点:
- 无序
- 不包含重复元素
- 只有一个空元素
Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是 equals()? 它们有何区别
Set 里的元素是不能重复的,那么用 iterator()方法来区分重复与否。equals()是判读两个
Set 是否相等
equals()和==方法决定引用值是否指向同一对象 equals()在类中被覆盖,为的是当两
个分离的对象的内容和类型相配的话,返回真值
双列集合的基础接口Map
Map是一个将key映射到value的对象(也就是key=value的键值对),一个Map不能包含重复的key,每个key最多只能映射一个value。
Map 提供 key 到 value 的映射
Map
- 无序
- 键不重,值可重
- 可一个空键、多个空值
为什么Map不继承Collection接口
尽管Map接口和它的实现也是集合框架的一部分,但是Map不是集合,集合也不是Map。
再说,Map包含key-value对,他提供抽取key或者value列表集合的方法,但是它不适合“”一组对象“”规范。
HashMap的底层结构
HashMap底层数据结构为数组+链表;在JDK1.8中当链表的长度超过8时,链表会转换为红黑树;
数组的默认数组长度为16,数组的长度总是为2的幂;当数组的某一个链表的长度超出扩容条件:数组长度负载因子(默认0.75),如:数组长度160.75=12,那么当链表(JDK1.7)或红黑树(JDK1.8)大小超过12,就会进行自动扩容;
HashMap怎么将数据存在有限的数组中(HashMap如何存储数据?)
1、如果数组还没有初始化(数组长度是0),则先初始化,默认16
2、通过hash方法计算key的hash值,hash值对数组长度进行取余操作,进而计算得到应该放置到数组的位置
3、如果该位置为空,则直接放置此处
4、如果该位置不为空,而且元素是红黑树,则插入到其中
5、如果是链表,则遍历链表,如果找到相等的元素则替换,否则插入到链表尾部
6、如果链表的长度大于或等于8,则将链表转成红黑树
HashMap 和 Hashtable 的区别
HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,主要区别在于 HashMap 允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和 containsKey。因为 contains 方法容易让人引起误解。
Hashtable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现。
最大的不同是,Hashtable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。
Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。
ArrayList 和 Vector 的区别,HashMap 和 Hashtable 的区别
就 ArrayList 与 Vector 主要从二方面来说.
一.同步性:Vector 是线程安全的,也就是说是同步的,而 ArrayList 是线程序不安全的,不是同步的
二.数据增长:当需要增长时,Vector 默认增长为原来一培,而 ArrayList 却是原来的一半
就 HashMap 与 HashTable 主要从三方面来说。
一.历史原因:Hashtable 是基于陈旧的 Dictionary 类的,HashMap 是 Java 1.2 引进的 Map
接口的一个实现
二.同步性:Hashtable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的,不是同步的
三.值:只有 HashMap 可以让你将空值作为一个表的条目的 key 或 value
HashMap在JDK1.8与JDK1.7中有什么不同
1、1.8中引入了红黑树,而1.7中没有
2、1.8中元素是插在链表的尾部,而1.7中新元素是插在链表的头部
3、扩容的时候,1.8中不会出现死循环,而1.7中容易出现死循环
HashMap和HashTable的区别
(1)HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都经过synchronized修饰。
(2)因为同步、哈希性能等原因,性能肯定是HashMap更佳,因此HashTable已被淘汰。
(3) HashMap允许有null值的存在,而在HashTable中put进的键值只要有一个null,直接抛出NullPointerException。
(4)HashMap默认初始化数组的大小为16,HashTable为11。前者扩容时乘2,使用位运算取得哈希,效率高于取模。而后者为乘2加1,都是素数和奇数,这样取模哈希结果更均匀。