【Map】

今日内容
    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);
    }
}

猜你喜欢

转载自blog.csdn.net/L531003231/article/details/81748056
Map