集合框架——Map接口

一、Map集合

1、Map集合中常见的方法。

    Map是一个接口,是所有双列集合的根接口

    Map<K,V>有两个泛型, K 表示的是键的数据类型, V表示的是值的数据类型。

    常见方法:

        (重要)V put(K key, V value): 向Map集合中添加键值对

        (重要)V get(Object key):根据键获取对应的值。

        V remove(Object key): 根据键删除整个的键值对。

    注意: put方法调用的使用如果key已经存在,那么就会覆盖掉原来的键值对。

public class Demo01MapMethod {

    public static void main(String[] args) {

        //创建一个Map集合,key是Integer,value是String

        Map<Integer, String> map = new HashMap<>();

        //调用put方法,向Map集合中添加键值对元素

        map.put(100, "刘德华");

        map.put(200, "张学友");

        map.put(300, "黎明");

        //打印Map集合

        System.out.println(map);

        //V get(Object key):根据键获取对应的值。

        System.out.println(map.get(100)); //获取100对应的值并直接打印

        System.out.println(map.get(10000)); //如果key不存在,那么结果是null。

 

        //V remove(Object key): 根据键删除整个的键值对。 返回的是被删除键值对的值.

        String str = map.remove(300); //将key为300的键值对删除。

        System.out.println(map); // {100=刘德华, 200=张学友}

        System.out.println("str:" + str);

        System.out.println("=============================================");

 

        //创建一个Map集合,key是String,value也是String

        Map<String, String> map2 = new HashMap<>();

 

        //添加元素

        map2.put("it001", "大幂幂");

        map2.put("it002", "柳岩");

        map2.put("it003", "郭德纲");

 

        //map2.put("it003", "于谦");//如果使用put方法向Map中添加的键值对中的key已经存在,那么就会把之前的键值对覆盖掉。

 

        System.out.println("map2:" + map2);

 

        //调用put方法时,如果没有产生覆盖效果,那么返回的是null

        //如果产生了覆盖效果,那么返回值为被覆盖掉的值。

        System.out.println(map2.put("it004", "赵本山")); //null

        System.out.println(map2.put("it004", "宋丹丹")); //赵本山

 

    }

}

        2、遍历Set集合,还有一种方式,是EntrySet遍历。

    遍历步骤:

        1. 调用Map集合的entrySet方法获取到Map集合中的所有的Entry对象。

        2. 遍历存放Entry对象的Set集合,拿到里面的每一个Entry对象。

        3. Entry对象中保存了键值对,我们可以调用方法获取到键和值。

    Map集合中获取所有Entry对象的方法:

        Set<Map.Entry<K,V>> entrySet():获取Map集合中所有的Entry对象'

    Entry中获取建和值的方法:

        K getKey() :获取此entry对象中的键

        V getValue(): 获取此entry对象中的值。

    两种遍历方式,一种是keySet,另一种是entrySet。

    第一种keySet方式更好,更加简洁,这种是推荐的。

public class Demo02EntrySet {

    public static void main(String[] args) {

        //创建Map集合

        Map<String, String> map = new HashMap<>();

        //添加键值对

        map.put("it001", "王宝强");

        map.put("it002", "李宝强");

        map.put("it003", "张宝强");

 

        //使用entrySet的方式遍历这个Map集合

 

        //调用Map集合的entrySet方法获取到Map集合中的所有的Entry对象。

        Set<Map.Entry<String, String>> set = map.entrySet();

 

        //遍历存放Entry对象的Set集合,拿到里面的每一个Entry对象。

        for (Map.Entry<String, String> entry : set) {

            //Entry对象中保存了键值对,我们可以调用方法获取到键和值。

            String key = entry.getKey();

            String value = entry.getValue();

            System.out.println(key + "-" + value);

        }

    }

}

    3、map集合的遍历

如何对Map集合进行遍历。

    Map是一个双列集合,不能直接通过增强for或者迭代器去遍历。

    我们可以想办法先获取到Map集合中所有的key,把所有的key存放到一个Set集合, 然后遍历这个Set集合,

    拿到里面的每一个key, 根据key获取对应的value。

    在Map集合中,有一个方法,可以获取到集合中的所有的key

        Set<K> keySet(): 获取Map集合中的所有的key,并放入到一个Set集合中返回.

    keySet方式遍历的步骤:

        1. 调用Map集合的keySet方法,获取所有的key,并存放于一个Set集合中返回

        2. 遍历Set集合,拿到Set集合中的每一个key

        3. 调用Map集合的get方法,根据key获取对应的value

