java常见的面试笔试题目(集合——1)

1.为何Map接口不继承Collection接口?
尽管Map接口和它的实现也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map继承Collection毫无意义,反之亦然。
如果Map继承Collection接口,那么元素去哪儿?Map包含key-value对,它提供抽取key或value列表集合的方法,但是它不适合“一组对象”规范。
2.什么是迭代器(Iterator)?
Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素,但是不可以直接调用集合的remove(Object Obj)删除,可以通过迭代器的remove()方法删除。
3.快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
快速失败:当你在迭代一个集合的时候,如果有另一个线程正在修改你正在访问的那个集合时,就会抛出一个ConcurrentModification异常。
在java.util包下的都是快速失败。
安全失败:你在迭代的时候会去底层集合做一个拷贝,所以你在修改上层集合的时候是不会受影响的,不会抛出ConcurrentModification异常。
在java.util.concurrent包下的全是安全失败的。
4.Enumeration和Iterator接口的差别?
Enumeration的速度是Iterator的两倍,也使用更少的内存。
Enumeration是非常基础的,也满足了基础的须要。可是,与Enumeration相比,Iterator更加安全,由于当一个集合正在被遍历的时候。它会阻止其他线程去改动集合。
迭代器代替了Java集合框架中的Enumeration。
迭代器同意调用者从集合中移除元素,而Enumeration不能做到。
为了使它的功能更加清晰,迭代器方法名已经经过改善。
5.Iterator是什么?
Iterator接口提供遍历不论什么Collection的接口。
我们能够从一个Collection中使用迭代器方法来获取迭代器实例。迭代器代替了Java集合框架中的Enumeration。迭代器同意调用者在迭代过程中移除元素。
6.Enumeration和Iterator接口的差别?
Enumeration的速度是Iterator的两倍,也使用更少的内存。
Enumeration是非常基础的,也满足了基础的须要。可是,与Enumeration相比,Iterator更加安全,由于当一个集合正在被遍历的时候。它会阻止其他线程去改动集合。
迭代器代替了Java集合框架中的Enumeration。
迭代器同意调用者从集合中移除元素,而Enumeration不能做到。
为了使它的功能更加清晰,迭代器方法名已经经过改善。
7.通过迭代器fail-fast属性,你明确了什么?
每次我们尝试获取下一个元素的时候,Iterator fail-fast属性检查当前集合结构里的不论什么改动。假设发现不论什么改动。它抛出ConcurrentModificationException。Collection中全部Iterator的实现都是按fail-fast来设计的(ConcurrentHashMap和CopyOnWriteArrayList这类并发集合类除外)。
8.UnsupportedOperationException是什么?
UnsupportedOperationException是用于表明操作不支持的异常。
在JDK类中已被大量运用,在集合框架java.util.Collections.UnmodifiableCollection将会在全部add和remove操作中抛出这个异常。
9.在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进行初始化是个不错的做法。
10.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
11.HashMap和HashTable有何不同?
(1)HashMap同意key和value为null。而HashTable不同意。
(2)HashTable是同步的,而HashMap不是。所以HashMap适合单线程环境,HashTable适合多线程环境。
(3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你非常easy从HashMap转向LinkedHashMap,可是HashTable不是这种。它的顺序是不可预知的。
(4)HashMap提供对key的Set进行遍历。因此它是fail-fast的。但HashTable提供对key的Enumeration进行遍历,它不支持fail-fast。
(5)HashTable被觉得是个遗留的类。假设你寻求在迭代的时候改动Map,你应该使用CocurrentHashMap
12.ArrayList和Vector有何异同点?
ArrayList和Vector在非常多时候都非常类似。
(1)两者都是基于索引的,内部由一个数组支持。
(2)两者维护插入的顺序,我们能够依据插入顺序来获取元素。
(3)ArrayList和Vector的迭代器实现都是fail-fast的。
(4)ArrayList和Vector两者同意null值。也能够使用索引值对元素进行随机訪问。
下面是ArrayList和Vector的不同点。
(1)Vector是同步的,而ArrayList不是。
然而。假设你寻求在迭代的时候对列表进行改变。你应该使用CopyOnWriteArrayList。
(2)ArrayList比Vector快。它由于有同步。不会过载。
(3)ArrayList更加通用,由于我们能够使用Collections工具类轻易地获取同步列表和仅仅读列表。

猜你喜欢

转载自blog.csdn.net/qq_39411208/article/details/82623280