Java集合面试题

1.ArrayList和Vector的区别

这两个类都实现了List接口(List 接口继承了Collection接口),它们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与HashSet没有任何关系,但为了说清楚ArrayListVector的功能,我们使用对比方式,更有利于说明问题。)接着才说ArrayListVector的区别,主要包括两个方面。

  • 同步性:

    Vector 是线程安全的,也就是说它的方法之间是线程同步的,而ArrayList是线程不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那么最好是使用ArrayList,因为它不考虑线程安全,效率会比较高;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再考虑和编写线程安全的代码。

  • 数据增长:

    ArrayListVector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayListVector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来的两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的时增长为原来的1.5倍)。ArrayListVector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。

    总结: 即Vector增长原来的一倍,ArrayList增加原来的0.5倍。

2.说说ArrayListVectorLinkedList 的存储性能和特性。

ArrayListVector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据通常需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

ArrayList在查找时速度快,LinkedList在插入与删除时更具优势。

3.快速失败(fail - fast) 和 安全失败(fail - safe) 的区别是什么?

Iterator 的安全失败是基于对底层集合做拷贝,因此,它不受源集合上修改的影响。java.util 包下面的所有集合都是快速失败的,而java.util.concurrent包下面的所有的类都是安全失败的。快速失败的迭代器会抛出ConcurrentModificationException异常,而安全失败的迭代器永远不会抛出这样的异常。

4.HashMap的数据结构

在Java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个数组和链表的结合体(在数据结构中,一般称之为"链表散列")

 

5.HashMap的工作原理是什么?

Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()equals()方法来向集合/从集合添加和检索元素。当调用put()方法的时候,HashMap会计算key 的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor) 和扩容极限(threshold resizing)。

6.HashMap什么时候进行扩容呢?

HashMap中的元素个数超过数组大小 loadFactor 时,就会进行数组扩容,loadFactor 的默认值为0.75,也就是说,默认情况下,数组大小为16.那么当HashMap 中元素个数超过16 * 0.75 = 12 的时候,就把数组的大小扩展为2 * 16 = 32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。

比如说,我们有 1000 个元素 new HashMap(1000),但是理论上来讲 new HashMap(1024) 更合适,不过上面已经说过,即使是 1000,HashMap (容量:2的n次方)也自动会将其设置为 1024。 但是 new HashMap(1024) 还不是更合适的,因为 0.75*1024 < 1000, 也就是说为了让 0.75 * size > 1000, 我们必须这样 new HashMap(2048) 才最合适,既考虑了loadFactor的问题,也避免了resize 的问题.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Illus1ion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值