public class Demo02MapKeySet {

    public static void main(String[] args) {

        //创建Map集合

        Map<String, String> map = new HashMap<>();

        //添加

        map.put("it001", "刘备");

        map.put("it003", "曹操");

        map.put("it004", "周瑜");

        map.put("it002", "关羽");

 

        //对Map集合进行遍历

        //调用Map集合的keySet方法,获取所有的key,并存放于一个Set集合中返回

        Set<String> set = map.keySet();

 

        //遍历Set集合,拿到里面的每一个key

        for(String key : set) {

            //调用Map集合的get方法,根据key获取对应的value

            String value = map.get(key);

            System.out.println(key + ":" + value);

        }

    }

}

 

    4、 练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到

    map集合中。学生对象作为键, 家庭住址作为值。

 

    注意,学生姓名相同并且年龄相同视为同一名学生

 

    HashMap中的key如何保证唯一性??

    HashMap中的key保证唯一性的过程和HashSet一模一样(原因: HashSet内部用的就是一个HashMap)

 

    1. 先比较对象的哈希值

        如果对象的哈希值不同,那么肯定是不同的对象。

        如果对象的哈希值相同,那么不一定是同一个对象。

    2. 如果哈希值相同还要调用equals方法

        如果equals方法得到的结果是true,那么表示两个对象相同

 

        如果equals方法得到的结果是false,那么表示两个对象不同。

 

public class Demo03MapTest {

    public static void main(String[] args) {

        //定义一个集合,key是Student类型, value是String

        Map<Student, String> map = new HashMap<>();

        //向Map集合中添加键值对。

        map.put(new Student("郭靖", 18), "襄阳");

        map.put(new Student("黄蓉", 16), "桃花岛");

        map.put(new Student("小龙女", 20), "古墓");

 

        map.put(new Student("小龙女", 20), "龙宫");

 

 

        //遍历Map集合,拿到Map集合中的每一个键值对并打印

        //获取到Map集合中的所有的key,放入到Set集合返回

        Set<Student> set = map.keySet();

 

        //遍历这个Set集合,拿到里面的每一个key

        for(Student key : set) {

            //根据key获取value

            String value = map.get(key);

            System.out.println(key + "::" + value);

        }

    }

}

        5、LinkedHashMap       

  LinkedHashMap 也是Map接口的实现类。

    内部除了有一个哈希表之外还有一个链表。 链表的作用是保证有序。

    LinkedHashMap 它的特点是有序(按照什么顺序存,就按照什么顺序取)

 

public class Demo04LinkedHashMap {

    public static void main(String[] args) {

        //创建一个Map集合

        Map<String, String> map = new LinkedHashMap<>();

        //添加键值对

        map.put("it001", "刘备");

        map.put("it002", "曹操");

        map.put("it003", "孙权");

 

        //进行打印

        System.out.println(map);

    }

}

 

 

    在JDK9之后,集合提供了of方法,可以直接创建带有少量元素的集合。

 

    这个of方法是List接口,Set接口,Map接口中的静态方法。

 

    注意:

        1. 使用of方法创建的集合不能改变(不能添加或者删除等操作)

        2. 这个of方法是ist接口,Set接口,Map接口中的静态方法,不能通过实现类去调用.

 

public class Demo06Of {

    public static void main(String[] args) {

        //通过List接口调用of方法,直接创建一个带有少量元素的List集合

        List<String> list = List.of("aa", "bb", "cc");

 

        //list.add("dd"); //UnsupportedOperationException

        System.out.println("list:" + list);

 

        //通过Set接口调用of方法,直接创建一个带有少量元素的Set集合

        Set<String> set = Set.of("张三", "李四", "王叔叔");

        System.out.println("set:" + set);

 

 

        //通过Map接口调用of方法,创建一个带有少量元素的Map集合

        Map<String, String> map = Map.of("it001", "张三", "it002", "李四", "it003", "王叔叔");

        System.out.println("map:" + map);

 

    }

}

 

    6、bug: 计算机中的问题

    debug: 解决问题。

    断点作用: 可以让程序在执行的过程中停下来

    如何加断点: 在代码的左边点击即可。

    如何运行: 右键 debug...

    F8: 让代码向下执行一行。

    F9: 释放断点

 

 

    7、斗地主排序版的实现

@SuppressWarnings("all") //注解,抑制警告

public class Demo01Game {

