java面试自答(2)

二. Java 容器模块
18.Java 容器都有哪些?

答:常见的容器:
普通容器:ArrayList,LinkedList,HashMap,HashSet
同步容器:Stack,Vector,Hashtable,Collections.sychroniedxxx
并发容器:ConcurrentHashMap,CopyOnWriteArrayList,CopyOnWriteArraySet,ArrayBlockingQueue,LinkedBlockingQueue

19.Collection 和 Collections 有什么区别?

答:Collection是一个接口,是所有集合容器的父接口,提供了集合对象的基本操作;
Collections是一个包装类,它包含了各种有关集合操作的静态方法,如排序,线程安全化,该类不能被实例化,所有更像一个
工具类,服务于Collection框架。

  1. HashMap 和 Hashtable 有什么区别?

答:1、继承的父类不同,HashMap继承自bstractMap类,Hashtable继承自Dictionary类,但是两个父类都实现了Map接口
2、线程的安全性不同,HashMap是非线程安全的,而Hashtable的对数据操作的方法都进行了线程同步,他是线程安全的

22.如何决定使用 HashMap 还是 TreeMap?

答:TreeMap是基于红黑数实现的,使用时要求key实现了Comparable接口,在迭代时TreeMap默认是按升序按照key值进行排序的,
所以TreeMap适用于需要按自然顺序或自定义顺序遍历键的场景;
HashMap是基于散列实现的,底层使用桶(数组),链表和红黑树,使用时要求key明确定义了equals和hashcode方法,可以通
过调整参数提高空间利用率,但是遍历结果是无序的,所以HashMap适用于不要求排序,插入、删除和定位性能要求高的场景。

但是他们都是线程不安全的,都不适用于对线程安全有要求的场景。

23.说一下 HashMap 的实现原理?

答:HashMap内部使用数组(桶)+ 链表/红黑树对数据进行存储,在使用put方法添加数据时,会先根据key的hashcode计算出对应的数组
下标,如果相应的桶中没有数据,则通过内部类Entry根据key和value创建存储实体直接填入对应的桶,如果有数据则先会遍历链表或树,
查看有无相同的key,如果有则更新对应的value,没有则插入键值对;在使用get方法获取数据时,也会先根据key的hashcaode计算出
对应的数组下标,然后遍历桶中是否存在此key,如果有则输出对应的value,否则输出null。

