送给程序员的20个Java集合面试问题


Posted in 面试题 onAugust 06, 2014

1.Java集合框架是什么?说出一些集合框架的优点?
答:每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。在保证线程安全的情况下使用泛型和并发集合类,Java已经经历了很久。它还包括在Java并发包中,阻塞接口以及它们的实现。集合框架的部分优点如下:
(1)使用核心集合类降低开发成本,而非实现我们自己的集合类。
(2)随着使用经过严格测试的集合框架类,代码质量会得到提高。
(3)通过使用JDK附带的集合类,可以降低代码维护成本。
(4)复用性和可操作性。

2.集合框架中的泛型有什么优点?
答:Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。它也给运行时带来好处,因为不会产生类型检查的字节码指令。

3.Java集合框架的基础接口有哪些?
答:Collection为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。Java平台不提供这个接口任何直接的实现。Set是一个不能包含重复元素的集合。这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。List是一个有序集合,可以包含重复元素。你可以通过它的索引来访问任何元素。List更像长度动态变换的数组。Map是一个将key映射到value的对象.一个Map不能包含重复的key:每个key最多只能映射一个value。一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。

4.为何Collection不从Cloneable和Serializable接口继承?
答:Collection接口指定一组对象,对象即为它的元素。如何维护这些元素由Collection的具体实现决定。例如,一些如List的Collection实现允许重复的元素,而其它的如Set就不允许。很多Collection实现有一个公有的clone方法。然而,把它放到集合的所有实现中也是没有意义的。这是因为Collection是一个抽象表现。重要的是实现。当与具体实现打交道的时候,克隆或序列化的语义和含义才发挥作用。所以,具体实现应该决定如何对它进行克隆或序列化,或它是否可以被克隆或序列化。在所有的实现中授权克隆和序列化,最终导致更少的灵活性和更多的限制。特定的实现应该决定它是否可以被克隆和序列化。

5.为何Map接口不继承Collection接口?
答:尽管Map接口和它的实现也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map继承Collection毫无意义,反之亦然。如果Map继承Collection接口,那么元素去哪儿?Map包含key-value对,它提供抽取key或value列表集合的方法,但是它不适合“一组对象”规范。

6.Iterator是什么?
答:Iterator接口提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者在迭代过程中移除元素。

7.Enumeration和Iterator接口的区别?
答:Enumeration的速度是Iterator的两倍,也使用更少的内存。Enumeration是非常基础的,也满足了基础的需要。但是,与Enumeration相比,Iterator更加安全,因为当一个集合正在被遍历的时候,它会阻止其它线程去修改集合。迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者从集合中移除元素,而Enumeration不能做到。为了使它的功能更加清晰,迭代器方法名已经经过改善。

8.为何没有像Iterator.add()这样的方法,向集合中添加元素?
答:语义不明,已知的是,Iterator的协议不能确保迭代的次序。然而要注意,ListIterator没有提供一个add操作,它要确保迭代的顺序。

9.为何迭代器没有一个方法可以直接获取下一个元素,而不需要移动游标?
答:它可以在当前Iterator的顶层实现,但是它用得很少,如果将它加到接口中,每个继承都要去实现它,这没有意义。

10.Iterater和ListIterator之间有什么区别?
答:(1)我们可以使用Iterator来遍历Set和List集合,而ListIterator只能遍历List。
(2)Iterator只可以向前遍历,而LIstIterator可以双向遍历。
(3)ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。


11.通过迭代器fail-fast属性,你明白了什么?
答:每次我们尝试获取下一个元素的时候,Iterator fail-fast属性检查当前集合结构里的任何改动。如果发现任何改动,它抛出ConcurrentModificationException。Collection中所有Iterator的实现都是按fail-fast来设计的(ConcurrentHashMap和CopyOnWriteArrayList这类并发集合类除外)。

12.fail-fast与fail-safe有什么区别?
答:Iterator的fail-fast属性与当前的集合共同起作用,因此它不会受到集合中任何改动的影响。Java.util包中的所有集合类都被设计为fail-fast的,而java.util.concurrent中的集合类都为fail-safe的。Fail-fast迭代器抛出ConcurrentModificationException,而fail-safe迭代器从不抛出ConcurrentModificationException。

