java基础面试题六集合框架
目录
1. List,Set,Map是否继承自collection接口?
2. 说说List,Set,Map三者的区别
3. 写出list、map、set接口的实现类,并说出其特点
4. 常见集合类的区别和适用场景
5. 集合的父类是谁?哪些安全的?
6. 遍历集合的方式有哪些?
7. List下面有哪些实现
8. ArrayList与LinkedList区别?
9. ArrayList与Vector区别呢?为什么要用ArrayList取代Vector呢?
10. Java.util.ArrayList常用的方法有哪些?
11. Arraylist 是有序还是无序?为什么?
12. Set集合有哪些实现类,分别有什么特点?
13. List集合和Set集合的区别?
14. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
15. TreeSet两种排序方式在使用的时候怎么起作用?
16. TreeSet的数据结构
17. 说一下Java的集合Map有哪些Map?
18. final怎么用,修饰Map可以继续添加数据吗?
19. Set和Map的比较
20. HashMap说一下,线程安全吗?
21. HashMap和Hashbable的区别?
22. Hashtable是怎么实现的,为什么线程安全?
23. HashMap和LinkedHashMap的区别
24. HashMap 和 TreeMap 的区别
25. HashMap里面实际装的是什么?
26. HashMap的key存储在哪里?和value存储在一起吗?那么value存储在哪里?说具体点?
27. 自定义类型可以作为Key么?
28. 集合类的工具类是谁?用过工具类哪些方法?
29. Collection 和 Collections的区别?
30. ArrayList 如何实现排序
31. HashMap是否线程安全,怎样解决HashMap的线程不安全
1. List,Set,Map是否继承自collection接口?
Map不是。
2. 说说List,Set,Map三者的区别
1. List
- 特性:
List
是一个有序集合,允许元素重复。 - 实现类:常见的实现类有
ArrayList
、LinkedList
和Vector
。 - 索引:
List
支持通过索引来访问元素,索引从 0 开始。 - 适用场景:适用于需要维护元素顺序和允许重复元素的场景,比如存储学生成绩列表、任务列表等。
2. Set
- 特性:
Set
是一个无序集合,不允许元素重复。 - 实现类:常见的实现类有
HashSet
、LinkedHashSet
(保持插入顺序)和TreeSet
(按自然排序或自定义排序)。 - 适用场景:适用于需要确保元素唯一性、不允许重复元素的场景,比如存储用户ID、电话号码等。
3. Map
- 特性:
Map
是一个键值对(key-value)集合,每个键唯一,值可以重复。 - 实现类:常见的实现类有
HashMap
、LinkedHashMap
(按插入顺序)和TreeMap
(按键排序)。 - 适用场景:适用于根据键快速查找值的场景,比如存储用户ID和对应的用户信息、单词和解释等。
3. 写出list、map、set接口的实现类,并说出其特点
1. List 接口的实现类
ArrayList
:查询快,增删慢,不线程安全。LinkedList
:增删快,查询慢,不线程安全。Vector
:查询快,增删慢,线程安全。Stack
:后进先出结构,线程安全。
2. Set 接口的实现类
HashSet
:无序,允许快速操作,不允许重复元素。LinkedHashSet
:有序(按插入顺序),不允许重复元素。TreeSet
:按顺序存储,支持排序,不允许重复元素。EnumSet
:专用于枚举类型的集合,高效。
3. Map 接口的实现类
HashMap
:无序,允许null
键和值,线程不安全。LinkedHashMap
:按插入顺序存储,允许null
键和值。TreeMap
:按键排序存储,不允许null
键。Hashtable
:无序,线程安全,不允许null
键和值。EnumMap
:适合枚举类型键的高效存储。ConcurrentHashMap
:线程安全,高效并发访问。
4. 常见集合类的区别和适用场景
1. List 集合类
ArrayList | 基于数组实现,有序、随机访问效率高,增删元素性能一般,线程不安全。 | 适用于频繁读取数据、元素增删较少的场景,比如商品列表、学生名单等。 |
LinkedList | 基于双向链表实现,有序,增删效率高,但随机访问性能差,线程不安全。 | 适用于频繁增删元素的场景,如队列、栈、任务调度等。 |
Vector | 类似 ArrayList ,但线程安全,方法加锁,性能稍差。 | 适用于多线程环境下的顺序列表存储,线程安全要求不高时推荐使用 ArrayList 。 |
Stack | 继承自 Vector ,实现了后进先出(LIFO)结构。 | 适用于后进先出(LIFO)需求的场景,如撤销操作、浏览历史记录等。 |
2. Set 集合类
HashSet | 基于哈希表实现,无序,不允许重复元素,查询和插入效率高,线程不安全。 | 适用于需要快速查找和去重的场景,如用户名、ID、电话簿等。 |
LinkedHashSet | 继承自 HashSet ,按插入顺序存储,不允许重复元素。 | 适用于需要顺序且无重复的集合场景,比如历史记录、用户输入记录等。 |
TreeSet | 基于红黑树实现,按元素自然顺序或自定义顺序存储,不允许重复元素,查询效率高。 | 适用于需要排序和去重的场景,比如学生成绩排名、字母顺序列表等。 |
EnumSet | 专门用于存储枚举类型,效率高。 | 适用于枚举类型的集合,且枚举类型固定的场景,如表示状态、方向等固定集合。 |
3. Map 集合类
HashMap | 基于哈希表实现,无序存储,允许 null 键和 null 值,线程不安全,查询和插入效率高。 | 适用于快速查找键值对的场景,如缓存、配置参数、数据映射等。 |
LinkedHashMap | 继承自 HashMap ,按插入顺序存储,允许 null 键和 null 值。 | 适用于既要保持插入顺序又需要键值对映射的场景,如按访问顺序排序的数据缓存。 |
TreeMap | 基于红黑树实现,按键排序,不允许 null 键,查询效率高。 | 适用于需要按键排序的场景,比如字典、电话号码簿等。 |
Hashtable | 类似 HashMap ,线程安全,不允许 null 键和 null 值,效率较低。 | 适用于多线程环境下的键值对存储,要求严格的线程安全,如早期的 Java 应用。 |
EnumMap | 专门用于枚举类型的键,效率高,顺序为枚举常量的自然顺序。 | 适用于键为枚举类型的场景,且不允许 null 键,如状态机、固定类别的数据映射。 |
ConcurrentHashMap | 线程安全,分段锁设计并发性能高,适合高并发场景,不允许 null 键和 null 值。 | 适用于多线程环境下高效的键值对存储,比如在线用户状态、并发访问的数据缓存等。 |
4. Queue 接口类
LinkedList | 可作为 Queue 使用,支持队列的 FIFO 操作,增删效率高。 | 适用于普通队列操作,如任务队列、消息队列等。 |
PriorityQueue | 基于堆实现的优先级队列,按元素的自然顺序或自定义排序器排序。 | 适用于优先级调度场景,如事件调度、任务优先级处理等。 |
ArrayDeque | 基于数组实现的双端队列,支持双向操作(两端插入和删除),性能高。 | 适用于双端队列场景,如双向数据流、栈和队列的混合需求。 |
5. 集合的父类是谁?哪些安全的?
在 Java 中,集合类的父接口是 Collection
和 Map
。
集合接口的继承关系
-
Collection
Collection
是所有单一数据集合(如List
和Set
)的父接口。Collection
本身不能直接用于创建集合对象,但它定义了一些集合的基本操作(如添加、删除、遍历等)。- 主要子接口:
List
:有序、允许重复元素。Set
:无序、不允许重复元素。Queue
:有序,通常按照 FIFO(先进先出)规则进行元素操作。
- 主要子接口:
-
Map
Map
是键值对集合的父接口,表示一种将唯一键映射到特定值的数据结构。Map
本身也不能直接用于创建对象,但它定义了键值对的基本操作。- 主要子接口和实现类:
HashMap
:无序存储,允许null
键和null
值,线程不安全。LinkedHashMap
:按插入顺序存储,允许null
键和null
值。TreeMap
:按键排序,不允许null
键。Hashtable
:线程安全,不允许null
键和null
值。ConcurrentHashMap
:线程安全,高效并发。
- 主要子接口和实现类:
线程安全的集合类
在 Java 中,并非所有集合类都是线程安全的,只有部分实现类提供了线程安全的操作。
-
线程安全的集合类:
Vector
和Stack
:这两者都是线程安全的List
实现,Vector
的所有方法都加了同步锁,而Stack
继承自Vector
。Hashtable
:线程安全的Map
实现,不允许null
键和null
值,所有方法都加了同步锁。ConcurrentHashMap
:线程安全的高效Map
实现,分段锁设计保证了更好的并发性,适合高并发场景。CopyOnWriteArrayList
和CopyOnWriteArraySet
:线程安全的List
和Set
实现,适合多读少写的场景,因为每次写操作都会复制整个集合。
-
非线程安全的集合类:
ArrayList
、LinkedList
、HashSet
、HashMap
等标准集合类都是非线程安全的。如果在多线程环境下使用这些集合,需手动同步(如通过Collections.synchronizedList
包装)或使用并发集合。
6. 遍历集合的方式有哪些?
1. 使用 for-each
循环(增强型 for 循环)
适用于所有实现了 Iterable
接口的集合,如 List
、Set
、Queue
等。使用简单、代码简洁。
List<String> list = Arrays.asList("A", "B", "C");
for (String item : list) {
System.out.println(item);
}
2. 使用迭代器(Iterator
)
Iterator
是一种通用遍历方法,适用于所有集合,包括 List
、Set
和 Map
。Iterator
支持在遍历过程中删除元素,确保在多线程环境下的安全性。
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
对于 List
类型,还可以使用 ListIterator
,它支持双向遍历和修改元素:
List<String> list = Arrays.asList("A", "B", "C");
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
String item = listIterator.next();
System.out.println(item);
}
7. List下面有哪些实现
实现类 | 特点 | 适用场景 |
---|---|---|
ArrayList | 基于数组实现,查询快,增删慢,线程不安全。 | 适合频繁查询和顺序存储的场景。 |
LinkedList | 基于双向链表,增删快,查询慢,线程不安全。 | 适合频繁增删操作的场景。 |
Vector | 基于数组实现,线程安全,性能较低。 | 适合多线程环境的顺序列表,但一般不推荐使用。 |
Stack | 继承自 Vector ,实现 LIFO 的栈结构。 | 适合后进先出的场景,如回退功能。 |
CopyOnWriteArrayList | 基于写时复制实现,线程安全,适合读多写少。 | 适合多线程环境下读多写少的场景。 |
8. ArrayList与LinkedList区别?
底层实现 | 动态数组 | 双向链表 |
随机访问效率 | 高(O(1)) | 低(O(n)) |
插入/删除效率 | 末尾高效,中间位置低效 | 首尾高效,中间位置高效(调整引用指针) |
内存占用 | 较小,存储元素本身 | 较大,每个元素需额外存储前后引用指针 |
线程安全性 | 线程不安全 | 线程不安全 |
适用场景 | 频繁读取、少量增删 | 频繁插入、删除(如队列、栈实现) |
9. ArrayList与Vector区别呢?为什么要用ArrayList取代Vector呢?
1. 线程安全性
-
ArrayList:非线程安全,没有同步机制,因此在多线程环境下需要手动同步。
-
Vector:线程安全,内部方法使用
synchronized
进行同步。每次访问或修改数据时都会加锁,保证线程安全性。为什么使用
ArrayList
替代Vector
?
在现代 Java 开发中,通常采用外部同步或使用CopyOnWriteArrayList
或Collections.synchronizedList()
来确保线程安全,而不需要依赖Vector
的同步机制。Vector
的同步是强制的,会影响性能,因此在不需要线程安全的场景下,ArrayList
是更好的选择。
2. 性能
- ArrayList:因为没有同步,性能比
Vector
高,适合单线程环境或手动控制同步的多线程环境。 - Vector:由于同步机制的存在,性能比
ArrayList
低,尤其是在频繁操作的情况下,过多的同步操作会导致性能损耗。
3. 扩容机制
-
ArrayList:默认情况下,容量不足时会扩容为原来的 1.5 倍(即 50%)。
-
Vector:默认情况下,容量不足时会扩容为原来的 2 倍。虽然这种扩容机制减少了扩容次数,但会增加内存消耗。
为什么使用
ArrayList
替代Vector
?ArrayList
的扩容机制相比Vector
更加节约内存,并减少不必要的扩容操作,更加灵活。
10. Java.util.ArrayList常用的方法有哪些?
1. 添加元素
add(E e)
: 将元素e
添加到ArrayList
的末尾。add(int index, E element)
: 在指定的索引位置插入元素element
。
2. 获取元素
get(int index)
: 获取指定索引位置的元素。
3. 修改元素
set(int index, E element)
: 用新的元素element
替换指定索引位置的元素。
4. 删除元素
remove(int index)
: 移除指定索引位置的元素。remove(Object o)
: 移除首次出现的指定元素o
。clear()
: 清空ArrayList
中的所有元素。
5. 查询元素
contains(Object o)
: 检查ArrayList
中是否包含指定元素o
。indexOf(Object o)
: 返回指定元素o
首次出现的索引位置,如果不存在则返回 -1。lastIndexOf(Object o)
: 返回指定元素o
最后一次出现的索引位置。
6. 获取大小
size()
: 返回ArrayList
中的元素个数。
7. 判断是否为空
isEmpty()
: 检查ArrayList
是否为空。
11. Arraylist 是有序还是无序?为什么?
ArrayList
是有序的,因为它会按照元素插入的顺序来存储和访问数据。
原因
-
顺序存储:
ArrayList
基于动态数组实现,每个元素都有一个固定的索引位置。插入时,元素会按顺序依次存储。 -
索引访问:
ArrayList
提供按索引访问元素的方法(如get(int index)
),这意味着我们可以通过索引确定每个元素的顺序。 -
插入顺序:在不排序的情况下,
ArrayList
中的元素会保持插入时的顺序,不会因为插入或删除而打乱已有元素的顺序。
因此,ArrayList
是有序的集合类,其元素按插入顺序排列,适合需要顺序访问或按索引快速访问的场景。
12. Set集合有哪些实现类,分别有什么特点?
1. HashSet
- 特点:基于哈希表实现的集合,不保证元素的顺序。
- 存储顺序:无序(插入顺序不被保证),但可以实现快速存取。
- 速度:插入、删除、查找的时间复杂度为 O(1),性能通常比其他 Set 实现更高。
- 注意事项:由于使用哈希算法,
HashSet
中存储的元素需要正确实现hashCode()
和equals()
方法。
2. LinkedHashSet
- 特点:
HashSet
的子类,基于链表和哈希表的组合实现,保留了元素的插入顺序。 - 存储顺序:有序(按元素的插入顺序存储)。
- 速度:在保证插入顺序的前提下,插入、删除、查找的时间复杂度仍然为 O(1),但略慢于
HashSet
。 - 适用场景:适合需要按插入顺序遍历元素的场景。
3. TreeSet
- 特点:基于红黑树(自平衡的二叉查找树)实现,元素会按自然顺序或自定义比较器排序。
- 存储顺序:有序(按元素的自然顺序或自定义排序规则存储)。
- 速度:插入、删除、查找的时间复杂度为 O(log n),由于排序,性能一般低于
HashSet
和LinkedHashSet
。 - 适用场景:适合需要排序的场景,或者需要按顺序遍历元素的情况。
13. List集合和Set集合的区别?
1. 是否允许重复元素
- List:允许存储重复的元素。例如,一个
List
中可以有多个相同的元素。 - Set:不允许存储重复的元素,每个元素在
Set
中都是唯一的。
2. 元素的存储顺序
- List:有序集合,按照元素的插入顺序进行存储和访问。可以通过索引访问元素。
- Set:一般是无序的(如
HashSet
),但有的实现类(如LinkedHashSet
)会按插入顺序存储,TreeSet
则按自然顺序或自定义比较器排序。
3. 索引支持
- List:支持按索引访问元素,提供了
get(int index)
、indexOf(Object o)
等方法,可以直接访问或查找特定索引位置的元素。 - Set:不支持索引访问,没有按位置访问的功能。
Set
中的元素只能通过迭代器或增强型for
循环来遍历。
4. 常见实现类
- List:
ArrayList
:基于动态数组实现,访问速度快,增删元素效率略低。LinkedList
:基于双向链表实现,增删元素效率较高,但随机访问速度较慢。Vector
:线程安全的List
实现,已较少使用。
- Set:
HashSet
:基于哈希表实现,不保证顺序,查找速度快。LinkedHashSet
:基于哈希表和链表,按插入顺序存储。TreeSet
:基于红黑树实现,按自然顺序或自定义顺序存储,支持排序。
14. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
Set
使用equals()
和hashCode()
方法来区分重复元素。==
比较的是内存地址,而equals()
比较的是内容。
15. TreeSet两种排序方式在使用的时候怎么起作用?
- 自然排序:依赖
Comparable
接口中的compareTo()
方法,适用于需要默认排序的情况。 - 定制排序:依赖
Comparator
接口,可以在创建TreeSet
时定义自定义排序规则,用于特定排序需求。
16. TreeSet的数据结构
TreeSet
的底层数据结构是红黑树(Red-Black Tree),它是一种自平衡的二叉搜索树。由于 TreeSet
使用红黑树实现,因此它可以保证集合中元素的有序性和高效的插入、删除、查找操作。
17. 说一下Java的集合Map有哪些Map?
1. HashMap
- 特点:基于哈希表实现,存储无序。键和值都允许为
null
(键只能有一个null
)。 - 线程安全性:非线程安全,如果需要线程安全,可以使用
Collections.synchronizedMap(new HashMap<>())
。 - 时间复杂度:平均情况下,插入、删除、查找的时间复杂度为 O(1)。
- 适用场景:适用于不要求顺序、需要快速查找的场景。
2. LinkedHashMap
- 特点:
HashMap
的子类,保留了键值对的插入顺序(也可以按访问顺序)。 - 线程安全性:非线程安全。
- 时间复杂度:与
HashMap
类似,平均时间复杂度为 O(1)。 - 适用场景:适用于需要维护元素插入顺序或按访问顺序迭代的场景。
3. TreeMap
- 特点:基于红黑树实现,键值对按键的自然顺序或自定义比较器的顺序排序。
- 线程安全性:非线程安全。
- 时间复杂度:查找、插入、删除操作的时间复杂度为 O(log n)。
- 适用场景:适用于需要按顺序遍历键值对的场景。
4. Hashtable
- 特点:基于哈希表实现,早期的
Map
实现类,不允许键或值为null
。 - 线程安全性:线程安全,通过同步方法实现线程安全。
- 时间复杂度:查找、插入、删除的时间复杂度为 O(1)。
- 适用场景:适用于多线程环境下不允许键或值为
null
的情况(不过由于性能问题,现已较少使用)。
18. final怎么用,修饰Map可以继续添加数据吗?
final
修饰Map
后,Map
的引用地址不能改变,即不能重新指向其他Map
对象。final
并不影响Map
的内容,因此可以在Map
中继续添加、删除或修改元素。
19. Set和Map的比较
HashSet底层就是HashMap
LinkedHashSet底层就是LinkedHashMap
TreeSet底层就是TreeMap
20. HashMap说一下,线程安全吗?
为什么 HashMap
不是线程安全的?
-
无同步机制:
HashMap
的方法没有进行同步(synchronized)处理,因此多个线程可以同时操作HashMap
,这可能导致竞态条件(Race Condition),如覆盖或丢失数据。 -
扩容时的并发问题:
HashMap
在需要扩容时,会重新分配内部的哈希桶数组并将数据重新分配到新的桶中。如果多个线程同时触发了扩容,可能会出现环形链表、数据丢失等问题,导致死循环或性能问题。
线程安全的替代方案
-
ConcurrentHashMap:
ConcurrentHashMap
是HashMap
的线程安全替代品。它采用了分段锁(Segmented Lock)机制,在高并发下可以保证线程安全,同时性能也优于使用同步锁的Hashtable
。 -
Collections.synchronizedMap():可以使用
Collections.synchronizedMap()
方法来包装HashMap
,得到一个线程安全的Map
。这种方式会对HashMap
的所有访问方法进行同步处理,但性能较差,因为所有操作都在同一个锁上进行串行化。
21. HashMap和Hashbable的区别?
线程安全性 | 不安全,需手动同步 | 线程安全,自动同步 |
是否允许 null 键/值 | 允许 null 键和 null 值 | 不允许 null 键和值 |
性能 | 更高效(无同步机制) | 性能较差(由于同步机制) |
迭代器 | fail-fast 迭代器(检测并发修改) | 传统的迭代器(没有 fail-fast ) |
继承关系 | 继承自 AbstractMap | 继承自 Dictionary (已废弃) |
使用推荐 | 推荐使用,特别是在现代应用中 | 不推荐使用,已经被淘汰 |
22. Hashtable是怎么实现的,为什么线程安全?
1. Hashtable
的实现结构
Hashtable
是基于哈希表实现的,这与 HashMap
类似。哈希表使用数组和链表(或其他数据结构)来存储数据,其核心思想是通过哈希函数将键(key)映射到数组中的索引位置,从而实现快速的查找、插入和删除。
- 哈希表数组:
Hashtable
底层使用一个数组来存储键值对。每个数组元素是一个链表或树(如果哈希冲突严重)。每个键值对通过哈希函数计算出键的哈希值,进而映射到数组中的一个索引位置。 - 链表解决冲突:当两个不同的键经过哈希函数计算后得到相同的索引时,会发生哈希冲突。
Hashtable
会使用链表来存储这些哈希冲突的键值对。即,多个键值对会被存储在同一个位置的链表中。
2. Hashtable
的线程安全性
Hashtable
的线程安全性主要来源于它对所有方法的同步(synchronization)。在多线程环境中,多个线程可能同时访问同一个 Hashtable
对象,Hashtable
会使用 synchronized
关键字来确保每次只有一个线程能够访问对象的内部状态,从而防止数据竞争和不一致的状态。
23. HashMap和LinkedHashMap的区别
存储顺序 | 无序 | 按插入顺序或访问顺序 |
实现结构 | 基于哈希表 | 基于哈希表 + 双向链表 |
性能 | 较高,操作较快 | 较低,因维护顺序而稍微慢一些 |
内存开销 | 较小 | 较大,额外维护链表指针 |
适用场景 | 不关心顺序的场景 | 需要维持顺序(如缓存、按顺序遍历) |
null 键/值 | 允许(最多一个 null 键) | 允许(最多一个 null 键) |
构造方法 | 简单构造方法 | 支持按顺序排序的构造方法 |
24. HashMap 和 TreeMap 的区别
HashMap
适合那些不关心顺序、需要快速查找、插入和删除的场景,通常性能更好,尤其是在大数据量的情况下。TreeMap
适合那些需要保证键的有序性,或者需要根据键的顺序进行遍历的场景,尤其适用于有序集合操作,如获取最大/最小键值对、按顺序遍历等。
25. HashMap里面实际装的是什么?
HashMap
内部实际存储的是Entry
对象,每个Entry
对象存储一个键值对(key-value)。- 元素是存储在一个数组中,如果发生哈希冲突,使用链表或红黑树来解决。
HashMap
采用哈希算法来确定元素存储的位置,元素的顺序是无序的。
26. HashMap的key存储在哪里?和value存储在一起吗?那么value存储在哪里?说具体点?
key
和value
是存储在Entry
对象中的。Entry
对象 存储在HashMap
的 数组 中。数组中的每个元素是一个链表或红黑树的头节点,用于处理哈希冲突。key
和value
存储在同一个Entry
对象内,而next
指针用于处理冲突时的链表连接。
因此,HashMap
的 key
和 value
会通过 Entry
对象一起存储在哈希表的数组中,而哈希表中的每个位置可能有多个 Entry
对象(在发生哈希冲突时)。
27. 自定义类型可以作为Key么?
- 自定义类型可以作为
HashMap
的key
,但必须确保自定义类正确实现了hashCode()
和equals()
方法,这样才能保证哈希值的正确性和键的唯一性。 - 键对象的
hashCode()
和equals()
方法应该根据对象的实际属性来实现,确保哈希表的效率和正确性。
28. 集合类的工具类是谁?用过工具类哪些方法?
在 Java 中,集合类的工具类是 java.util.Collections
类,它提供了许多静态方法来操作和处理集合(如 List
、Set
、Map
等)。这些方法大大简化了集合的操作,增强了集合类的功能。
常用的 Collections
类方法
1. 排序方法
-
sort(List<T> list)
: 用于对List
集合进行升序排序。排序的依据是元素的自然顺序(即元素实现了Comparable
接口)。 -
sort(List<T> list, Comparator<? super T> c)
: 用于按照指定的Comparator
对List
进行排序,可以自定义排序规则。
2. 反转方法
reverse(List<?> list)
: 用于反转List
中元素的顺序
3. 填充方法
fill(List<? super T> list, T obj)
: 用指定的元素替换List
中的所有元素
4. 查找方法
-
max(Collection<? extends T> coll)
: 返回集合中最大元素。要求元素实现了Comparable
接口。 -
min(Collection<? extends T> coll)
: 返回集合中最小的元素
29. Collection 和 Collections的区别?
Collection
是集合框架的根接口,定义了集合的基本操作方法,所有集合类(如List
、Set
等)都实现了Collection
接口。Collections
是一个工具类,提供了许多静态方法来操作和处理集合,如排序、查找、反转等。它不用于定义集合类型,而是用于执行常见的集合操作。
30. ArrayList 如何实现排序
1. 使用 Collections.sort()
对 ArrayList
进行排序
Collections.sort()
是 Java 提供的一个静态方法,用于对实现了 Comparable
接口的元素进行排序。它对 List
进行升序排序,并且修改原列表。如果要实现自定义的排序顺序,可以传入一个 Comparator
对象。
31. HashMap是否线程安全,怎样解决HashMap的线程不安全
HashMap
本身不是线程安全的,在多线程环境下使用时需要特别小心。- 如果需要线程安全的
Map
,最推荐使用ConcurrentHashMap
,它可以在多线程环境下高效地进行并发操作。 - 如果必须使用
HashMap
,可以通过Collections.synchronizedMap()
或显式加锁(如使用ReentrantLock
)来确保线程安全,但这些方法可能会影响性能。