1. 集合概览
1.1 Java集合概览
Java集合主要包括两部分:Collection接口,用于存放单一元素;Map接口,用于存放键值对。
Java 集合框架如下图所示:
1.2 说说 List, Set, Queue, Map 四者的区别?
- List: 存储的元素是有序的、可重复的。
- Set:存储的元素是无序的、不可重复的。
- Queue: 按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。
- Map(用 key 来搜索的专家): 使用键值对(key-value)存储,类似于数学上的函数 y=f(x),”x” 代表 key,”y” 代表 value,key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。
1.3 为什么要使用集合?
我们常使用数组来存储一组同类型的数据,但是在实际开发中,存储的数据类型多种多样且数量不确定。与数组相比,Java 集合提供了更灵活、更有效的方法来存储多个数据对象。Java 集合框架中的各种集合类和接口可以存储不同类型和数量的对象,同时还具有多样化的操作方式。相较于数组,Java 集合的优势在于它们的大小可变、支持泛型、具有内建算法等。总的来说,Java 集合提高了数据的存储和处理灵活性,可以更好地适应现代软件开发中多样化的数据需求,并支持高质量的代码编写。
1.4 如何选用集合?
需要根据键值获取元素值就选用Map接口下的集合
- 需要排序TreeMap
- 无需排序HashMap
- 需要保证线程安全ConcurrentHashMap
只存放元素选择Collection接口的集合
- 需要保证元素唯一Set
- 无需保证元素唯一List
2. List
2.1 ArrayList 和 Array(数组)的区别?
ArrayList内部基于动态数组实现,比Array更加灵活方便:
- ArrayList可以动态扩缩容,Array一旦创建就无法改变长度
- ArrayList可以使用泛型来确保类型安全,Array不可以
- ArrayList能存储任何类型的对象,对于基本数据类型,需要使用其包装类。Array对象和基本数据类型都可以存储
- ArrayList提供了丰富的API,Array只能根据下标访问元素,修改麻烦
- ArrayList创建时无需定义大小,Array需要定义大小
2.2 ArrayList 插入和删除元素的时间复杂度?
插入:
- 头部插入:将所有元素依次后移一位,时间复杂度是 O(n)
- 尾部插入:当ArrayList的容量还没满时,直接插在尾部时间复杂度是 O(1);当容量已满需要扩容时,先扩容时间复杂度是O(n),再插入时间复杂度是 O(1),因此时间复杂度是 O(n)
- 指定位置插入:需要将目标位置之后的所有元素都向后移动一个位置,然后再把新元素放入指定位置。这个过程需要移动平均 n/2 个元素,因此时间复杂度为 O(n)
删除:
- 头部删除:将所有元素依次前移一位,时间复杂度是 O(n)
- 尾部删除:直接删除,时间复杂度是 O(1)
- 指定位置删除:需要将目标位置之后的所有元素都向前移动一个位置,然后再把新元素放入指定位置。这个过程需要移动平均 n/2 个元素,因此时间复杂度为 O(n)
2.3 LinkedList 插入和删除元素的时间复杂度?
- 头尾插入/删除:修改头/尾节点指针修改,时间复杂度是 O(1)
- 指定位置插入/删除:需要先移动到指定位置,再修改指定节点的指针完成插入/删除,因此需要移动平均 n/2 个元素,时间复杂度为 O(n)
2.4 ArrayList 与 LinkedList 区别?
- 是否保证线程安全:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全 Java线程安全详解
- 底层数据结构: ArrayList 为数组, LinkedList为链表
- 插入和删除是否受元素位置影响:区别与数组和链表同理
- 是否支持快速访问:区别与数组和链表同理
- 内存空间占用:ArrayList在list末尾会预留一定空间;LinkedList一个结点包括前驱、后继结点和数据三个部分
在项目中一般是不会使用到 LinkedList 的,需要用到 LinkedList 的场景几乎都可以使用 ArrayList 来代替,并且,性能通常会更好!
3. Map
3.1 HashMap 和 Hashtable 的区别
- 线程是否安全:HashMap是非线程安全的,Hashtable是线程安全的(被synchronized修饰)
- 效率:HashMap效率较高
- Null key和Null value的支持:HashMap可以存储空的键值而Hashtable不允许
- 。。。