    public static void main(String[] args) {

        //1. 准备牌

        //定义一个ArrayList集合,保存牌的编号

        ArrayList<Integer> poker = new ArrayList<>();

        //定义一个Map集合,保存编号和牌的对应关系

        HashMap<Integer, String> map = new HashMap<>();

        //向ArrayList集合添加编号,向Map集合中添加编号和牌的对应关系

        //定义两个数组,一个保存花色,一个保存点数

        String[] colors = {"♠", "♥", "♣", "♦"};

        String[] nums = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};

        //定义变量,表示牌的编号,从0开始

        int index = 0;

 

        //对花色和点数进行组合

        for (String num : nums) {

            for(String color : colors) {

                //先把编号 添加到ArrayList集合

                poker.add(index);

                //把这个编号和当前遍历到的牌组合添加到map集合中

                map.put(index, color + num);

                //让编号自增

                index++;

            }

        }

 

        //添加大小王

        poker.add(index);

        map.put(index, "小王");

        index++;

 

        poker.add(index);

        map.put(index, "大王");

 

        //2. 洗牌

        //打乱保存编号集合的顺序

        Collections.shuffle(poker);

 

        //3. 发牌

        //定义三个集合,用来保存这三个人的扑克牌(真正保存的是编号)

        ArrayList<Integer> playerOne = new ArrayList<>();

        ArrayList<Integer> playerTwo = new ArrayList<>();

        ArrayList<Integer> playerThree = new ArrayList<>();

 

        //定义一个集合,保存底牌(真正保存的是编号)

        ArrayList<Integer> diPai = new ArrayList<>();

 

        //发牌,遍历保存扑克牌的集合,根据每张牌的索引进行发牌。

        for(int i = 0; i < poker.size(); i++) {

            //拿到当前遍历到的扑克牌(真正遍历到的其实是牌的编号)

            Integer card = poker.get(i);

 

            //处理底牌,如果剩余不足三张,就放入到底牌中

            if(i >= 51) {

                diPai.add(card);

                continue;

            }

 

            //开始发牌

            if(i % 3 == 0) { //根据牌的索引发牌,如果索引 % 3 结果是0,那么就发给第一个人

                playerOne.add(card);

            } else if(i % 3 == 1) {//如果牌的索引 % 3 结果是1 ,那么就发给第二个人

                playerTwo.add(card);

            } else { //如果是牌的索引对3取余结果是2,那么就发给第三个人

                playerThree.add(card);

            }

        }

 

        //4. 看牌

        lookCard("刘德华", playerOne, map);

        lookCard("周润发", playerTwo, map);

        lookCard("周星驰", playerThree, map);

 

        lookCard("底牌", diPai, map);

    }

 

    /*

        看牌方法

        参数: String类型的姓名, ArrayList集合(玩家手里的编号), Map集合(编号和牌的对应关系)

     */

    public static void lookCard(String name, ArrayList<Integer> list, HashMap<Integer, String> map) {

        //对保存编号的ArrayList集合进行排序

        Collections.sort(list);

        //打印玩家的姓名

        System.out.print(name + ": ");

        //遍历保存编号的集合,拿到玩家手中的每一个编号

        for(Integer num : list) {

            //num指的是每张牌的编号

            //拿着这个编号去Map集合中找一下这个牌到底是什么

            String card = map.get(num);

            System.out.print(card + " ");

        }

        //为了方便后面输出,打印空换行

        System.out.println();

    }

 

}

 

    总结:

能够说出Map集合特点

    Map集合中的每一个元素都是一个键值对。

    键不能重复。

    值可以重复。

    可以根据键找到对应的值。

使用Map集合添加方法保存数据

    map.put(key, value);

    如果添加的元素key已经存在了,就会把之前的元素覆盖掉。

使用”键找值”的方式遍历Map集合

    keySet方法

    

    1. 调用Map集合的keySet方法,获取所有的key。

    2. 遍历保存所有key的Set集合,拿到每一个key。

    3. 调用map集合的get方法,根据key获取value

使用”键值对”的方式遍历Map集合

    entrySet

    1. 调用Map集合的entrySet方法,获取所有的entry对象

    2. 遍历保存所有entry对象的Set集合, 拿到每一个Entry

    3. 调用entry对象的getKey和getValue获取键和值

能够使用HashMap存储自定义键值对的数据

    如果要使用HashMap保存自定义键,并且要保证唯一性,

    必须要重写hashCode和equals方法。

能够使用HashMap编写斗地主洗牌发牌案例

    因为要排序,所以我们使用了一个集合保存编号。

    洗牌发牌操作的都是编号。

    只有看牌的时候才根据编号去找的这张牌到底是什么。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值