Java集合框架读书笔记(四)

Java的TreeMap实现了SortedMap接口,会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过本身的自然顺序,也可以通过构造时的比较器(Comparator)。
底层是通过红黑树来实现的。并且也是非同步的。

红黑树是一种近似平衡的二叉查找树,它能确保任何一个节点的左右子树的高度差不会超过二者中较低的那个的一倍。红黑树是满足如下条件的二叉查找树:
1.每个节点要么是红色,要么是黑色。
2.根节点必须是黑色。
3.红色节点不能连续(红色节点的孩子和父亲都不能是红色)。
4.对于每个节点,从该节点至null(树尾端)的任何路径,都含有相同个数的黑色节点。

当查找树的结构发生改变时,红黑树的条件可能被破坏,需要通过调整重新满足红黑树的条件。
左旋
在这里插入图片描述
右旋
在这里插入图片描述

get()方法
get(Object key)方法根据指定的key值返回对应的value,该方法调用了getEntry(Object key)。核心思路是根据key的自然顺序或者比较器顺序对二叉树进行查找,直到满足k.compareTo(p.key) == 0 的entry。
在这里插入图片描述
在这里插入图片描述

put()
该方法首先会对map做一次查找,看是否包含该元素,如果已经包含则直接返回。如果没有找到则会在红黑树中插入新的entry。如果破坏了红黑树约束,还要进行调整。

remove()
作用是删除key值对应的entry,该方法先通过上文中提到的getEntry方法找到key对应的entry,然后调用deleteEntry删除对应的entry。如果破坏了结构,也需要进行调整。

TreeSet是对TreeMap的简单包装,所有TreeSet的方法都会转换成合适TreeMap的方法。

HashSet和HashMap
二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装。HashMap实现了Map接口,允许放入null元素。除了为实现同步外,其余根HashTable大致相同。但是该容器不保证元素顺序,根据需要对该容器可能会对元素进行重新哈希,顺序会被打乱。

Java HashMap采用的是冲突链表方式。
在这里插入图片描述
有两个参数可以影响HashMap的性能:初始容量和负载系数,初始容量制定了初始table的大小,负载系数用来指定自动扩容的临界值。
将对象放入到HashMap或者HashSet中时,有两个方法需要特别关心:hashCode()和equals(),hashCode()决定了对象会被放到哪个bucket()里,当多个对象哈希值冲突时,equals()方法决定了这些对象是否是同一个对象。

get()
算法思想是首先通过hash()函数得到对应的bucket的下标,然后依次遍历冲突链表,通过key.equals(k)方法判断是否要找的那个entry。
在这里插入图片描述
put()
put方法是将指定的key,value对添加到map里,该方法首先会对map做一次查找,看看是否包含该元素,如果已经包含则直接返回。如果没有找到会在链表头部直接插入。
在这里插入图片描述
remove()
删除key对应的entry。
在这里插入图片描述

HashSet是对HashMap的简单封装。

LinkedHashSet 和LinkedHashMap
LinkedHashMap可以看做是linked list增强的HashMap。
LinkedHashMap是HashMap的直接子类,二者唯一的区别是LinkedHashMap在HashMap的基础上,采用双向链表的形式将所有entry连接了起来,这样是为了保证元素迭代的顺序和插入顺序相同。
在这里插入图片描述
迭代LinkedHashMap时不需要像HashMap那样遍历整个table,而只需要直接遍历header指向的双向链表即可。
LinkedHashMap是有序但非同步的。

get()
根据指定的key返回对应的value,和HashMap的方法的流程几乎一样。
put()
put方法执行时不仅要考虑插入冲突链表,同时要维护双向链表的指针。
在这里插入图片描述

remove()
这个方法也同样要维护冲突链表和双向链表。

猜你喜欢

转载自blog.csdn.net/bianhao92115/article/details/86528501