从源代码来理解HashMap和HashSet
HashMap类
HashMap 内有一个table数组存放<K,V>,用keywordtransient,则说明HashMap的table数组值是存放在内存中,不作为序列化数据保存。
put函数
假设key==null。
注意:table是一个数组。而这个数组下每一个元素的以下事实上是个链表。都是通过hash(key)得到同样k位置(table[k])
空值统一放在table的0位置。先遍历table[0]下的全部元素,假设插入的key==null。则将原本Entry的value替换,返回之前的值(oldValue)。
假设key!=null
依据key求出hash值。然后再让hash与table.length做相与运算,求得i在0-table.length-1中。然后依据i的位置,遍历table[i]下的链表,假设其下的元素key值与插入的key值相等的话则把原来key所相应的value值改成插入的value值,返回oldValue,假设旗下的元素key值遍历循环都没有与之相等。则加入一个Entry(addEntry(hash,key,value,i)).
在table[bucketIndex]中存放新的Entry对象,对象的next值存放原来的table[bucketIndex]对象。链表长度添加。
remove函数
假设key==null,hash为0(固定的。前面有说),否则就依据key求得hash值,然后相与运算得到i,prev为table[i]对象,遍历table[i]下的链表,推断假设key相等的话。假设它是首(也就是说table[i]------(pre == v)的情况),则让table[i]=next,假设它不是首else prev.next = next,直接连接下个元素。跳过中间元素。相当于删除(Java的gc机制,假设没有对象引用它的话。则会被回收掉),返回删除掉的e。
循环结束后假设找不到找不到则返回null。
HashSet
HashSet本质是用HashMap来实现功能的。
PRESENT是随便new出来的Object。是一个final值,也就是说add加进去的每一个Value都是一样的。
put函数又调用到前面所讲的HashMap里的put内,都是一样的
假设成功加入成功(addEntry后)则返回null,则add函数返回true。表示HashSet加入元素成功。
remove函数
本质也是调用HashMap的remove函数,
假设HashMap中有这个key的话则返回这个key相应的value,假设没有则返回null.