今日内容
Map集合
Map的概述
Map集合是一个双列集合,它和Collection是一个完全不同的体系,Collection是单列集合
Collection是单列集合一个元素中存一个值,Map是双列集合一个元素可以存储两个值,分别叫做键和值
单列集合:
add("hello");
add("world");
双列集合
put("张三","北京");// "张三"这列就是键,"北京"这列就是值
put("李四","武汉");
put("张三","上海");
put("王五","上海");
Map集合的特点:
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
(1)Map是一个双列集合,键和值,键和值有对应关系
(2)Map集合不能存储相同的键,如何键相同,值覆盖
但是同一个Map集合中可以存储相同的值
(3)键和值是一一对应关系(身份证号和名字),通过键可以唯一找到一个值
但是反过来不能成立
Map集合体系
Map
|-HashMap:不能存储重复元素,存取无序,无索引,针对的是键有效,值是跟着键走的
|-LinkedHashMap:除了存取有序之外,其余都和父类相同
|-TreeMap:大纲已删除,很少用
Map的体系和Set的体系非常相似,Set集合体系下的实现有些其实底层使用的就是Map的功能,比如
HashSet底层使用的就是HashMap的功能
Map集合的数据结构只和键有关,特点也是和键有关
Map接口
常用方法
删除
void clear():清除集合中所有的键值对
V remove(Object key):根据指定的键删除整个键值对,并返回其对应的值,如果指定的键不存储,返回null
判断
boolean containsKey(Object key):判断Map集合中是否包含指定的键
boolean containsValue(Object value):判断Map集合中是否包含指定的值
boolean isEmpty():判断Map集合中是否为空
获取
int size():获取键值对的个数
Collection<V> values():获取Map集合中所有的值,存储到Collection集合中
和Map遍历有关的方法
Set<K> keySet()
V get(Object key):根据键来获取对应的值,并返回
Set<Map.Entry<K,V>> entrySet()
添加/修改
V put(K key, V value):添加键值对,键相等值覆盖(修改值),
如果存在相同的键返回被覆盖的值
如果不存在相同的键返回null
Map集合的遍历
方式一:通过键找值,通过keySet()和get(K k)方法
思路:
(1)先通过keySet()方法找到所有的键,得到的是一个Set集合
(2)遍历Set集合得到每一个键
(3)通过get(K k)方法根据每一个键找到对应的值
// 创建Map集合
Map<String,Integer> map = new HashMap<>();
// 添加元素
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178);
// 遍历
// (1)先通过keySet()方法找到所有的键,得到的是一个Set集合
Set<String> set = map.keySet();
// (2)遍历Set集合得到每一个键
Iterator<String> it = set.iterator();
while(it.hasNext()){
String key = it.next();
// (3)通过get(K k)方法根据每一个键找到对应的值
Integer value = map.get(key);
System.out.println(key+":"+value);
}
方式二:通过键值对对象找键和值,通过entrySet()方法
思路:
(1)先通过entrySet()方法获取所有的键值对对象(Map.Entry<K,V>),得到的是一个Set集合
(2)遍历set集合得到每一个键值对对象(Map.Entry<K,V>)
(3)通过Map.Entry中的getKey()和getValue()方法,分别获取每一个键值对对象中的键和值
步骤:
// 创建Map集合
Map<String,Integer> map = new HashMap<>();
// 添加元素
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178);
// (1)先通过entrySet()方法获取所有的键值对对象(Map.Entry<K,V>),得到的是一个Set集合
Set<Map.Entry<String ,Integer>> set = map.entrySet();
// (2)遍历set集合得到每一个键值对对象(Map.Entry<K,V>)
Iterator<Map.Entry<String ,Integer>> it = set.iterator();
while(it.hasNext()){
Map.Entry<String ,Integer> entry = it.next();
// (3)通过Map.Entry中的getKey()和getValue()方法,分别获取每一个键值对对象中的键和值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+":"+value);
}
四种写法
keySet() 增强for
entrySet() 迭代器
面试题:HashMap和Hashtable的区别?
(1)HashMap集合允许存储null键和null值,但是null键只能有一个
Hashtable不允许存储null键和null值,否则会报出空指针异常
(2)HashMap是非同步的,多线程情况下不安全,没有加同步锁,不需要判断锁,效率高
Hashtable是同步的,多线程情况下安全,加了同步锁,需要判断锁,效率低
课堂案例:统计一个字符串中每个字符出现次数
of方法
JDK1.9的新特性,从JDK1.9开始List接口、Set接口和Map接口提供了静态的of方法
使用场景:为了方便一次给集合存储多个元素,知道具体的元素值和个数
注意事项:
(1)集合元素是不能改变(不能添加、删除和修改元素的值)
(2)针对Set存储的值不能重复
针对Map存储的键不能重复,值可以重复
斗地主案例
package cn.day07.test;
import java.util.*;
/*
步骤:
准备牌
给每一种牌进行编号
洗牌
洗编号
对编号进行排序
发牌
发编号
看牌
根据编号反找牌
*/
public class Test03 {
public static void main(String[] args) {
// (1)准备牌
// map集合有对应关系,键存编号,值存牌
Map<Integer,String> pokerBox = new HashMap<>();
String[] str1 = {"♥","♠","♣","♦"};
String[] str2 = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
// 牌的编号
int pokerIndex = 0;
for (int i = 0; i < str2.length; i++) {
for (int j = 0; j < str1.length; j++) {
pokerBox.put(pokerIndex++,str1[j]+str2[i]);
}
}
// 加入大小王,并编号
pokerBox.put(pokerIndex++,"小王");
pokerBox.put(pokerIndex,"大王");
// (2)洗牌
// 编号
ArrayList<Integer> numList = new ArrayList<>();
// 拿到所有的编号
Set<Integer> set = pokerBox.keySet();
// 方到List集合中,因为shuffle方法只能对List集合进行随机打乱操作
numList.addAll(set);
Collections.shuffle(numList);
// (3)发牌
// 牌友
ArrayList<Integer> zhourunfa = new ArrayList<>();
ArrayList<Integer> jackma = new ArrayList<>();
ArrayList<Integer> pony = new ArrayList<>();
// 底牌
ArrayList<Integer> dipai = new ArrayList<>();
for (int i = 0; i < numList.size(); i++) {
Integer pokerNum = numList.get(i);
if(i >= numList.size()-3){ //
// 底牌
dipai.add(pokerNum);
}else if(i%3==0){
// zhourunfa
zhourunfa.add(pokerNum);
}else if(i%3==1){
// jackma
jackma.add(pokerNum);
}else {
// pony
pony.add(pokerNum);
}
}
// 排序
Collections.sort(zhourunfa);
Collections.sort(jackma);
Collections.sort(pony);
Collections.sort(dipai);
// (4)看牌
lookPoker(pokerBox, zhourunfa,"周润发");
lookPoker(pokerBox, jackma,"马云");
lookPoker(pokerBox, pony,"马化腾");
lookPoker(pokerBox, dipai,"底牌");
}
private static void lookPoker(Map<Integer, String> pokerBox, ArrayList<Integer> zhourunfa, String name) {
System.out.print(name+":");
StringBuilder sb = new StringBuilder("[");
// 看牌
for (int i = 0; i < zhourunfa.size(); i++) {// [,,,,]
// 编号
Integer num = zhourunfa.get(i);
// 根据编号去牌盒中获取对应的牌
String poker = pokerBox.get(num);
sb.append(poker);
// 最后一张牌
if(i != zhourunfa.size()-1){
sb.append(", ");
}else {
sb.append("]");
}
}
System.out.println(sb);
}
}