黑马程序员----十八-Map集合

来源:互联网 发布:读书笔记本软件 编辑:程序博客网 时间:2024/05/20 05:07

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

今天开始学Map集合

一.Map集合
双列集合,K-Key,V-Value,键都是不能重复的,每个键映射一个值.
Map和Collection的区别
1.双列,单列
2.Map的键唯一,Collection的子体系Set唯一
3.Map的数据结构针对键有效,跟值无关,Collection的数据结构针对元素有效.

问:到底是Map底层依赖Set还是Set底层依赖Map呢?
源代码中发现Map的put方法中没有Set支持,而Set的add方法中是由Map的put方法支持的,也就是说Set依赖Map.所以Set是put时,每个值都用一个private static final Object PRESENT=new Object();这样一个常量对象来隐藏.

为什么要用双列支持单列呢?
画图解释:双列支持单列的时候,只要用一套哈希算法就可以了,隐藏一列比较容易,如果是用两个单列来构造双列,那就比较麻烦

二.Map集合的功能概述
1.添加
put的时候,如果这个键的位置是null,那么添加时,就会返回null,如果这个键的位置已经有了一个值,那么就会覆盖这个值,并且返回原来那个值.
2.删除
remove时,会返回删除的这个键对应的值.
3.判断
boolean containsKey()
boolean containsValue()
boolean isEmpty()
4.获取
get()通过键获取值
values()获取所有值Collection
keyset()获取所有键Set
entrySet()所有键值对EntrySet


三.Map遍历键找值
Map没有迭代器,所以不能直接迭代,那么双列集合如何迭代呢?
先用keySet获取所有键,再通过遍历这个Set和get方法来获取所有值.

四.Map集合的键值对
通过entrySet方法获取所有键值对,再通过遍历这个Set和getKey,getValue方法来获取所有值和所有键.

Map.Entry到底是什么呢?
Entry就是Map中的一个内部接口,想要实现Entry,必须先找到Map,所以是Map.Entry.

五.键值对对象和源码分析
如果用Map.Entry的话就是父类引用指向子类对象,如果直接用Entry就是直接获取子类对象.源码中写了一个Entry实现了Map.Entry接口.

发现自定义对象没有覆盖,因为没有重写hashCode和equals方法,跟Set是一个道理.

为什么直接输出HashMap是键=值的格式?
因为Map中肯定重写了toString方法.
源码中在AbstractMap中找到toString方法.

六.LinkedHashMap
底层是链表实现的,所以是有序的.

七.TreeMap
和TreeSet一样,也要给定排序方法.
1.排序的类来实现Comparable,重写compareTo
2.新建类来来实现Comparator,重写compare


八.统计字符串中每个字符出现的次数

九.集合嵌套
HashMap嵌套HashMap
其实就是把HashMap放在另一个HashMap的键或值上,甚至键和值.

十.HashMap和Hashtable的区别
Vector被ArrayList替代了
Hashtable被HashMap替代了
共同点:
1.底层都是哈希算法.
2.都是双列集合
区别:
1.HashMap是线程不安全的,因为不同步,效率高.JDK1.2版本
  Hashtable是线程安全的,因为同步,效率低,JDK1.0版本
2.HashMap可以存储null键和null值
  Hashtable不可以存储


十一.Collections工具类
为集合的操作提供很多方法.方法全都是静态的.私有了构造方法.为了不能创建该类对象,就用类名直接调用方法.

1.sort()方法
Collections.sort(***),传入即可排序.
2.binarySearch二分查找法
Collections.binarySearch(***,key)
3.max找最大的,传入集合
4.revers反转,传入集合
5.shuffle,随机排序,传入集合


十二.模拟斗地主洗牌发牌.
分析:
1.买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去.
2.洗牌,调用shuffle方法
3.发牌
4.看牌

String[] num={1,2,3};
String[] color={"红桃","黑桃"};
ArrayList poker=new ArrayList();
for(String s1:color){
 for(String s2:num){
 poker.add(s1+s2);
 }
}
poker.add("小王");
poker.add("大王");
//洗牌
Collections.shuffle(poker);
//发牌
ArrayList a1=new ArrayList();
ArrayList a2=new ArrayList();
ArrayList a3=new ArrayList();
ArrayList 底牌=new Arraylist();

for(int i=0;i<poker.size();i++){
 if(i>=poker.size()-3){
 底牌.add(poker.get(i));
 }else if(i%3==0){
 a1.add(poker.get(i));
 }else if(i%3==1){
 a2.add(poker.get(i));
 }else {
 a3.add(poker.get(i));
 }
}

//看牌
sysout(a1);
sysout(a2);
sysout(a3);
sysout(底牌);

十五.集合框架(泛型固定下边界)
1.泛型固定下边界
? super E

构造了一个Student类型的比较器,子类BaseStudent也可以用,为什么呢,因为这里有一个泛型Student.
2.泛型固定上边界
? extends E

addAll方法--把一个集合中的所有元素都添加到元素中.
两个ArrayList,List2的元素是List1的子类,添加元素,list1.addAll(list2),也就是说固定了上边界.其实很简单,list2中的元素的类型如果大于或者不等于list1中的元素,当然就添加不进去.

 

0 0
原创粉丝点击