编程语言
首页 > 编程语言> > Java面试(七)

Java面试(七)

作者:互联网

HashMap工作原理是什么

Java 中最常用的两种结构是数组模拟指针(引用),几乎所有的数据结构都可以利用这两种来组合实现,HashMap 也是如此。实际上 HashMap 是一个链表散列
HashMap 是基于 hashing 的原理。

HashMap图解

  1. 使用 #put(key, value) 方法来存储对象到 HashMap 中,使用 get(key) 方法从 HashMap
    中获取对象。
  2. 给 #put(key, value) 方法传递键和值时,我们先对键调用 #hashCode() 方法,返回的 hashCode 用于找到 bucket(桶)位置来储存 Entry 对象。

当两个对象的 hashCode 相同会发生什么?

  1. 因为 hashcode 相同,所以它们的 bucket 位置相同,“碰撞”会发生。
  2. 因为 HashMap 使用链表存储对象,这个 Entry(包含有键值对的 Map.Entry 对象)会存储在链表中。

hashCode 和 equals 方法有何重要性?

HashMap 使用 key 对象的 #hashCode() 和 #equals(Object obj) 方法去决定 key-value 对的索引。当我们试着从 HashMap 中获取值的时候,这些方法也会被用到。

同样的,所有不允许存储重复数据的集合类都使用 #hashCode() 和 #equals(Object obj) 去查找重复,所以正确实现它们非常重要。#hashCode() 和 #equals(Object obj) 方法的实现,应该遵循以下规则:

HashMap 默认容量是多少?

默认容量都是 16 ,负载因子是 0.75 。就是当 HashMap 填充了 75% 的 busket 是就会扩容,最小的可能性是(16 * 0.75 = 12),一般为原内存的 2 倍。

有哪些顺序的 HashMap 实现类?

我们能否使用任何类作为 Map 的 key?

我们可以使用任何类作为 Map 的 key ,然而在使用它们之前,需要考虑以下几点:

  1. 如果类重写了 equals 方法,它也应该重写 hashcode 方法。

  2. 类的所有实例需要遵循与 equals 和 hashcode 相关的规则。

  3. 如果一个类没有使用 equals ,你不应该在 hashcode 中使用它。

  4. 用户自定义 key 类的最佳实践是使之为不可变的,这样,hashcode 值可以被缓存起来,拥有更好的性能。不可变的类也可以确保hashcode 和 equals 在未来不会改变,这样就会解决与可变相关的问题了。

     //传递给MyKey的name参数被用于equals()和hashCode()中
     MyKey key = new MyKey('Pankaj'); //assume hashCode=1234
     myHashMap.put(key, 'Value');
     // 以下的代码会改变key的hashCode()和equals()值
     key.setName('Amit'); //assume new hashCode=7890
     //下面会返回null,因为HashMap会尝试查找存储同样索引的key,而key已被改变了,匹配失败,返回null
     myHashMap.get(new MyKey('Pankaj'));
    

这就是为何 StringInteger 被作为 HashMap 的 key 大量使用。

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

为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀,每个链表/红黑树长度大致相同。这个实现就是把数据存到哪个链表/红黑树中的算法。

这个算法应该如何设计呢?我们首先可能会想到采用 % 取余的操作来实现。但是,重点来了:

这就解释了 HashMap 的长度为什么是 2 的幂次方。

HashSet 的工作原理是什么?

HashSet 是构建在 HashMap 之上的 Set hashing 实现类。让我们直接撸下源码,代码如下:

// HashSet.java

private transient HashMap<E,Object> map;

private static final Object PRESENT = new Object();

HashSet 如何检查重复?

当你把对象加入 HashSet 时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比较。

EnumSet 是什么?

java.util.EnumSet ,是使用枚举类型的集合实现。

Java Priority Queue 是什么?

PriorityQueue(优先级队列) 是一个基于优先级堆的无界队列,它的元素都以他们的自然顺序有序排列。

poll 方法和 remove 方法的区别?

poll 和 remove 方法,都是从队列中取出一个元素,差别在于:

LinkedHashMap 和 PriorityQueue 的区别是什么?

标签:Java,HashMap,equals,EnumSet,hashCode,面试,key,hashcode
来源: https://blog.csdn.net/liu726301387/article/details/98477567