40 个 Java 集合面试问题和答案(建议收藏)下
前言:
Java 集合框架是 Java 编程语言的基本方面。这是java面试问题的重要主题之一。在这里,我列出了一些关于java 集合框架的重要问题和答案。(下)
1.HashMap 和 Hashtable 有什么区别?
HashMap 和 Hashtable 都实现了 Map 接口,看起来很相似,但是 HashMap 和 Hashtable 有以下区别。
HashMap 允许空键和值,而 Hashtable 不允许空键和值。
Hashtable 已同步,但 HashMap 未同步。所以HashMap更适合单线程环境,Hashtable适合多线程环境。
LinkedHashMap作为 HashMap 的子类在 Java 1.4 中引入,因此如果您需要迭代顺序,您可以轻松地从 HashMap 切换到 LinkedHashMap,但迭代顺序不可预测的 Hashtable 并非如此。
HashMap 提供了一组键来迭代,因此它是快速失败的,但 Hashtable 提供了不支持此功能的键的枚举。
Hashtable 被认为是遗留类,如果你在迭代时寻找 Map 的修改,你应该使用 ConcurrentHashMap。
2.如何在 HashMap 和 TreeMap 之间做出决定?
对于在 Map 中插入、删除和定位元素,HashMap 提供了最佳选择。但是,如果您需要按排序顺序遍历键,那么 TreeMap 是您更好的选择。根据集合的大小,将元素添加到 HashMap,然后将映射转换为 TreeMap 以进行排序键遍历可能会更快。
3.ArrayList和Vector有什么异同?
ArrayList 和 Vector 在许多方面都是相似的类。
- 两者都是基于索引的,并由内部数组备份。
- 两者都保持插入顺序,我们可以按插入顺序获取元素。
- ArrayList 和 Vector 的迭代器实现在设计上都是快速失败的。
- ArrayList 和 Vector 都允许空值和使用索引号随机访问元素。
这些是 ArrayList 和 Vector 之间的区别。
- Vector 是同步的,而 ArrayList 是不同步的。但是,如果您在迭代时寻找列表的修改,您应该使用 CopyOnWriteArrayList。
- ArrayList 比 Vector 快,因为它不会因为同步而产生任何开销。
- ArrayList 更加通用,因为我们可以使用 Collections 实用程序类轻松地从中获取同步列表或只读列表。
4.Array 和 ArrayList 有什么区别?什么时候使用 Array 而不是 ArrayList?
数组可以包含原始对象或对象,而 ArrayList 只能包含对象。
数组是固定大小的,而 ArrayList 大小是动态的。
数组并没有像ArrayList那样提供很多特性,比如addAll、removeAll、iterator等。虽然ArrayList是我们处理list时的明显选择,但很少有时候数组很好用。
如果列表的大小是固定的,并且主要用于存储和遍历它们。
对于原始数据类型的列表,虽然集合使用自动装箱来减少编码工作,但在处理固定大小的原始数据类型时仍然会使它们变慢。
如果您正在处理固定的多维情况,使用 [][] 远比 List<List<>>
5.ArrayList 和 LinkedList 有什么区别?
ArrayList 和 LinkedList 都实现了 List 接口,但它们之间存在一些差异。
ArrayList 是由 Array 支持的基于索引的数据结构,因此它提供对其元素的随机访问,性能为 O(1),但 LinkedList 将数据存储为节点列表,其中每个节点都链接到它的前一个节点和下一个节点。所以即使有一种使用索引获取元素的方法,但在内部它是从开始遍历到索引节点然后返回元素,所以性能是O(n),比ArrayList慢。
与 ArrayList 相比,LinkedList 中元素的插入、添加或删除更快,因为在中间添加元素时没有调整数组大小或更新索引的概念。
LinkedList 比 ArrayList 消耗更多内存,因为 LinkedList 中的每个节点都存储了前一个和下一个元素的引用。
6.哪些集合类提供对其元素的随机访问?
ArrayList、HashMap、TreeMap、Hashtable 类提供对其元素的随机访问。
7.什么是枚举集?
java.util.EnumSet是设置实现以与枚举类型一起使用。枚举集合中的所有元素都必须来自一个枚举类型,该枚举类型在创建集合时显式或隐式指定。EnumSet 未同步,并且不允许使用 null 元素。它还提供了一些有用的方法,如 copyOf(Collection c)、of(E first, E... rest) 和 ComplementOf(EnumSet s)。
8.哪些集合类是线程安全的?
Vector、Hashtable、Properties 和 Stack 是同步类,因此它们是线程安全的,可以在多线程环境中使用。Java 1.5 Concurrent API 包括一些允许在迭代时修改集合的集合类,因为它们在集合的克隆上工作,因此它们在多线程环境中使用是安全的。
9.什么是并发集合类?
Java 1.5 Concurrent 包 ( java.util.concurrent) 包含线程安全的集合类,允许在迭代时修改集合。按照设计,迭代器是快速失败的并抛出
ConcurrentModificationException。其中一些类是CopyOnWriteArrayList, ConcurrentHashMap, CopyOnWriteArraySet。阅读这些帖子以更详细地了解它们。
避免
ConcurrentModificationException
CopyOnWriteArrayList 示例
HashMap 与 ConcurrentHashMap
10.什么是阻塞队列?
java.util.concurrent.BlockingQueue是一个队列,它支持在检索和删除元素时等待队列变为非空,并在添加元素时等待队列中的空间可用的操作。BlockingQueue 接口是 java 集合框架的一部分,主要用于用于实现生产者消费者问题。我们不需要担心等待 BlockingQueue 中的空间可供生产者使用或对象可供消费者使用,因为它由 BlockingQueue 的实现类处理。Java 提供了几种 BlockingQueue 实现,例如 ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue 等.
11.什么是队列和堆栈,列出它们的区别?
Queue 和 Stack 都用于在处理数据之前存储数据。java.util.Queue是一个接口,其实现类存在于 java 并发包中。队列允许以先进先出 (FIFO) 顺序检索元素,但并非总是如此。还有一个 Deque 接口,允许从队列的两端检索元素。
堆栈类似于队列,只是它允许以后进先出 (LIFO) 顺序检索元素。
Stack 是一个扩展 Vector 的类,而 Queue 是一个接口。
12.什么是集合类?
java.util.Collections是一个实用程序类,仅由操作或返回集合的静态方法组成。它包含对集合进行操作的多态算法、“包装器”,它返回一个由指定集合支持的新集合,以及其他一些零碎的东西。这个类包含集合框架算法的方法,例如二进制搜索、排序、改组、反向等
13.什么是 Comparable 和 Comparator 接口?
Java 提供了 Comparable 接口,如果我们想使用 Arrays 或 Collections 排序方法,任何自定义类都应该实现该接口。Comparable 接口具有用于排序方法的 compareTo(T obj) 方法。我们应该重写此方法,如果“this”对象小于、等于或大于作为参数传递的对象,则它返回负整数、零或正整数。但是,在大多数现实生活场景中,我们希望根据不同的参数进行排序。例如,作为 CEO,我想根据 Salary 对员工进行排序,HR 想根据年龄对员工进行排序。这是我们需要使用Comparator接口的情况,因为Comparable.compareTo(Object o)方法实现只能基于一个字段排序,我们不能选择要排序的字段 Object.Comparator 接口compare(Object o1, Object o2)方法需要实现,需要两个 Object 参数,它应该以返回的方式实现如果第一个参数小于第二个参数,则返回负整数;如果它们相等,则返回零;如果第一个参数大于第二个参数,则返回正整数。
14.Comparable 和 Comparator 接口有什么区别?
Comparable 和 Comparator 接口用于对对象的集合或数组进行排序。Comparable 接口用于提供对象的自然排序,我们可以使用它来提供基于单一逻辑的排序。
Comparator 接口用于提供不同的排序算法,我们可以选择我们想要使用的比较器来对给定的对象集合进行排序。
15.我们如何对对象列表进行排序?
如果我们需要对一个对象数组进行排序,我们可以使用Arrays.sort(). 如果我们需要对对象列表进行排序,我们可以使用Collections.sort(). 这两个类都重载了 sort() 方法,用于自然排序(使用 Comparable)或基于标准排序(使用 Comparator)。Collections 内部使用 Arrays 排序方法,因此两者具有相同的性能,只是 Collections 需要一些时间来将列表转换为数组。
16.在将 Collection 作为参数传递给函数时,我们如何确保函数无法修改它?
我们可以在将它作为参数传递之前使用方法创建一个只读集合
Collections.unmodifiableCollection(Collection c),这将确保任何更改集合的操作都会抛出
UnsupportedOperationException.
17.我们如何从给定的集合创建一个同步的集合?
我们可以
Collections.synchronizedCollection(Collection c)用来获取由指定集合支持的同步(线程安全)集合。
18.Collections Framework 中实现的常用算法有哪些?
Java Collections Framework 提供了排序和搜索等常用的算法实现。Collections 类包含这些方法实现。这些算法中的大多数都适用于 List,但其中一些适用于所有类型的集合。其中一些是排序、搜索、改组、最小值-最大值。
19.什么是大 O 符号?举几个例子?
Big-O 表示法根据数据结构中元素的数量来描述算法的性能。由于 Collection 类实际上是数据结构,我们通常倾向于使用 Big-O 表示法来根据时间、内存和性能来选择要使用的集合实现。示例 1:ArrayListget(index i)是一个常量时间操作,不依赖于数量列表中的元素。所以它在 Big-O 表示法中的性能是 O(1)。
示例 2:对数组或列表的线性搜索性能是 O(n),因为我们需要搜索整个元素列表才能找到元素。
20.与 Java Collections Framework 相关的最佳实践是什么?
根据需要选择正确的集合类型,例如如果大小是固定的,我们可能希望使用 Array 而不是 ArrayList。如果我们必须按插入顺序遍历 Map,我们需要使用 TreeMap。如果我们不想重复,我们应该使用 Set。一些集合类允许指定初始容量,因此如果我们估计要存储的元素数量,我们可以使用它来避免重新散列或调整大小。根据接口而不是实现来编写程序,它允许我们在以后轻松地更改实现。始终使用泛型来确保类型安全,并在运行时避免 ClassCastException。使用 JDK 提供的不可变类作为 Map 中的键,以避免为我们的自定义类实现 hashCode() 和 equals()。尽可能将 Collections 实用程序类用于算法或获取只读、同步或空集合,而不是编写自己的实现。它将增强代码重用,具有更高的稳定性和低可维护性。
总结:
好了,40道我已经发完了。我会继续添加更多关于 java 集合框架的问题,如果你觉得它有用,请帮帮忙动下你的手手帮忙点赞加关注,博主会持续更新Java的问题与解说,如需直接获取更多的请关注私信UP主,谢谢
#面试##内推##春招##实习##笔试题目##面经##求面经##Java#