Java集合常见面试题总结

115 阅读3分钟

Java集合常见面试题总结(上)

java集合,也叫容器。

  1. Collection接口。
  2. Map接口

image.png

如何选用集合?

我们主要根据集合的特点来选择合适的集合。比如:

  • 我们需要根据键值获取到元素值时就选用 Map 接口下的集合,需要排序时选择 TreeMap,不需要排序时就选择 HashMap,需要保证线程安全就选用 ConcurrentHashMap
  • 我们只需要存放元素值时,就选择实现Collection 接口的集合,需要保证元素唯一时选择实现 Set 接口的集合比如 TreeSetHashSet,不需要就选择实现 List 接口的比如 ArrayListLinkedList,然后再根据实现这些接口的集合的特点来选用。

ArrayList 与 LinkedList 区别?

  • 是否保证线程安全:  ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;
    • 是否保证线程安全:  ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;
  • 内存空间占用: ArrayList 的空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。

不推荐使用LinkedList, 因为可以用ArrayList代替并且性能更好。

PriorityQueue 在面试中可能更多的会出现在手撕算法的时候,典型例题包括堆排序、求第 K 大的数、带权图的遍历等,所以需要会熟练使用才行。

HashMap 的长度为什么是 2 的幂次方?

说法1: 当你使用 put() 方法向 HashMap 中添加元素时,Java会根据键的哈希码来确定该元素将被放置在数组的哪个位置。数组的索引通过以下操作计算得到:hash & (table.length - 1)

这里使用了位运算中的与运算(&),而使用 (table.length - 1) 是因为在使用位与运算时,要求用作与运算的数是2的幂次方,这样可以确保结果的范围在数组的有效索引范围内,即为 0table.length - 1

如果 table.length 是2的幂次方,比如 16 (0b10000)table.length - 1 则是 15 (0b01111),这样就能够充分利用哈希码的低位信息,让它在数组中的分布更均匀。这是因为 (hash & 15) 的结果总是 015 之间的数,这样会更好地分散到数组中的不同位置,减少了碰撞的可能性。

说法2: 散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“ (n - 1) & hash”。(n 代表数组长度)。这也就解释了 HashMap 的长度为什么是 2 的幂次方。

我们首先可能会想到采用%取余的操作来实现。但是,重点来了: “取余(%)操作中如果除数是 2 的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是 2 的 n 次方;)。” 并且 采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是 2 的幂次方。

HashMap 的 7 种遍历方式与性能分析

HashMap 的 7 种遍历方式与性能分析!「修正篇」 (qq.com)