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();
    }
}