Day16
一、Map接口(双列集合层次结构的根接口)
1、Map是以键值对的形式来进行存储(Key,Values),键是唯一的,不能够重复,values是可以重复的,每一个键只能对应一个值(一一对应,映射的关系)
2、Map的具体实现类有HashMap(重点),TreeMap,Hashtable(较少使用)
Map.Entry<K,V>:Entry是Map里的一个内部接口(定义时直接使用Map.Entry)
3、Map常规的一些方法:
- V put(K key,V value):通过键值对来进行添加数据;还可以根据键来修改值,键必须存在;
- V remove(Object key):通过键来删除键值对数据(没有根据索引来移除);
- boolean containsKey(Object key):判断这个键是否存在;
- boolean containsValue(Object value):判断这个值是否存在;
- boolean isEmpty():是否存在元素;
- void clear():清除所有的元素;
- V get(Object key):通过键来获取值;
- int size():获取集合的长度;
- Collection values():获取所有的values();
- Set keySet():获取map中所有的键,返回值是一个Set对象;
Collection与Map的区别:
- Collection:(1)单列集合(存储的数据都是独立);(2)数据结构都是具体的数据;(3)Set集合不能出现重复的数据
- Map:(1)双列集合(以键值对进行存储);(2)数据结构都是键值对;(3)键不能出现重复的数据
4、Map集合遍历方式:
package com.yxlim.day16;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 两种方式遍历Map集合
*/
public class Test {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "123");
map.put(2, "213");
map.put(3, "321");
//迭代器遍历Map.keySet(通过所有Key《keySet》来获取map)
Set<Integer> set1 = map.keySet();
Iterator<Integer> it = set1.iterator();
while (it.hasNext()) {
int id = it.next();
System.out.println(id + "-->" + map.get(id));
}
System.out.println("***************************");
//迭代器遍历map.entrySet(通过map.entrySet来获取map)
Set<Map.Entry<Integer,String>> set2 = map.entrySet();
Iterator<Map.Entry<Integer,String>> ite=set2.iterator();
while (ite.hasNext()){
Map.Entry<Integer,String> entry=ite.next();
System.out.println(entry.getKey()+"-->"+entry.getValue());
}
}
}
5、Map集合里嵌套Map集合,然后进行遍历(从外层往内层剥开):
package com.yxlim.day16;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 使用Map嵌套Map,然后解嵌套遍历输出
*/
public class MapNesting {
public static void main(String[] args) {
//Map集合嵌套另一个Map集合
Map<String,Student> innerMap=new HashMap<>();
innerMap.put("飓风",new Student("皮蛋",10));
innerMap.put("棉花糖",new Student("小乖",8));
Map<String,Map<String,Student>> outerMap=new HashMap<>();
outerMap.put("繁荣山丘",innerMap);
outerMap.put("摩登城镇高速",innerMap);
//从外层往内层剥开
Set<String> outerSet=outerMap.keySet();//先对外层的剥开
Iterator<String> outerIte=outerSet.iterator();
while (outerIte.hasNext()){
String placeKey=outerIte.next();
System.out.println("赛道:"+placeKey);
Set<String> innerSet=outerMap.get(placeKey).keySet();//再对内层的剥开
Iterator<String> innerIte=innerSet.iterator();
while (innerIte.hasNext()){
String carKey=innerIte.next();
System.out.println(innerMap.get(carKey).getName()+"-->"+carKey+"\t"+innerMap.get(carKey).getAge()+"岁");
}
System.out.println("****************");
}
}
}
二、HashMap类(是Map直接实现类,存储方式是以哈希表的结构来进行存储的,无序)
- HashMap和HashSet都是以哈希表结构来进行存储《查询速度快》
- HashSet的底层是以Map的方法来实现的,只取Map集合的key部分,对于values,给予private static final Object PRESENT = new Object()静态常对象,表示不使用(所以Map的key和Set都是无序且不能重复)
三、LinkedHashMap是HashMap的一个子类,存储结构也是数组+双重链表
四、Hashtable和HashMap的区别
- 版本不一样:Hashtable 1.0;HashMap 1.2
- Hashtable不符合命名规范;HashMap 是符合
- Hashtable线程安全,效率低;HashMap线程不安全,效率高
- HashMap已经替换掉Hashtable,常用hashMap
五、Collections(对List操作的工具类)、Arrays(对数组操作的工具类)
六、List和Map的结合操作
package com.yxlim.day16;
import java.util.*;
/**
* 生成扑克(四种花色:方块、梅花、红桃、黑桃)(A-K加大小鬼)共54张
* 清洗扑克
* 分发扑克(3人*17张,底牌3张)
* 查看扑克
* (使用List<Integer>存储对应Map里的key)重点
*/
public class PoKer {
public static void main(String[] args) {
//定义两个数组,一个表示花色、一个表示A-K
String[] pokerColors={"♢","♣","♡","♠"};
String[] pokerNums={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//定义一个Map存储扑克类型,List存储key
List<Integer> pokerKey=new ArrayList<>();//存放索引-->对应Map的key
Map<Integer,String> poker=new HashMap<>();
int index=0; //递增作为List的索引,Map的key
for(String s2:pokerNums){
for(String s1:pokerColors){
poker.put(index,s1+s2);
pokerKey.add(index);
index++;
}
}
poker.put(index,"小王");
poker.put(index+1,"大王");
pokerKey.add(index);//添加小王索引
pokerKey.add(index+1);//添加大王索引
//洗牌
Collections.shuffle(pokerKey);
//发牌
List<Integer> list1=new ArrayList<>();//玩家1
List<Integer> list2=new ArrayList<>();//玩家2
List<Integer> list3=new ArrayList<>();//玩家3
List<Integer> dipai=new ArrayList<>();//底牌
for(int i=0;i<pokerKey.size();i++){
if(i>=pokerKey.size()-3){ //抽出最后的三张底牌
dipai.add(pokerKey.get(i));
}else if(i%3==0){ //模3给第一个人发牌
list1.add(pokerKey.get(i));
}else if(i%3==1){ //模3给第二个人发牌
list2.add(pokerKey.get(i));
}else if(i%3==2){ //模3给第三个人发牌
list3.add(pokerKey.get(i));
}
}
//整理扑克
show("玩家1",list1,poker);
show("玩家2",list2,poker);
show("玩家3",list3,poker);
show("底牌",dipai,poker);
}
//整理方法
public static void show(String s,List<Integer> list,Map<Integer,String> map){
Collections.sort(list);
if(s.equals("底牌")){ //判断是否是底牌
System.out.print(s+":");
}else { //玩家输出
System.out.print(s + "的手牌:");
}
//对玩家和底牌进行输出
for(int i=0;i<list.size();i++){
System.out.print(map.get(list.get(i))+" ");
}
System.out.println();
}
}