13.在迭代一个集合的时候,如何避免ConcurrentModificationException?
答:在遍历一个集合的时候,我们可以使用并发集合类来避免ConcurrentModificationException,比如使用CopyOnWriteArrayList,而不是ArrayList。

14.为何Iterator接口没有具体的实现?
答:Iterator接口定义了遍历集合的方法,但它的实现则是集合实现类的责任。每个能够返回用于遍历的Iterator的集合类都有它自己的Iterator实现内部类。这就允许集合类去选择迭代器是fail-fast还是fail-safe的。比如,ArrayList迭代器是fail-fast的,而CopyOnWriteArrayList迭代器是fail-safe的。

15.UnsupportedOperationException是什么?
答:UnsupportedOperationException是用于表明操作不支持的异常。在JDK类中已被大量运用,在集合框架java.util.Collections.UnmodifiableCollection将会在所有add和remove操作中抛出这个异常。

16.在Java中,HashMap是如何工作的?
答:HashMap在Map.Entry静态内部类实现中存储key-value对。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。当我们通过传递key-value对调用put方法的时候,HashMap使用Key hashCode()和哈希算法来找出存储key-value对的索引。Entry存储在LinkedList中,所以如果存在entry,它使用equals()方法来检查传递的key是否已经存在,如果存在,它会覆盖value,如果不存在,它会创建一个新的entry然后保存。当我们通过传递key调用get方法时,它再次使用hashCode()来找到数组中的索引,然后使用equals()方法找出正确的Entry,然后返回它的值。下面的图片解释了详细内容。其它关于HashMap比较重要的问题是容量、负荷系数和阀值调整。HashMap默认的初始容量是32,负荷系数是0.75。阀值是为负荷系数乘以容量,无论何时我们尝试添加一个entry,如果map的大小比阀值大的时候,HashMap会对map的内容进行重新哈希,且使用更大的容量。容量总是2的幂,所以如果你知道你需要存储大量的key-value对,比如缓存从数据库里面拉取的数据,使用正确的容量和负荷系数对HashMap进行初始化是个不错的做法。

