List重复的定义是equels
二叉树是大小
1 MAP
1.1 特点
1.Map接口是Map集合体系的顶级接口
2.Map储存的数据是K-V数据,(K-v数据具有自我描述性)
3.Map的有些子实现K是有序的,有些K是无序的(Hash无序tree有序)
4.Map不允许存储重复的元素(注意:重复的定义)是key
5.Map的有些子实现允许存储null,有些不允许( )
注:有序,null,重复等都是指key,我们不关心value
API
V put(k,v):添加
void putAll():添加所有
v remove(key):根据key删除这个键值对
v get(objec):根据key获取value
boolean containsValue()
boolean containsKey()
视图方法
Set<k> keySet():返回K的集合
Collection<V> values():返回value集合
set<Map.Entry<K,V>>,entrySet()>:返回键值对集合
2 HashMap
结构:数组+链表+红黑树
key经过计算得到位置,然后比对key的值,一样就替换,不一样就链上
2.1特点
1.HashMap是Map接口的一个具体子实现
2.HashMap它的结构是数组+链表+红黑树
3.数组默认的初始化容量16,扩容机制扩为原来的二倍,默认加载因子:0.75
4.存储的数据是无序的(通过key计算出的数组下标是不确定的)
5.允许存储null键与null值
6.不允许存储重复的key值
7.线程不安全
8.加载因子是控制该HashMap扩容的阈值,
存储元素数量>加载因子*数组长度
eg:数组长度16,加载因子:0.75,只能存储12个元素(指的是12个entry数量而不是12个下标位置)
9.如果我们给定HashMap一个初始 长度,--构造器赋值(与deque不同先减一了,所以是得到是大于等于给定值的最小的2次幂)
如图:每次初始化都是n的右移,也就是给定值的最小二次幂;
10.key-value数据是如何存储的?
把key取出,根据k计算hash值:
根据hash值(这里做一个新旧值的异或操作)与数组长度取模,得到下标
如果下标位置没用存储任何元素,那么就将kv数据创建一个节点(hash,K,V,next)进行存储
如果经过计算的下标位置没又任何元素,那么就new一个节点
如果这个位置已经存储了元素,先判断(先hash再equals)key是否重复
如果这时候是一样的key就替换值如果不一样:
1.此时是链表:(并且不满足树化操作)此时一个一个对象比较,1.8之后是尾插用next指向
2.此时是红黑树,肮脏红黑树的compareTo方法插入(红黑树插入5种情况)
3.链表大于8达到9后会进行树化操作(此时也应该满足数组长度大于64,否则会先扩增数组,扩增数组之后数组长度的变化会导致hash值计算得出的最后角标为x与x+旧length)
)
11.hash值的计算
Hash = (h=key.hashCode())^(h>>>16)
移动16位的原因:我们希望这个hash算法能够尽可能的充分散列,因此,让hashcode的高位也参与到运算之中,下标的位置将取决于低位+高位+数组长度;
12.HashMap中key值重复的依据与条件是:
哈希值没重写的时候看地址值,重写看key值
13.如果新储存的KV储存已经存在或者重复,那么新的V回覆盖旧的V,旧的value值会作为返回值返回;
经过计算得到(Key-->hash(先异或)-->再取模(位与)得到下标),此时到一个下标上,就回计算
key的hash值是否一样,在hash一样的基础上,key是否相等,相equals;
这个哈希值首先进行右移16位再与旧值进行异或操作,保留高位与地位的信息,减少碰撞
key的哈希值与length长度-1的值做与运算(和对长度取模是一样的),找到角标(位运算取模速度更快)
14.如果一份kv值依据存储在hashmap中,尽量不通过引用修改这个kv值,因为有可能再也访问不到了。(因为角标是根据k计算得出的)
在重写hashcore的之后zs1与zs2 equals了,就变成相同元素
,只会存储一个;zs1的key,与zs2的值(第二次添加覆盖了zs1);
不推荐这种做法,
因为此时通过key(aaa与18)值计算出的位置,在经过equals之后不会等于原来(zs,18)的值,就删不掉了,而就算通过zs18找到这个位置,在equals过后也会发现不匹配 无法删除
注:上图是否重新散列,因为数组长度变化了,进行取模(也就是位与操作的时候得到的高位值可能会变化,如果是1就会到x+lenth的位置上去)
添加过程: 哈希值移动16位(>>>16)异或旧值,之后取模数组长度(这也是为什么扩容为两倍的原因,以为取模是用位运算的方式得到的,这样算出的更快)得到下标;
在扩容之后,根据哈希值的高位来决定在原来的位置还是在原来位置+旧的长度;
( 依然>>>16异或之后取模(位与),此时决定位的只有高位的值 )
--
15,在数据的不断存储过程之中,有可能导致key经过计算之后得到同一个下标而这些key不重复,也就是意味着这些kv都会存储到这个位置,这会导致数组链表的产生,如果链表过长(效率降低的时候)需要转化为红黑树
链表多长转化为红黑树?链表长度超过8达到9的时候
(这是因为泊松分布,在8之前链表的效率是优于红黑树的)
1.有重复位置的元素,p不为null,继续往下,先判断如果这个节点是树节点,按照树结构查找,否则按照链表方式查找
链表方式
泊松分布,当长度超过8的时候链表的查找效率此时低于红黑树,所以转化为红黑树
16.当链表长度大于8达到9的时候:
此时如果底层数组长度小于64会先扩容而非转化为红黑树(扩容也会重新分布,参考下文扩容的时候高位决定了新的位置)
17.如果数组扩容,那么一个原本在x位置的元素要重新散列,就两个位置可以选择,x,以及旧长度+x位置,取决于高位(是根据hash值重新算)
18.红黑树转化为链表:
1.当不断删除的元素(并且删除的是红黑树上的元素->导致红黑树上的节点变少->转回链表
2.扩容(扩容->一个红河偶数,拆分成两部分->有可能需要转化回链表;)
删除:判断红黑树的根节点,以及跟节点的左节点,右节点,以及左节点的左节点,如果这四个节点有任意一个是null,那么就会由红黑树转化为链表()
扩容:当紧邻的高位为0
此时就会还在原来的位置
扩容的时候红黑树散列无论是新位置还是旧位置,只要散列的节点数是小于等于6的,那么就要留红黑树转化为链表
(在红黑树上用hash值比较大小)
思考:扩容的时候会重新散列//红黑树的遍历依靠next//删除过程(找到值,替换为左树最大和右树最小)//
为什么是6,如果是7刚转化为链表,此时添加之后又反复转化形态;用6概率相对降低
2.2 总结一个kv添加的过程
以上
树的扩容:散列之后数组长度是2的幂值,只取决于高位的值
2.3构造方法
Hash算法不是加密算法
加密--->(x)解密 加密是为了解密,而Hash为了散列
MD4、MD5、SHA-1、SHA-2
3.LinkedHashMap
3.1特点
1.LinkedHashMap是HashMap的子类
2.LinkedHashMap它的底层结构复用了HashMap的底层而机构
它的特点基本上于HashMap一致
3.LinkedHashMap在HashMap基础上额外维护了一个双向链表,以保证迭代顺序
:尾元素双向指向下一个元素
4.HashMap是有序的(HashMap按下标进行遍历,Linked按链表顺序)
同样不允许key重复
3.2
4.TreeMap
1.TreeMap是map接口的子实现
2.TreeMap是一个黑红树
3.TreeMap存储元素大小有序(key)
4.TreeMap不允许存储重复的key值(红黑树,大小相关compareTo)所以填入的值一定是可以进行比较的;
5.TreeMap的key不允许是null(null不能比较因为)
6.TreeMap是线程不安全的
注意:与hashmap一致,如果数据已经存储通过类的点修改属性,可能会导致这个节点找不到无法删除
注意使用的类要实现排序方法
API(TreeMap)
boolean containskey//value
Map.Entry ceilingEntry 返回大于等于给定key的最小的键值对
Map.Entry floorKey:返回小于等于给定key的KV
Map.Entry firstEntry:获得最小键值对 K firstKey():获得最小的key
K firstKey():获得最大的
Map.Entry higherEntry:大于给定key的
(对所有给定的key值的大于或者严格大于,小于或者严格小于的值的查找,删除)
map的切割
headMap(头切到x) // subMap // tailMap(从x切割到尾部)
5.Hashtable
5.1.1Hashtable是Map子实现(Map是1.2 Hashtable是1.0出现了))
2.Hashtable底层是数组+链表(没有红黑树结构)
3.数组默认初始容量(11)与扩容机制(扩容为原来的2倍加一)
4.不允许存储null值,null值
(HashMap是可以的并且null值为0,排在第一个,Hashtable是)HashMap在put的时候会调用hash()方法来计算key的hashcode值而Hashtable执行int hash = key.hashCode()会空指针
5.计算hash值的方式key.hashcode(直接计算和取模,没有位运算))
6.线程安全
5.2Properties
(Hashtable的子类)
Xml
Properties