继承实现
1 | public class HashMap<K,V> extends AbstractMap<K,V> |
AbstractMap
1 | public abstract class AbstractMap<K,V> implements Map<K,V>{...} |
AbstractMap 抽象类实现了一些 Map 接口的简单且通用的方法
Map
1 | public interface Map<K,V>{...} |
定义键值对结构对象的通用操作,通过使用模板方式实现类或实例化时候可以动态自定义键(K)和值(V)类型
Cloneable
1 | public interface Cloneable { |
Cloneable 是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用 Object.clone() 方法。如果没有 implements Cloneable 的类调用 Object.clone() 方法就会抛出 CloneNotSupportedException。
Serializable
1 | public interface Serializable { |
和 Cloneable 一样都是标记型接口,一个类只有实现了 Serializable 接口,它的对象才能被序列化
变量属性
1 | // 持久化版本ID,用于 Serializable 的序列化。 |
static
用来修饰变量表示类变量,一个类中某个属性被static所修饰,那么就可以通过”类名.属性名”来访问
final
一旦定义了 final 变量并在首次为其显示初始化后,final修饰的变量值不可被改变。对于基础类型变量,值不能改变;对于引用类型变量,引用不能指向其他对象。
transient
- 只能修饰变量。
- 局部变量不能被 transient 关键字修饰,静态变量不管是否被 transient 修饰,均不能被序列化。
- 一旦变量被 transient 修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
HashMap 实现 Serializable 接口,搭配 transient 可以选择性的序列化变量,比如 entrySet 和 threshold 之类的就可以不用了。
内部类
Node类
1 | static class Node<K,V> implements Map.Entry<K,V> { |
HashMap 的数据元节点,该类实现 Map.Entry 类,节点有 键-值 属性,Next 节点可以实现链式结构。
- Node.hashCode 方法
Objects.hashCode 方法如下:
1 | public static int hashCode(Object o) { |
Object.hashCode 方法如下:
1 | public native int hashCode(); |
Object.hashCode 方法为 native 方法,通常是通过 C/C++ 本地方法库实现的,思路一般是将对象的内部地址转换成整数来实现。
用位运算生成新的 hashCode,其一是为了程序效率更快;其二用 ^
异或运算,而不用与运算和或运算,是因为对象内部地址很紧凑,与和或运算很容易产生重复值,而异或运算有更好的散列性。
- Node.setValue 方法
设置新值,返回旧值。这种编程思维,使得数据具有一次记忆反馈的特性,是一种可以参考的思想。
- Node.equals 方法
重写该方法是扩展 equals 的含义,一般情况,对于自定义类对象有比较操作,都会重定义 equals 概念。
比如,判断两位公民账号是否为同一人,其身份证号一样即为同一人。
TreeNode 类
1 | /** |
KeySet 类
1 | final class KeySet extends AbstractSet<K> { |
该类继承自 AbstractSet,而AbstractSet 继承自 AbstractCollection,并且实现了 Set 接口。
1 | public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...} |