17.hashCode()和equals()方法有何重要性?
答:HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引。当我们试着从HashMap中获取值的时候,这些方法也会被用到。如果这些方法没有被正确地实现,在这种情况下,两个不同Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,然后覆盖它们,而非把它们存储到不同的地方。同样的,所有不允许存储重复数据的集合类都使用hashCode()和equals()去查找重复,所以正确实现它们非常重要。equals()和hashCode()的实现应该遵循以下规则:
(1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的。
(2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。

18.我们能否使用任何类作为Map的key?
答:我们可以使用任何类作为Map的key,然而在使用它们之前,需要考虑以下几点:
(1)如果类重写了equals()方法,它也应该重写hashCode()方法。
(2)类的所有实例需要遵循与equals()和hashCode()相关的规则。请参考之前提到的这些规则。
(3)如果一个类没有使用equals(),你不应该在hashCode()中使用它。
(4)用户自定义key类的最佳实践是使之为不可变的,这样,hashCode()值可以被缓存起来,拥有更好的性能。不可变的类也可以确保hashCode()和equals()在未来不会改变,这样就会解决与可变相关的问题了。比如,我有一个类MyKey,在HashMap中使用它。

19.队列和栈是什么,列出它们的区别?
答:栈和队列两者都被用来预存储数据。java.util.Queue是一个接口,它的实现类在Java并发包中。队列允许先进先出(FIFO)检索元素,但并非总是这样。Deque接口允许从两端检索元素。栈与队列很相似,但它允许对元素进行后进先出(LIFO)进行检索。Stack是一个扩展自Vector的类,而Queue是一个接口。

20.Comparable和Comparator接口有何区别?
答:Comparable和Comparator接口被用来对对象集合或者数组进行排序。Comparable接口被用来提供对象的自然排序,我们可以使用它来提供基于单个逻辑的排序。
Comparator接口被用来提供不同的排序算法,我们可以选择需要使用的Comparator来对给定的对象集合进行排序。
 



Tags in this post...

面试题 相关文章推荐
如何设定的weblogic的热启动模式(开发模式)与产品发布模式
Sep 08 面试题
如何将字串String转换成整数int
Feb 21 面试题
金智子午JAVA面试题
Sep 04 面试题
将"引用"作为函数返回值类型的格式、好处和需要遵守的规则
Feb 09 面试题
What is view? why do we have view?
Jun 22 面试题
STP的判定过程
Oct 01 面试题
一些Solaris面试题
Dec 22 面试题
介绍一下Prototype的$()函数,$F()函数,$A()函数都是什么作用?
Mar 05 面试题
在Ajax应用中信息是如何在浏览器和服务器之间传递的
May 31 面试题
用JAVA实现一种排序,JAVA类实现序列化的方法(二种)
Apr 23 面试题
short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
Sep 26 面试题
J2EE模式面试题
Oct 11 面试题
IBatis持久层技术
Jul 18 #面试题
Hibernate持久层技术
Dec 16 #面试题
Jdbc数据访问技术面试题
Mar 30 #面试题
Java基础类库面试题
Sep 04 #面试题
25道Java面试题集合
May 21 #面试题
Java面试题汇总
Dec 06 #面试题
Java面向对象面试题
Dec 26 #面试题
You might like
深入解析Session是否必须依赖Cookie
2013/08/02 PHP
PHP合并数组的2种方法小结
2016/11/24 PHP
SCP远程VPS快速搬家和WDCP升级php5.3安装memcached和eaccelerator教程
2017/07/27 PHP
不常用但很实用的PHP预定义变量分析
2019/06/25 PHP
JavaScript 入门·JavaScript 具有全范围的运算符
2007/10/01 Javascript
jquery 选择器部分整理
2009/10/28 Javascript
JavaScript的单例模式 (singleton in Javascript)
2010/06/11 Javascript
jQuery 操作option的实现代码
2011/03/03 Javascript
js控制容器隐藏出现防止样式变化的两种方法
2014/04/25 Javascript
JS实现鼠标点击展开或隐藏表格行的方法
2015/03/03 Javascript
全面理解闭包机制
2016/07/11 Javascript
js添加千分位的实现代码(超简单)
2016/08/01 Javascript
AngularJS动态绑定HTML的方法分析
2016/11/07 Javascript
微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义实例
2016/12/08 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
JS设置时间无效问题的解决办法
2017/02/18 Javascript
jQuery Ajax自定义分页组件(jquery.loehpagerv1.0)实例详解
2017/05/01 jQuery
JS中使用media实现响应式布局
2017/08/04 Javascript
JS实现的base64加密解密操作示例
2018/04/18 Javascript
jQuery插件jsonview展示json数据
2018/05/26 jQuery
用webpack4开发小程序的实现方法
2019/06/04 Javascript
vue根据条件不同显示不同按钮的操作
2020/08/04 Javascript
keras 指定程序在某块卡上训练实例
2020/06/22 Python
python文件编写好后如何实践
2020/07/07 Python
css3给背景图片加颜色遮罩的方法
2019/11/05 HTML / CSS
SmartBuyGlasses德国:购买太阳镜和眼镜
2019/08/20 全球购物
大学生毕业自我鉴定范文
2013/09/19 职场文书
财务会计应届生求职信
2013/11/24 职场文书
六年级学生评语
2014/04/22 职场文书
企业消防安全责任书
2014/07/23 职场文书
大学教师师德师风演讲稿
2014/08/22 职场文书
学前教育专业求职信
2014/09/02 职场文书
正风肃纪剖析材料
2014/09/30 职场文书
安全第一课观后感
2015/06/18 职场文书
Java Socket实现Redis客户端的详细说明
2021/05/26 Redis
Python极值整数的边界探讨分析
2021/09/15 Python