1、背会集合的集成结构图
java.util.Collection;
![](https://i-blog.csdnimg.cn/blog_migrate/4a87df7c357449addec0aa10a6f23749.png)
![](https://i-blog.csdnimg.cn/blog_migrate/762e128bd3268592ef1702f301a385f3.png)
java.util.Map;
![](https://i-blog.csdnimg.cn/blog_migrate/9c5f58874edf116be64bd6f33c3ee15a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2a256b52a1ad4aa63ddfaa5863733936.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ce0454991ab26717adb28fda4e5c35ec.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1c843c9d3b0f2a93854b514f48e692c0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6ab79f54cb517cb980dd093bd8f2d4e3.png)
2、map中的常用方法:
![](https://i-blog.csdnimg.cn/blog_migrate/bf82e127600b982223a4b3e6b8a4e993.png)
![](https://i-blog.csdnimg.cn/blog_migrate/abd4ddccfe3d0c48e12cded8f387e98c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/50198d43f6192bd19fc84390158c7ebe.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bf2ee439b86be56fd0368ac807ebf208.png)
调用这些方法:
![](https://i-blog.csdnimg.cn/blog_migrate/728f2ddcb6e8f5f6412859a3e9f80f10.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4ba0805c7c7c313b398c6664e16fa2a2.png)
3、map集合的遍历:
第一种方式用keyset()方法将key全部取出来,然后利用get()方法将value取出来。
![](https://i-blog.csdnimg.cn/blog_migrate/12d13d18fbd0f8269d5e29f73e113f8f.png)
第二种方法:利用set<Map.Entry<k,y>>entrySet()来获取键值对,然后通过getkey()方法获得key值。通过getValue()方法获得value值。这里的Map.Entry<k,y>是一种内部类,也就是说可以看做一种数据类型,而k,y分别填写key和value的类型。这种方·比第一种方式效率要高的多,因为这种方式的一次性取出了key值和value值。
![](https://i-blog.csdnimg.cn/blog_migrate/a878469163b7f6127b51e5a28a66c671.png)
set<Map.Entry<k,y>>entrySet()的底层内存图
![](https://i-blog.csdnimg.cn/blog_migrate/f461d5f1f0c441b2c050a1870869fa71.png)
4、hashmap的概念及操作
![](https://i-blog.csdnimg.cn/blog_migrate/d7f360486cfe559eb0d419f6382ca6f0.png)
哈希表数据结构图
![](https://i-blog.csdnimg.cn/blog_migrate/cc23551a7914ef0495871f3c695a3f98.png)
5、hashmap的put和get操作以及哈希表的原理:
![](https://i-blog.csdnimg.cn/blog_migrate/ef9dd86b759e9ed03f4c4a7b6d8f766b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/359192da6c6f404ca4ec5d054b7be6d7.png)
hash表的内存原理图以及put()和get()方法的操作过程。
![](https://i-blog.csdnimg.cn/blog_migrate/6fa090685a74072b53c1e972ac2ed34e.png)
需要注意的地方:
第一点:
![](https://i-blog.csdnimg.cn/blog_migrate/bba9c50156ae606f7105079814fca28a.png)
第二点:
看一个例子,来体会hashcode()方法不重写带来的问题:
![](https://i-blog.csdnimg.cn/blog_migrate/dde7be334056a6656312552a504eb6a7.png)
图片中放入的两个对象是相同的,也就是说最后的打印结果是2,按照hashmap的特性而言,hashmap是无序不可重复的。之所以出现这个情况,是因为hashcode没有重写,这是因为hashcode()函数不知道按照什么条件来判断两个对象是否相等。也就是说hashcode()判断相等不是只有equals()判断完就可以了,还要hashcode()函数里也判断一下是不是两个对象相等。因此hashcode()不重写会导致返回的两个对象的hashcode不一样,所以被同时放入了hashmap当中。因此这里我们得出了一个结论,hashcode不重写会导致存入重复的值。
![](https://i-blog.csdnimg.cn/blog_migrate/4f04b9d9ab35f30369a96a429d4e2b26.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1bd3fc0ef13e85f4db0c6a5ee2fde99f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4e22ecbeaaf1df0ad91d7db93cf2d07d.png)
hashmap在jdk8之后做了改进,如果哈希表单向链表中元素超过8个,单向链表这种数据结构会变成红黑树数据结构。当红黑树上的节点数量小于6时,会重新把红黑树变成单向链表数据结构。注意hashmap的数组初始化容量是16,默认加载因子是0.75,也就是说当数组中数值达到容量的0.75时,数组会进行扩容,扩容之后的容量是原容量的二倍。
注意:hashmap中key和value可以为null但是只能由一个null值,因为hashmap时不可重复的。
![](https://i-blog.csdnimg.cn/blog_migrate/7d0fcf9b2fdcc0d8d4ca744ceab063ca.png)
注意:hashtable中key和value不可以为null,如果为空会报错。
![](https://i-blog.csdnimg.cn/blog_migrate/851456dbd01c21b59b79e1f31996fa21.png)
5、hashtable的定义和特性(技术比较老了解一下)
hashtable中key和value不允许为null
hashtable集合初始化容量为11
默认加载扩容因子为原容量*2+1
hashtable和hashmap一样底层也是哈希表数据结构
![](https://i-blog.csdnimg.cn/blog_migrate/dce41a740f767221e28b6bf8eb141431.png)
6、hashtable的子类:properties类
需要掌握的是properties的setproperty()(实际上调用的hashtable的put方法)和getproperty()相关方法即可
![](https://i-blog.csdnimg.cn/blog_migrate/f77baf700e3dc71fbb4aed6153234afe.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fc610f2827a5797d184ff747d2c4d72b.png)
7、treeset放一个自定义的类型对象。
首先看一个问题,
![](https://i-blog.csdnimg.cn/blog_migrate/8dade9b8a90344f86652a381ebbf0d6f.png)
解决问题的方法:
重写hashset中的compare()函数
![](https://i-blog.csdnimg.cn/blog_migrate/b0b9ddab762ad659d3db86857c7c7f17.png)
![](https://i-blog.csdnimg.cn/blog_migrate/01fe4c466dbc603671b45b0922352b12.png)
8、二叉树
图中树结构就是自平衡二叉树:存放时先比较,小的放左边,大的放右边,取得时候按照中序遍历的方式取,也就是左根右。
![](https://i-blog.csdnimg.cn/blog_migrate/5bba963e82e533436d7a7fa6415f06c3.png)
9、通过重写比较器来实现,对自己新建的类的对象放入treeset中时的排序:
最终的结论是:放到TreeSet或者TreeMap集合key部分的元素要想做到排序,包括两种方式:
![](https://i-blog.csdnimg.cn/blog_migrate/8ae8511a5903fac8d41396d65fa31957.png)
与重写comparable接口不同的是,重写comparator是实现java.util.comparator接口,重写comparable是实现java.lang.comparable接口。
以下方法是重写比较器的方式:
![](https://i-blog.csdnimg.cn/blog_migrate/f49afb735abe9671ad7226754aebaec6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9213f8b9256f4360cb97d95a2068d484.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b123d4697c7e4683749e8fdd7fa54603.png)
比较器也可以用匿名内部类的形式实现
![](https://i-blog.csdnimg.cn/blog_migrate/6d94c224e7b1eb4d4de3bb76a9d7ebdd.png)