天水营销型网站建设,长沙传媒公司招聘信息,如何找广告商合作,玩具外贸网站模板大家好#xff0c;我是栗筝i#xff0c;从 2022 年 10 月份开始#xff0c;我持续梳理出了全面的 Java 技术栈内容#xff0c;一方面是对自己学习内容进行整合梳理#xff0c;另一方面是希望对大家有所帮助#xff0c;使我们一同进步。得到了很多读者的正面反馈。 而在 2… 大家好我是栗筝i从 2022 年 10 月份开始我持续梳理出了全面的 Java 技术栈内容一方面是对自己学习内容进行整合梳理另一方面是希望对大家有所帮助使我们一同进步。得到了很多读者的正面反馈。 而在 2023 年 10 月份开始我将推出 Java 面试题/知识点系列内容期望对大家有所助益让我们一起提升。 本篇是对 Java 基础系列的面试题 / 知识点的总结的上篇 全网最全的 Java 面试题内容梳理持续更新中Java基础面试题知识点总结上篇Java基础面试题知识点总结下篇 文章目录 1、Java基础面试题问题2、Java基础面试题解答2.1、Java集合架构相关2.2、JavaList集合相关2.3、JavaQueue集合相关2.4、JavaSet集合相关 1、Java基础面试题问题
问题 1. 简述 Java 集合类都有哪些问题 2. 简述 Collection 与 Collections 的区别问题 3. 简述 List、Set、Map 三者的区别问题 4. 介绍一下 ArrayList 的底层结构和相关原理问题 5. 介绍一下 ArrayList 的扩容机制问题 6. 介绍一下 ArrayList 删除元素时有哪些顾虑问题 7. 介绍一下 ArrayList 中怎么在遍历移除一个元素问题 8. 介绍一下 ArrayList 是线程安全的吗如何保证 ArrayList 的线程安全问题 9. 简述 ArrayList 和 LinkedList 的区别问题 10. 简述 ArrayList 和 Vector 的区别问题 11. 简述 ArrayList 与 Array 的区别问题 12. 介绍一下 LinkedList 的底层结构和相关原理问题 13. 介绍一下 Vector 的底层结构和相关原理问题 14. 介绍一下 Stack 的底层结构和相关原理问题 15. 请解释一下 Java 中的 CopyOnWriteArrayList问题 16. 简述队列和栈是什么它们有何区别问题 17. 请解释一下 Java 中的 Queue 和 Deque问题 18. 请解释一下 Java 中的 PriorityQueue问题 19. 请解释一下 Java 中的 BlockingQueue问题 20. 介绍一下 HashSet 的底层结构和相关原理问题 21. 介绍一下 LinkedHashSet 的底层结构和相关原理问题 22. 介绍一下 TreeSet 的底层结构和相关原理问题 23. 请解释一下 Java 中的 EnumSet问题 24. 请解释一下 Java 中的 SortedSet问题 25. 请解释一下 Java 中的 NavigableSet 2、Java基础面试题解答
2.1、Java集合架构相关
问题 1. 简述 Java 集合类都有哪些
解答Java 集合类呢主要是指 java.Util包 下的集合容器。主要包含三种List、Set、Map其中 List、Set 主要继承自 Collection 接口然后它们三个又都依赖了 Iterator 迭代器
首先List 常用的就是 ArrayList、LinkedList、Vector其中 ArrayList 的底层实现是数组LinkedList 的实现是双向链表此外 LinkedList 还实现了 Queue 队列也在 Collection 下的接口Vector 就是 ArrayList 的线程安全版本但不推荐使用此外 Java 中的栈 Stack 还继承自 Vector其次Set 集合常用的就是 HashSet 和 TreeSet它们的实现就是依赖于 HahsMap 和 TreeMap最后Map 集合就是 HahsMap 和 TreeMap了。这些实现大多数都是非线程安全的。
问题 2. 简述 Collection 与 Collections 的区别
解答Collection 和 Collections 在 Java 中是两个不同的概念。 Collection 是一个接口它是 List、Set 和 Queue 接口的父接口定义了适用于任何集合的操作如 add、remove 和 contains。 Collections 是一个类它包含了一些静态的工具方法这些方法可以对集合进行操作如排序sort、查找binarySearch、修改fill、copy、同步控制synchronizedXxx等。
问题 3. 简述 List、Set、Map 三者的区别
解答List、Set 和 Map 是 Java 集合框架中的三种基本接口它们的区别主要体现在存储内容和使用方式上。 List是一个有序的集合可以包含重复的元素。它提供了索引的访问方式我们可以通过索引列表的位置来访问或者搜索列表中的元素。主要实现类有 ArrayList、LinkedList 和 Vector。 Set是一个不允许有重复元素的集合也就是说每个元素只能出现一次。它不提供索引访问方式主要用于存在性检查即检查一个元素是否存在。主要实现类有 HashSet、LinkedHashSet 和 TreeSet。 Map是一个键值对的集合每个键映射到一个值键不能重复每个键最多只能映射到一个值。它提供了基于键的访问方式我们可以通过键来获取、删除或者检查值。主要实现类有 HashMap、LinkedHashMap、TreeMap 和 Hashtable。
2.2、JavaList集合相关
问题 4. 介绍一下 ArrayList 的底层结构和相关原理
解答ArrayList 是 Java 中常用的一种动态数组实现其底层是基于数组实现的。 存储结构ArrayList 内部使用一个数组elementData来存储元素。当添加元素时如果数组已满就会创建一个新的更大的数组并将原数组的内容复制到新数组中这个过程称为扩容。 扩容机制ArrayList 的扩容机制是每次扩容时新数组的大小是原数组大小的 1.5 倍。如果这个值仍然不足以满足需求那么新数组的大小就直接设置为需求的大小。 插入和删除ArrayList 在尾部插入和删除元素非常高效时间复杂度为 O(1)。但是在中间或头部插入和删除元素需要移动大量元素时间复杂度为 O(n)。 访问元素由于底层是数组所以 ArrayList 支持随机访问按索引访问元素的时间复杂度为 O(1)。 线程安全ArrayList 是非线程安全的如果需要在多线程环境下使用可以使用 Collections.synchronizedList() 方法返回一个线程安全的 ArrayList或者使用线程安全的 Vector。
总的来说ArrayList 是一种动态数组结构适合随机访问场景但在中间或头部插入和删除元素时效率较低。
问题 5. 介绍一下 ArrayList 的扩容机制
解答ArrayList 的扩容机制是这样的 当我们向 ArrayList 添加元素时如果当前数组已满即数组的大小等于其元素的数量那么 ArrayList 就需要进行扩容。 ArrayList 的扩容过程是创建一个新的数组这个新数组的大小是原数组大小的 1.5 倍即原数组大小加上原数组大小的一半。具体来说如果原数组大小为 10那么新数组的大小就是 15。 创建新数组后ArrayList 会将原数组中的所有元素复制到新数组中然后丢弃原数组。 这个扩容过程是自动进行的我们在使用 ArrayList 时无需关心其扩容机制。
需要注意的是ArrayList 的这种扩容机制意味着其在添加大量元素时可能会有一定的性能开销因为每次扩容都需要创建新数组并复制元素。如果我们预先知道 ArrayList 将要存储的元素数量可以在创建 ArrayList 时指定其初始大小这样可以减少扩容操作提高性能。
问题 6. 介绍一下 ArrayList 删除元素时有哪些顾虑
解答在使用 ArrayList 删除元素时需要注意以下几点 ConcurrentModificationException在遍历 ArrayList 的过程中直接调用 ArrayList 的 remove() 方法删除元素可能会抛出 ConcurrentModificationException 异常。正确的做法是使用 Iterator 的 remove() 方法删除元素。 性能考虑ArrayList 在删除元素时为了保持元素的连续性会将后面的元素向前移动所以删除元素的性能与 ArrayList 的大小成正比。如果需要频繁删除元素可以考虑使用 LinkedList。 索引越界在调用 remove(int index) 方法时如果索引超出了 ArrayList 的范围会抛出 IndexOutOfBoundsException 异常。所以在删除元素前需要确保索引是有效的。 自动装箱ArrayList 的 remove() 方法有两个重载版本remove(int index) 和 remove(Object o)。如果 ArrayList 存储的是基本类型的包装类比如 Integer那么在调用 remove() 方法时需要注意自动装箱可能带来的问题。例如list.remove(1) 可能不是删除元素 1而是删除索引为 1 的元素。 空指针如果 ArrayList 中存储的是对象那么在删除元素时如果 ArrayList 中存在 null需要注意 NullPointerException 异常。
问题 7. 介绍一下 ArrayList 中怎么在遍历移除一个元素
解答在遍历 ArrayList 时移除元素需要注意 ConcurrentModificationException 异常。以下是几种常见的移除元素的方法
使用 Iterator 的 remove() 方法。这是最安全且推荐的方式。
IteratorString iterator list.iterator();
while (iterator.hasNext()) {String item iterator.next();if (需要移除的条件) {iterator.remove();}
}使用 List 的 remove() 方法但需要倒序遍历。
for (int i list.size() - 1; i 0; i--) {if (需要移除的条件) {list.remove(i);}
}使用 Java 8 的 Collection.removeIf() 方法。
list.removeIf(item - 需要移除的条件);以上三种方法都可以在遍历 ArrayList 时移除元素但是推荐使用 Iterator 的 remove() 方法因为它在面对并发修改时可以提供正确的行为。
问题 8. 介绍一下 ArrayList 是线程安全的吗如何保证 ArrayList 的线程安全
解答ArrayList 是非线程安全的它的方法没有进行同步处理所以在多线程环境下可能会出现问题。
如果需要在多线程环境下使用 ArrayList有以下几种方式可以保证线程安全
使用 Collections.synchronizedList() 方法创建一个同步的 ArrayList
ListString list Collections.synchronizedList(new ArrayList());这个方法会返回一个线程安全的 List所有的方法都进行了同步处理。
使用 CopyOnWriteArrayList这是一个线程安全的 List 实现
ListString list new CopyOnWriteArrayList();CopyOnWriteArrayList 在每次修改操作如添加、删除元素时都会复制一份新的数组这样可以避免修改操作对遍历操作的影响提供了一种读写分离的机制。 使用并发包 java.util.concurrent 中的其他线程安全集合如 ConcurrentLinkedQueue、ConcurrentHashMap 等。 使用 synchronized 关键字或 Lock 对象手动同步 ArrayList 的操作。
需要注意的是以上方法在提供线程安全的同时可能会带来一定的性能开销。
问题 9. 简述 ArrayList 和 LinkedList 的区别
解答ArrayList 和 LinkedList 都是 List 接口的实现但它们在内部数据结构和性能上有一些区别
内部数据结构ArrayList 是基于动态数组实现的支持随机访问按索引访问元素非常快时间复杂度为 O(1)。LinkedList 是基于双向链表实现的不支持高效的随机访问按索引访问元素需要从头或尾开始遍历时间复杂度为 O(n)。插入和删除ArrayList 的插入和删除操作需要进行数组元素的移动除非插入和删除操作在列表末尾进行所以插入和删除元素的时间复杂度为 O(n)。LinkedList 的插入和删除操作只需要改变节点的引用所以在列表中间插入和删除元素的时间复杂度为 O(1)前提是已经获取到了要插入位置的节点。内存占用ArrayList 的内存占用相对较低因为它只需要存储元素数据和数组的引用。LinkedList 的内存占用较高因为它需要额外存储节点之间的引用。
总的来说ArrayList 更适合随机访问场景LinkedList 更适合插入和删除操作频繁的场景。
问题 10. 简述 ArrayList 和 Vector 的区别
解答ArrayList 和 Vector 都是实现了 List 接口的类它们都是基于动态数组实现的但是在同步性和性能上有一些区别
同步性Vector 是线程安全的它的大部分方法都进行了同步处理可以在多线程环境下使用。实现上其实就是 Vector 在 ArrayList 的方法前面加上了 Synchronized。ArrayList 是非线程安全的它的方法没有进行同步处理所以在多线程环境下可能会出现问题。性能由于 Vector 进行了同步处理所以在单线程环境下Vector 的性能会比 ArrayList 差一些。ArrayList 在单线程环境下的性能比 Vector 好因为它没有进行同步处理。扩容ArrayList 在每次需要扩容时都会增加到原来的 1.5 倍。Vector 在每次需要扩容时都会增加到原来的 2 倍。
总的来说如果需要在多线程环境下使用可以选择 Vector如果是在单线程环境下或者已经通过其他方式处理了同步问题那么 ArrayList 会是更好的选择。
问题 11. 简述 ArrayList 与 Array 的区别
解答Array 和 ArrayList 是 Java 中两种不同的数据结构它们的主要区别在于大小的可变性、性能、类型限制和功能。
大小可变性Array 是固定长度的一旦创建其大小就不能改变。ArrayList 是动态的可以自动调整其大小以适应元素的添加和删除。性能Array 在访问元素时具有更好的性能因为它是基于索引的数据结构。ArrayList 在添加和删除元素时具有更好的性能特别是在列表的末尾因为它可以动态调整大小。类型限制Array 可以存储基本数据类型或对象。ArrayList 只能存储对象不能直接存储基本数据类型。功能Array 是一个简单的数据结构没有提供很多功能。ArrayList 是一个集合类提供了大量的方法如添加、删除、遍历等。
总的来说Array 和 ArrayList 各有优势选择哪种取决于具体的需求。
问题 12. 介绍一下 LinkedList 的底层结构和相关原理
解答LinkedList 是 Java 中常用的一种链表实现其底层是基于双向链表实现的。 存储结构LinkedList 内部使用一个双向链表来存储元素。每个元素节点都包含了对前一个元素和后一个元素的引用。 插入和删除LinkedList 在链表头部和尾部插入和删除元素非常高效时间复杂度为 O(1)。在链表中间插入和删除元素需要先找到对应的位置时间复杂度为 O(n)。 访问元素LinkedList 不支持高效的随机访问访问特定索引的元素需要从头或尾开始遍历时间复杂度为 O(n)。 线程安全LinkedList 是非线程安全的如果需要在多线程环境下使用可以使用 Collections.synchronizedList() 方法返回一个线程安全的 LinkedList。
总的来说LinkedList 是一种链表结构适合插入和删除操作频繁的场景但在访问元素时效率较低。
问题 13. 介绍一下 Vector 的底层结构和相关原理
解答Vector 是 Java 中的一种线程安全的动态数组实现其底层是基于数组实现的。 存储结构Vector 内部使用一个数组elementData来存储元素。当添加元素时如果数组已满就会创建一个新的更大的数组并将原数组的内容复制到新数组中这个过程称为扩容。 扩容机制Vector 的扩容机制是每次扩容时新数组的大小是原数组大小的 2 倍。如果这个值仍然不足以满足需求那么新数组的大小就直接设置为需求的大小。 插入和删除Vector 在尾部插入和删除元素非常高效时间复杂度为 O(1)。但是在中间或头部插入和删除元素需要移动大量元素时间复杂度为 O(n)。 访问元素由于底层是数组所以 Vector 支持随机访问按索引访问元素的时间复杂度为 O(1)。 线程安全Vector 的所有公共方法都进行了同步处理所以它是线程安全的。但这也意味着在单线程环境下Vector 的性能会比 ArrayList 差一些。
总的来说Vector 是一种线程安全的动态数组结构适合在多线程环境下使用但在单线程环境下由于同步处理带来的开销其性能会比 ArrayList 差一些。
问题 14. 介绍一下 Stack 的底层结构和相关原理
解答Stack 是 Java 中的一种后进先出LIFO的数据结构其底层是基于 Vector 实现的。 存储结构Stack 内部使用一个 Vector 来存储元素。当添加元素压栈时元素被添加到 Vector 的末尾当删除元素弹栈时元素从 Vector 的末尾被移除。 扩容机制由于 Stack 是基于 Vector 实现的所以其扩容机制与 Vector 相同。每次扩容时新数组的大小是原数组大小的 2 倍。 插入和删除Stack 的插入和删除操作都在 Vector 的末尾进行所以非常高效时间复杂度为 O(1)。 访问元素Stack 提供了 peek() 方法来查看栈顶元素时间复杂度为 O(1)。由于底层是 Vector所以 Stack 也支持按索引访问元素但这并不常用。 线程安全由于 Stack 是基于 Vector 实现的所以它也是线程安全的。但这也意味着在单线程环境下Stack 的性能会比基于 ArrayList 实现的 Deque 差一些。
总的来说Stack 是一种后进先出的数据结构适合在需要后进先出操作的场景下使用如函数调用栈、回溯算法等。
问题 15. 请解释一下 Java 中的 CopyOnWriteArrayList
解答CopyOnWriteArrayList 是 Java 中的一个线程安全的 List 实现它是通过“写时复制”Copy-On-Write策略来保证并发安全的。 写时复制策略当对 CopyOnWriteArrayList 进行修改操作如 add、set、remove 等时它并不直接在当前数组上进行修改而是先将当前数组进行复制然后在新的数组上进行修改最后再将引用指向新的数组。这样可以保证在修改过程中不会影响到读操作实现了读写分离。 读操作无锁由于所有的写操作都是在新的数组上进行的所以读操作是无锁的可以直接读取这对于读多写少的场景性能提升很大。 写操作加锁写操作修改、添加、删除等需要加锁防止多线程同时写入时导致数据不一致。 内存占用由于每次写操作都需要复制一个新的数组所以 CopyOnWriteArrayList 在内存占用上会比普通的 ArrayList 大。
总的来说CopyOnWriteArrayList 是一种适用于读多写少且需要线程安全的场景的 List 实现。但是由于写时复制策略它在内存占用和写操作性能上有一定的开销。
2.3、JavaQueue集合相关
问题 16. 简述队列和栈是什么它们有何区别
解答队列Queue和栈Stack是两种常见的数据结构它们在数据的存储和访问方式上有一些区别。 队列Queue队列是一种先进先出FIFOFirst In First Out的数据结构新元素添加到队列的尾部而移除元素则从队列的头部开始。队列常用于实现需要按照元素添加顺序进行处理的场景如任务队列、消息队列等。 栈Stack栈是一种后进先出LIFOLast In First Out的数据结构新元素添加到栈的顶部移除元素也从栈的顶部开始。栈常用于实现需要后进先出操作的场景如函数调用栈、撤销操作、深度优先搜索等。
总的来说队列和栈的主要区别在于元素的访问顺序队列是先进先出而栈是后进先出。
问题 17. 请解释一下 Java 中的 Queue 和 Deque
Queue 和 Deque 是 Java 中的两种接口分别代表队列和双端队列这两种数据结构。 Queue队列是一种先进先出FIFO的数据结构支持在队尾插入元素offer 方法在队头删除元素poll 方法查看队头元素peek 方法。常用的 Queue 实现类有 LinkedList、PriorityQueue 等。 Deque双端队列是一种特殊的队列它支持在两端插入和删除元素。除了支持 Queue 的所有操作外还支持在队头插入元素offerFirst 方法在队尾删除元素pollLast 方法查看队尾元素peekLast 方法。常用的 Deque 实现类有 ArrayDeque、LinkedList 等。
在实际使用时可以根据具体需求选择使用 Queue 还是 Deque以及选择合适的实现类。例如如果需要按元素的优先级进行处理可以使用 PriorityQueue如果需要在两端插入和删除元素可以使用 Deque。
问题 18. 请解释一下 Java 中的 PriorityQueue
解答PriorityQueue 是 Java 中的一种特殊的队列它的特点是队列中的元素按照它们的优先级进行排序。 存储结构PriorityQueue 内部使用一个二叉小顶堆来实现。二叉小顶堆是一种特殊的二叉树树中任意一个非叶子节点的值都不大于其子节点的值树的根节点顶部是所有节点中的最小值。 元素排序PriorityQueue 中的元素可以自然排序或者通过提供的 Comparator 进行自定义排序。在添加元素时会根据元素的优先级找到合适的位置保证堆的性质。 插入和删除插入元素和删除元素或者说是获取并删除最高优先级的元素的时间复杂度都是 O(log n)。 访问元素PriorityQueue 提供了 peek 方法来访问最高优先级的元素堆顶元素时间复杂度为 O(1)。 线程安全PriorityQueue 是非线程安全的如果需要在多线程环境下使用可以使用 PriorityBlockingQueue。
总的来说PriorityQueue 是一种可以动态调整内部元素顺序的队列适合实现需要动态排序的场景如任务调度、Dijkstra 算法、Huffman 编码等。
问题 19. 请解释一下 Java 中的 BlockingQueue
解答BlockingQueue 是 Java 中的一个接口它是一种特殊的队列主要提供了阻塞操作的支持适用于生产者消费者模式。 阻塞操作BlockingQueue 提供了 put 和 take 方法当队列满时put 方法会阻塞直到队列不满当队列空时take 方法会阻塞直到队列不空。这样可以简化生产者消费者模式的实现无需显式地进行同步和唤醒操作。 非阻塞操作BlockingQueue 也提供了非阻塞操作 offer 和 poll如果无法立即执行操作这些方法会返回一个特殊值如 null 或 false而不是阻塞。 超时操作BlockingQueue 还提供了带超时的 offer 和 poll 方法如果在指定的时间内无法执行操作这些方法会返回一个特殊值。 实现类BlockingQueue 的常用实现类有 ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue 等它们分别适用于不同的场景。
总的来说BlockingQueue 是一种支持阻塞操作的队列适合实现生产者消费者模式可以简化多线程编程。
2.4、JavaSet集合相关
问题 20. 介绍一下 HashSet 的底层结构和相关原理
解答HashSet 是基于 HashMap 实现的底层采用 HashMap 来保存所有元素。因此HashSet 的数据结构就是 HashMap 的数据结构。
HashMap 是一个散列表它存储的内容是键值对 (key-value)。HashMap 通过键的哈希值进行快速查找具有较高的查找和插入速度。
HashSet 中的元素实际上作为 HashMap 的键存在而 HashMap 的值则存储了一个固定的对象 PRESENT。因此HashSet 中的元素不能重复这是因为 HashMap 的键不能重复。
HashSet 的操作都是基于 HashMap 的操作来实现的例如添加元素、删除元素、查找元素等。
问题 21. 介绍一下 LinkedHashSet 的底层结构和相关原理
解答LinkedHashSet 是 HashSet 的一个子类它的底层是基于 LinkedHashMap 来实现的。
LinkedHashMap 是 HashMap 的一个子类它在 HashMap 的基础上增加了一个双向链表。这个双向链表连接了所有的键值对定义了键值对的迭代顺序。迭代的顺序可以是插入顺序也可以是访问顺序。
LinkedHashSet 中的元素实际上作为 LinkedHashMap 的键存在而 LinkedHashMap 的值则存储了一个固定的对象 PRESENT。因此LinkedHashSet 中的元素不能重复这是因为 LinkedHashMap 的键不能重复。
LinkedHashSet 的操作都是基于 LinkedHashMap 的操作来实现的例如添加元素、删除元素、查找元素等。由于 LinkedHashSet 维护了一个运行于所有条目的双向链表因此可以在用迭代器遍历 LinkedHashSet 时得到一个确定的顺序插入的顺序。
问题 22. 介绍一下 TreeSet 的底层结构和相关原理
解答TreeSet 是基于 TreeMap 实现的底层采用 TreeMap 来保存所有元素。因此TreeSet 的数据结构就是 TreeMap 的数据结构。
TreeMap 是一个红黑树自平衡的排序二叉树。它存储的内容是键值对 (key-value)。TreeMap 通过键的自然顺序或者自定义的比较器进行排序具有较高的查找和插入速度。
TreeSet 中的元素实际上作为 TreeMap 的键存在而 TreeMap 的值则存储了一个固定的对象 PRESENT。因此TreeSet 中的元素不能重复这是因为 TreeMap 的键不能重复。
TreeSet 的操作都是基于 TreeMap 的操作来实现的例如添加元素、删除元素、查找元素等。由于 TreeSet 是基于 TreeMap 实现的所以 TreeSet 的元素是有序的元素的排序方式取决于构造 TreeSet 时提供的 Comparator或者依赖元素的自然顺序Comparable。
TreeSet 是 SortedSet 接口的一个实现类它提供了一个基于树结构的 Set元素可以按照自然顺序或者自定义的比较器进行排序。
问题 23. 请解释一下 Java 中的 EnumSet
解答EnumSet 是 Java 中的一个专门为枚举类型设计的集合类。它继承自 AbstractSet并实现了 Set 接口。
以下是 EnumSet 的一些特性 EnumSet 中的所有元素都必须来自同一个枚举类型它在创建时显式或隐式地指定。 EnumSet 是有序的其元素的顺序就是它们在源代码中的顺序。 EnumSet 集合类的实现是非常高效和快速的其大部分操作都是通过位运算实现的。 EnumSet 不允许使用 null 元素如果尝试添加 null 元素它会抛出 NullPointerException。 EnumSet 是线程不安全的如果多个线程同时修改 EnumSet需要进行同步处理。
以下是创建 EnumSet 的一些方法
EnumSet.allOf(ClassE elementType)创建一个包含指定枚举类型的所有元素的 EnumSet。EnumSet.noneOf(ClassE elementType)创建一个指定枚举类型的空 EnumSet。EnumSet.of(E first, E... rest)创建一个最初包含指定元素的 EnumSet。EnumSet.range(E from, E to)创建一个包含从 from 元素到 to 元素范围内的所有元素的 EnumSet。EnumSet.copyOf(CollectionE c) 或 EnumSet.copyOf(EnumSetE s)创建一个与指定 EnumSet 具有相同元素类型的 EnumSet最初包含相同的元素如果有的话。
问题 24. 请解释一下 Java 中的 SortedSet
解答SortedSet 是 Java 集合框架中的一个接口它继承自 Set 接口。SortedSet 接口为集合中的元素提供了一个总的排序。
以下是 SortedSet 的一些特性 SortedSet 中的元素按照自然顺序或者自定义的比较器Comparator进行排序。 SortedSet 不允许插入 null 元素。如果尝试插入 null 元素它会抛出 NullPointerException。 SortedSet 是线程不安全的如果多个线程同时修改 SortedSet需要进行同步处理。
以下是 SortedSet 的一些主要方法 Comparator? super E comparator()返回用于对此 set 中的元素进行排序的比较器如果此 set 使用其元素的自然顺序则返回 null。 E first()返回此 set 中当前第一个最低元素。 SortedSetE headSet(E toElement)返回此 set 的部分视图其元素严格小于 toElement。 E last()返回此 set 中当前最后一个最高元素。 SortedSetE subSet(E fromElement, E toElement)返回此 set 的部分视图其元素的范围从 fromElement包括到 toElement不包括。 SortedSetE tailSet(E fromElement)返回此 set 的部分视图其元素大于等于 fromElement。
问题 25. 请解释一下 Java 中的 NavigableSet
解答NavigableSet 是 Java 集合框架中的一个接口它继承自 SortedSet 接口。NavigableSet 描述了一种可以通过搜索方法导航的数据结构。
以下是 NavigableSet 的一些特性 NavigableSet 中的元素按照自然顺序或者自定义的比较器Comparator进行排序。 NavigableSet 提供了多种导航方法例如获取小于/大于某个元素的最大/最小元素等。 NavigableSet 不允许插入 null 元素。如果尝试插入 null 元素它会抛出 NullPointerException。 NavigableSet 是线程不安全的如果多个线程同时修改 NavigableSet需要进行同步处理。
以下是 NavigableSet 的一些主要方法 E lower(E e)返回此 set 中严格小于给定元素的最大元素如果不存在这样的元素则返回 null。 E floor(E e)返回此 set 中小于等于给定元素的最大元素如果不存在这样的元素则返回 null。 E ceiling(E e)返回此 set 中大于等于给定元素的最小元素如果不存在这样的元素则返回 null。 E higher(E e)返回此 set 中严格大于给定元素的最小元素如果不存在这样的元素则返回 null。 E pollFirst()获取并移除此 set 中的第一个最低元素如果此 set 为空则返回 null。 E pollLast()获取并移除此 set 中的最后一个最高元素如果此 set 为空则返回 null。
TreeSet 是 NavigableSet 接口的一个实现类它提供了一个基于树结构的 Set元素可以按照自然顺序或者自定义的比较器进行排序。