#美团#Java面试题:集合高频要点问题你能答上来吗?( 二 )


integers.forEach(System.out::println); // 1 2 5 4 5

  • 很显然我们是可以修改 list集合的 可以使用set方法
  • 但是当我们尝试去使用add() 方法时会抛出 java.lang.UnsupportedOperationException 的异常 不支持操作的异常
  • 当我们使用 java9+时 可以使用 List.of()方法 他就是彻彻底底的不可修改的
7. 怎么将一个不安全数组换成安全数组?
使用 Collections这个工具类
List<Integer> integers1 = Collections.synchronizedList(integers);
java5+ 变成 CopyOnWriteArrayList
CopyOnWriteArrayList<Integer> integers2 = (CopyOnWriteArrayList<Integer>) integers;
. java9+ 使用 List.of() 变成只读对象
8. Collections 工具类?
. 创建一个安全的空集合防止NullPointerException异常
List<String> list = Collections.<String>emptyList();
. 拷贝集合
Collections.addAll(list 23 4 5 6);
. 构建一个安全的集合
List<Integer> safeList = Collections.synchronizedList(list);
. 二分查找
Collections.binarySearch(list 2);
.翻转数组
Collections.reverse(list);
Set
1. HashSet、TreeSet 和 LinkedHashSet 三种类型什么时候使用它们?
如你的需求是要一个能快速访问的 Set , 那么就要用 HashSet , HashSet 底层是 HashMap 实现的 , 其中的元素没有按顺序排列 。
如果你要一个可排序 Set , 那么你应该用 TreeSet , TreeSet 的底层实现是 TreeMap 。
如果你要记录下插入时的顺序时 , 你应该使用 LinedHashSet 。
Set 集合中不能包含重复的元素 , 每个元素必须是唯一的 , 你只要将元素加入 set 中 , 重复的元素会自动移除 。 所以可以去重 , 很多情况下都需要使用(但是去重方式不同) 。
LinkedHashSet 正好介于 HashSet 和 TreeSet 之间 , 它也是一个基于 HashMap 和双向链表的集合 , 但它同时维护了一个双链表来记录插入的顺序 , 基本方法的复杂度为 O(1) 。
三者都是线程不安全的 , 需要使用 Collections.synchronizedSet(new HashSet(…)); 。
2. HashSet 和 LinkedHashSet 判定元素重复的原则是相同的?
会先去执行 hashCode() 方法 , 判断是否重复 。 如果 hashCode() 返回值相同 , 就会去判断 equals 方法 。 如果 equals() 方法还是相同 , 那么就认为重复 。
3. TreeSet 判断元素重复原则?
TreeSet 的元素必须是实现了 java.lang.Comparable<T> 接口 , 所以他是根据此个接口的方法 compareTo 方法进行判断重复的 , 当返回值一样的时认定重复 。
4. 怎么实现一个线程安全的 hashset?
我们看源码会发现他里面有一个 HashMap(用 transient 关键字标记的成员变量不参与序列化过程 , 因为 HashMap 已经实现 Serializable) 。
5. CopyOnWriteArraySet 的实现?
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
很显然翻源码我们发现他实现了 CopyOnWriteArrayList() 。
Map
1. Hashtable 特点?
Hashtable 和 ConcurrentHashMap 以及 ConcurrentSkipListMap 以及 TreeMap 不允许 key 和 value 值为空 , 但是 HashMap 可以 key 和 value 值都可以为空 。
Hashtable 的方法都加了 Synchronized 关键字修饰 , 所以线程安全 。
它是数组+链表的实现 。
2. ConcurrentHashMap 问题?
取消 segments 字段 , 直接采用 transient volatile HashEntry<KV>[
table 保存数据 。


推荐阅读