Java八股第三天

68 阅读5分钟

21.HashMap 和 Hashtable 有什么区别?

安全性不同
HashMap是线程不安全的,在多线程并发环境下,可能会产生死锁等问题,因此需要开发人员自己处理多线程的安全问题。hashTable是线程安全的,它的每一个方法上都有synchonized关键字,因此可以直接用多线程中。

两者的父类不同
HashMap是继承自AbstrctMap类,而hashtable是继承Dictionary类。不过他们都同时实现了map、Coleable、Serializable这三个接口。
对Null的支持不同
HashTable:key和value都不能为null。如果key为Null只会抛出空值的异常,value为Null则需要手动抛出异常。hashMap:key可以为Null,但是这样的key只能有一个,因为必须保证key的唯一性;可以有多的key值对应的value值为Null.

初始容量大小和每次扩张容量大小不同

计算hash值的方法不同

推荐使用
在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使 用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。

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

对于在 Map 中插入、删除、定位一个元素这类操作,HashMap 是最好的选择,因为相对而言HashMap的插入会更快,但如果你要对一个 key 集合进行有序的遍历,那 TreeMap 是更好的选择。

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

HashMap 基于 Hash 算法实现的,我们通过 put(key,value)存储,get(key)来获取。当传入 key 时, HashMap 会根据 key,用hashCode()计算出hash值,根据hash值将value保存在bucket里。当计算出的 hash 值相同时,我们称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。当 hash 冲突的个数比较少时,使用链表否则使用红黑树。

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

HashSet 是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,默认构造函数是构建一个初始容量为16,负载因子为0.75 的HashMap。封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存。

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

数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。 访问效率:ArrayList 比 LinkedList 在访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其他数据的下标。 综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。

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

数组转 List:使用 Arrays. asList(array) 进行转换。 List 转数组:使用 List 自带的 toArray() 方法。

ArrayList 和 Vector 的区别是什么?

线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全 的。 性能:ArrayList 在性能方面要优于 Vector。 扩容:ArrayList 和 Vector 都会根据实际的需要动态的调整容量,只不过在 Vector 扩容每次会增加 1 倍,而 ArrayList 只会增加 50%。

28. Array 和 ArrayList 有何区别?

Array 可以存储基本数据类型和对象,ArrayList 只能存储对象,在存储基本类型数据的时候要使用基本数据类型的包装类。 Array 是指定固定大小的,而 ArrayList 大小是自动扩展的。 Array 内置方法没有 ArrayList 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。当能确定长度并且数据类型一致的时候就可以用数组,其他时候使用ArrayList

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

相同点:都是返回第一个元素,并在队列中删除返回的对象。 不同点:如果没有元素 poll()会返回 null,而 remove()会直接抛出 NoSuchElementException 异常。

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

早在jdk的1.1版本中,所有的集合都是线程安全的。但是在1.2以及之后的版本中就出现了一些线程不安全的集合,为什么版本升级会出现一些线程不安全的集合呢?因为线程不安全的集合普遍比线程安全的集合效率高的多。随着业务的发展,特别是在web应用中,为了提高用户体验减少用户的等待时间,页面响应速度(也就是效率)是优先考虑的。而且对线程不安全的集合加锁以后也能达到安全的效果(但是效率会低,因为会有锁的获取以及等待)。其实在jdk源码中相同效果的集合线程安全的比线程不安全的就多了一个同步机制,但是效率上却低了不止一点点,因为效率低,所以已经不太建议使用了。下面举一些常用的功能相同却线程安全和不安全的集合。
Vector:就比Arraylist多了个同步化机制(线程安全)。
Hashtable:就比Hashmap多了个线程安全。
ConcurrentHashMap:是一种高效但是线程安全的集合。
Stack:栈,也是线程安全的,继承于Vector。