在里面进行key的比对尤为重要,会先对key的hashcode进行计算出数组索引,在根据key的equals方法去判断是否是相同的key,
所以为了提高性能一般要求重写key的hashcode和equals方法(因为object的equals对比的时两个对象的内存地址,这样只要是
不同的对象,HashMap就会将其进行存储,但是这两个对象保存的内容却是可以一样的,这样便可能浪费资源。

在进行添加键值对后,可能会出现扩容操作和链树转换操作,当容器存储元素的个数超过元素个数最大值*负载因子时便会出现扩
容操作,以1.5倍于原来进行扩容,扩容后会重新将元素进行散列,这个操作很消耗性能,所以可以调节负载因子进行容器的调优,
默认时0.75,是空间和性能的折衷方案。而当某个桶的元素超过7个时,会由原来的链结构变换为树结构进行存储,而当元素小于7
个时会由树结构转换为链结构进行存储。

HashMap中所有的方法都是非线程安全的。

24.说一下 HashSet 的实现原理?

答:HashSet实现了Set接口,由散列表支持,内部使用了一个HashMap实例保存元素,只是每个键值对的value都统一使用了一个
final Object进行填充,相关的操作基本上都是调用底层HashMap的相关方法完成的。

25.ArrayList 和 LinkedList 的区别是什么?

答:ArrayList实现了List接口,底层使用一个Object数组保存元素,ArrayList中的涉及操作元素的方法都是对该数组进行操作,故
其拥有数组的特点,即其查询速度快,支持随机访问,但是插入和删除元素速度较慢。
LinkedList实现了List接口和Queue接口,底层使用的是双向链表存储元素,LinkedList中涉及操作元素的方法都是对链表的操作,
故其拥有链表特点,即插入和删除元素速度快,但是查询速度慢,也不支持随机访问

26.如何实现数组和 List 之间的转换?

答:可以使用List的实现类的toArray()方法进行转换,而常用的List接口实现类ArrayList实现的toArray()方法底层使用的是java api
提供的Arrays类的copyOf()方法转换而来,而另一个常用实现类LinkedList实现的toArray()方法底层使用的是对链表遍历填入一个
数组返回完成转换。

27.ArrayList 和 Vector 的区别是什么?

答:两者继承的类和实现的接口一样,底层实现和其方法也基本一样,但他们最主要的区别是线程的安全性,ArrayList的方法都是非线程安全的,
而Vector的方法基本上全被synchronied修饰,进行了线程同步。所以在性能上ArrayList要比Vector高(多线程下)。

28.Array 和 ArrayList 有何区别?

答:Array(数组)的大小是固定的,ArrayList的大小是可以动态变化的;
Array可以存储基本数据类型和引用数据类型的数据,而ArrayList只能存储引用类型的数据
ArrayList提供了更多的特性和方法,如removeAll(),addAll()。

29.在 Queue 中 poll()和 remove()有什么区别?

答:poll()和remove()都是从队列中移除并返回队头,但是当队列为空的时候poll()会返回null,而remove()
会抛出NoSuchElementException异常。
同时的peek()和element()方法都是再不删除元素前提下返回队头,当队为空时,peek()会返回null,
element()会抛出NoSuchElementException。
还有的offer()和add()方法都是向队列添加元素,但是当队列满时,使用offer()会返回false,使用add()抛出运行时异常。

30.哪些集合类是线程安全的?

答:Vector、stack、Enumeration、HashTable、java.util.concurrent包下的所有集合类,如:ConcurrentHashMap、CopyOnWriteArrayList、
CopyOnWriteArraySet、LinkedBlockingQueue、ArrayBlockingQueue…

31.迭代器 Iterator 是什么?

答:Iterator是一种设计模式,用于遍历集合类的标准访问方法,它可以把访问逻辑从不同的集合类中抽像出来,从而避免向客户端
暴漏出集合的内部结构。

32.Iterator 怎么使用?有什么特点?

答:通常通过调用集合的iterator()得到一个Iterator对象,然后使用hasNext()和next()方法进行迭代,hasNext()方法用于是否到达
迭代的终点,next()则是取出集合中的元素,每次使用next()前都有必要先调用hasNext()来判断是否可以继续迭代,否则容易出现
越界异常,而remove()方法比较少使用,用来移除最近迭代出去的一个元素,即在使用remove()前需要先进行next()操作,否则将会
抛出异常。还有一个特点是在迭代过程中是不允许改变集合的长度,只能使用Iterator的remove()方法移除最近迭代出去的集合,
否则将会抛出异常。Iterator只能迭代集合,不能够迭代数组,想要迭代数组可以使用for循环。

33.Iterator 和 ListIterator 有什么区别?

答:Iterator服务于所有Collection对象,ListIterator是Iterator的子接口,只服务于List对象,其扩充了Iterator,如;add()方法向
集合中添加元素,set()方法修改元素,nextIndex()定位下一个索引和previousIndex()定位上一个索引,进而定位出当前索引,使用
hasPrevious()和previous()实现从后向前遍历。这些能够都是Iterator没有的。

34.怎么确保一个集合不能被修改?

答:首先自然而然的想到使用final对集合进行修饰,但是集合是引用类型,final修饰引用类型只是其引用指向的地址不可改变,但是
地址中的内容可以改变。要确保一个集合不能被修改,可以使用Collections.unmodifiablexx()方法,将原集合包装成一个不可修改
的集合对象(Unmodifiablexxx),包装后的集合对象底层是继承了UnmodifiableCollection接口,UnmodifiableCollection接口
实现了Collection接口,但是其增删改方法均是抛出异常,不对集合进行操作,但是操作原集合对象会对包装后的对象产生影响
(因为包装类持有的是一个集合类引用)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值