基础面试题
1、常用的集合类有哪?
- Map接口和Collection接口是所有集合框架的父接口:
1、Collection接口的子接口包括:Set接口和List接口
2、Map接口的实现类主要有:HashMap,TreeMap,Hashtable,ConcurrentHashMap以及Properties等
3、Set接口的实现主要有:HashSet、TreeSet、LinkedHashSet等
4、List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
2、List,Set,Map三者的区别?
-
Java 容器分为 Collection 和 Map 两大类,Collection集合的子接口有Set、List、Queue三种子接口。我们比较常用的是Set、List,Map接口不是collection的子接口。
-
Collection集合主要有List和Set两大接口
- List:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。
- Set:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及TreeSet。
-
Map是一个键值对集合,存储键、值和之间的映射。 Key无序,唯一;value 不要求有序,允许重复。Map没有继承于Collection接口,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。
- Map 的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap
3、集合框架底层数据结构
- Collection
- List
- ArrayList:Object数组
- Vector:Object数组
- LinkedList:双向循环链表
============================= - Set
- HashSet(无序,唯一):基于 HashMap 实现的,底层采用 HashMap 来保存元素
- LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。
- TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)
- List
- Map
-
HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间.
-
LinkedHashMap:LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
-
HashTable:数组+链表组成的,数组是HashMap的主体,链表则主要为了解决哈希冲突而存在。
-
TreeMap: 红黑树(自平衡的排序二叉树)
-
4、哪些集合类是线程安全
- Vector:就比ArrayList多了个synchronized (线程安全),因为效率较低,现在已经不太建议使用。
- hashTable:就比hashMap多了个synchronized (线程安全),不建议使用。
- ConcurrentHashMap:是Java5中支持高并发、高吞吐量的线程安全HashMap实现。它由Segment数组结构和HashEntry数组结构组成。
5、Java集合的快速失败机制 “fail-fast?
是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast 机制。
6、怎么确保一个集合不能被修改?
- 可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。
- 示例代码如:
List<String> list = new ArrayList<>();
list.add("x");
Collection<String> clist = Collections.unmodifiableCollection(list);
clist.add("y");
// 运行时此行报错
System.out.println(list.size());
7、Iterator 和 ListIterator 有什么区别?
- Iterator可以遍历Set和List集合,而ListIterator只能遍历List。
- Iterator 只能单向遍历,而 ListIterator 可以双向遍历(向前/后遍历)。
- ListIterator实现Iterator接口,然后添加了一些额外的功能,比如添加一个元素,替换一个元素、获取前面或者元素的索引位置。
8、说一下 ArrayList 的优缺点?
- ArrayList的优点如下:
- ArrayList 底层以数组实现,是一种随机访问模式。ArrayList 实现了 RandomAccess 接口,因此查找的时候非常快。
- ArrayList 在顺序添加一个元素的时候非常方便。
- ArrayList 的缺点如下:
- 删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。
- 插入元素的时候,也需要做一次元素复制操作,缺点同上。
- ArrayList 比较适合顺序添加、随机访问的场景。
9、如何实现数组和 List 之间的转换
- 数组转 List:使用 Arrays. asList(array) 进行转换。
- List 转数组:使用 List 自带的 toArray() 方法。
10、ArrayList 和 LinkedList 的区别是什么?
- 数据结构实现:ArrayList是动态数组实现的,而LinkedList是通过双向链表来实现的。
- 随机访问效率:ArrayList在随机访问效率高,LinkedList是线性数据结构,所以移动指针从前到后一次查找,效率低
- 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为ArrayList 增删操作要影响数组内的其他数据的下标。
- 内存空间占用:LinkedList 比 ArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
- 线程安全:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;