7月25号_Map集合

Map

今天的主要内容

  • Map接口概述

  • Map集合的两种遍历方式

    • 通过键找值keySet

    • 通过键值对对象获取键和值

      • 涉及到Map.Entry的认识
  • HashMap

    • 自定义对象必须重写equals和hashCode方法
  • LinkedHashMap

  • TreeMap

    • 统计字符串中每个字符出现的次数
  • HashMap和Hashtable的区别

    • 线程安全方面

    • 存储键值对的数据类型方面

一、集合框架(Map集合概述和特点)

  1. Map接口概述

    • 查看API可以知道:

      • 将键映射到值的对象( maps keys to values)

      • 一个映射不能包含重复的键(A map cannot contain duplicate keys)

      • 每个键最多只能映射到一个值( each key can map to at most one value.)

  1. Map接口和Collection接口的不同

    • Map是双列的,Collection是单列的

    • Map的键唯一,Collection的子体系Set是唯一的

    • Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效

二、集合框架(Map集合的功能概述)

  • A:Map集合的功能概述

    • a:添加功能

      • V put(K key,V value):添加元素。

        • 如果键是第一次存储,就直接存储元素,返回null

        • 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

        • 相同的键不存储,值覆盖

    • b:删除功能

      • void clear():移除所有的键值对元素

      • V remove(Object key):根据键删除键值对元素,并把值返回

    • c:判断功能

      • boolean containsKey(Object key):判断集合是否包含指定的键

      • boolean containsValue(Object value):判断集合是否包含指定的值

      • boolean isEmpty():判断集合是否为空

    • d:获取功能

      • Set<Map.Entry<K,V>> entrySet():

      • V get(Object key):根据键获取值

      • Set<K> keySet():获取集合中所有键的集合

      • Collection<V> values():获取集合中所有值的集合

    • e:长度功能

      • int size():返回集合中的键值对的个数
  • 测试程序

      public class TestMap {
          public static void main(String[] args) {
              Map<String,Integer> map = new HashMap<>();
              
              //添加功能
              System.out.println("====V put(K key,V value):添加元素.====");
              testPut(map);
              
              //删除功能
              System.out.println("====V remove(Object key):====");
              testRemove(map);
              
              //判断功能
              System.out.println("==============判断功能==============");
              testBoolean(map);
              
              System.out.println(" ==========e:长度功能 int size()==========");
              testSize(map);
          }
          
          public static void testPut(Map<String,Integer> map) {
              /*
                  a:添加功能
                      V put(K key,V value):添加元素。
                      * 如果键是第一次存储,就直接存储元素,返回null
                      * 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
              */
              Integer i1  = map.put("小王", 21);
              Integer i2 = map.put("小李", 22);
              Integer i3 = map.put("小王", 23);
              Integer i4 = map.put("小花", 24);
              Integer i5 = map.put("小明", 25);
              
              System.out.println(map);
              System.out.println(i1);
              System.out.println(i2);
              System.out.println(i3);
              System.out.println(i4);
              System.out.println(i5);
              
              /*
               *   在JDK1.8中输出结果为:
               *  -------------------------------
               *  ====V put(K key,V value):添加元素.====
                  {小李=22, 小明=25, 小王=23, 小花=24}
                  null        //返回null表示值没有被覆盖
                  null
                  21          //键相等,值覆盖,返回被覆盖的值
                  null
                  null
               * -------------------------------
               * */
          }
          
          public static void testRemove(Map<String,Integer> map) {
              /*
               * b:删除功能
               * void clear():移除所有的键值对元素
               * V remove(Object key):根据键删除键值对元素,并把值返回
               */
              
              Integer i1 = map.remove("小王");
              Integer i2 = map.remove("小李");
              
              System.out.println(i1);
              System.out.println(i2);
              
              System.out.println("删除后,集合中元素有:");
              System.out.println(map);
              
              /*
               * 在JDK1.8中输出结果为:
               * ---------------------------------
               * ====V remove(Object key):====
                  23
                  22
                  删除后,集合中元素有:
                  {小明=25, 小花=24}
                ---------------------------------
               * */       
          }
          
          public static void testBoolean(Map<String,Integer> map) {
              /*
               * c:判断功能
               *
               * boolean containsKey(Object key):判断集合是否包含指定的键
               * boolean containsValue(Object value):判断集合是否包含指定的值
               * boolean isEmpty():判断集合是否为空
              */
              
              System.out.println("Map集合是否为空?" + map.isEmpty());
              System.out.println("Map集合是否包含指定的键“小花? " + map.containsKey("小花"));
              System.out.println("Map集合是否包含指定的值:28  " + map.containsValue(28));
              
              /*
               *  在JDK1.8中输出结果为:
               *  ---------------------------------------
               *  ==============判断功能==============
                  Map集合是否为空?false
                  Map集合是否包含指定的键“小花? true
                  Map集合是否包含指定的值:28  false
                  --------------------------------------- 
               * */
          }
          
          public static void testSize(Map<String,Integer> map) {
              System.out.println("Map中键值对个数为: "  + map.size()); 
              
              /*
               * 在JDK1.8中输出结果为:
               * ---------------------------------------
               * ==========e:长度功能 int size()==========
                 Map中键值对个数为: 2
                 ---------------------------------------
               * */
          }
      }
    

三、集合框架(Map集合的遍历之键找值)

  1. 键找值思路:

    • 获取所有键的集合

      • Set<K> keySet()——返回所有键的集合
    • 遍历键的集合,获取到每一个键

      • Set集合中的iterator方法
    • 根据键找值

      • V get(Object key)
  2. 程序——Map集合的遍历之键找值

     public static void main(String[] args) {
         Map<String,Integer> map = new HashMap<>();
         
         map.put("小王", 21);
         map.put("小李", 22);
         map.put("小花", 24);
         map.put("小明", 25);
         
         //获取所有键
         Set<String> set = map.keySet();
         
         //获取迭代器
         Iterator<String> i = set.iterator();
         
         //遍历输出所有键
         while(i.hasNext()) {
             String key = i.next();
             System.out.println("key = " + key + " value = " + map.get(key));
         }
     
         //增强的for循坏输出键值对
         /*
         for(String key : map.keySet()) {
             System.out.println("key = " + key + " value = " + map.get(key));
         }*/
     }
    

四、集合框架(Map集合的遍历之键值对对象找键和值)

  1. 键值对对象找键和值思路:、

    • 获取所有键值对对象的集合——entrySet方法返回Map.Entry类型

      • 将所有的Map.Entry对象放在Set集合中
* 遍历键值对对象的集合,获取到每一个键值对对象

    * Set接口中的iterator方法遍历出每一个Map.Entry对象

* 根据键值对对象找键和值

    * 利用Map.Entry接口中的getKey()和getValue方法获取键和值
  1. 案例演示
    • Map集合的遍历之键值对对象找键和值

        public class TestIterator_3 {
            public static void main(String[] args) {
                Map<String,Integer> map = new HashMap<>();
                
                map.put("小王", 21);
                map.put("小李", 22);
                map.put("小花", 24);
                map.put("小明", 25);
                
                /*//Map.Entry说明Entry是Map的内部接口
                //将键和值封装成Entry对象,并存储在Set集合中
                Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
                
                //获取每一个对象
                Iterator<Map.Entry<String, Integer>> i = entrySet.iterator();
                
                while(i.hasNext()) {
                    
                    Map.Entry<String,Integer> me = i.next();
                    System.out.println("key = " + me.getKey() + "value  = " + me.getValue());
                }*/
                
                for(Map.Entry<String, Integer> e : map.entrySet()) {
                    System.out.println("key = " + e.getKey() + "value  = " + e.getValue());
                }
            }
        }
        /*
         *   在JDK1.8中输出结果为:
         *  -----------------------
         *  key = 小李value  = 22
            key = 小明value  = 25
            key = 小王value  = 21
            key = 小花value  = 24
            ------------------------
         * */
      

五、HashMap

  • 类似于HashSet对键唯一的要求

    • 在自定义类型的时候,一定要重写HashCode和equals方法

六、LinkedHashMap

  • 链表实现:可保证怎么存就怎么取

七、TreeMap

  • 自定义对象必须实现Comparable接口或者Comparator接口

    • 自定义对象若实现Comparable接口,则必须重写compareTo方法

    • 自定义对象若实现Comparator接口,则必须重写compare方法

八、集合框架(统计字符串中每个字符出现的次数)

  • 需求:统计字符串中每个字符出现的次数

  • 分析

    1. 从键盘获取字符串输入,将字符串转换为字符数组
    2. 创建HashMap集合,将字符串中的字符作为key存入到HashMap中
    3. 当该字符包含在HashMap中时,则增加value
    4. 遍历HashMap输出字符串中每一个字符出现的次数
  • 程序

      public class TestMap_2 {
          public static void main(String[] args) {
              //1. 从键盘获取字符串输入,将字符串转换为字符数组
              Scanner input = new Scanner(System.in);
              
              System.out.println("请输入要统计的字符串");
              String string = input.nextLine();
              
              char[] charArr = string.toCharArray();
              
              //2. 创建HashMap集合,将字符串中的字符作为key存入到HashMap中
              HashMap<Character, Integer> hashMap = new HashMap<>();
              
              //3. 当该字符包含在HashMap中时,则增加value
              for(char c : charArr) {
                  /*
                  if(hashMap.containsKey(c)) {
                      //增加value
                      hashMap.put(c,hashMap.get(c) + 1);
                  }
                  else {
                      hashMap.put(c,1);
                  }
                  */
                  //上段代码也等价于
                  hashMap.put(c, hashMap.containsKey(c) ? hashMap.get(c) + 1 : 1);
              }
              
              //4. 遍历HashMap输出字符串中每一个字符出现的次数
              //在这儿我们使用通过键值对象获取键和值
              
              Set<Map.Entry<Character, Integer>> set = hashMap.entrySet();
              
              //获取set的迭代器
              Iterator<Map.Entry<Character, Integer>> iterator = set.iterator();
              
              //遍历输出键和值
              while(iterator.hasNext()) {
                  //获取Entry对象
                  Entry<Character, Integer> entry = iterator.next();
                  
                  System.out.println(entry.getKey() + "出现的次数为:" + entry.getValue());
              }
          }
      }
      /*
       *  在JDK1.8中输出结果为:
       *  ----------------
       *  请输入要统计的字符串
          aaaabbbbbcc
          a出现的次数为:4
          b出现的次数为:5
          c出现的次数为:2
          ----------------
       * */
    

九、集合框架(HashMap和Hashtable的区别)

  • A:面试题

    • HashMap和Hashtable相同点

      • 底层实现都是哈希算法,都是双列集合
    • HashMap和Hashtable的区别

      • Hashtable是JDK1.0版本出现的,是线程安全的,效率低,HashMap是JDK1.2版本出现的,是线程不安全的,效率高

      • Hashtable不可以存储null键和null值,HashMap可以存储null键和null值

十、集合框架(Collections工具类的概述和常见方法讲解)

  • A:Collections类概述

    • 针对集合操作 的工具类
  • B:Collections成员方法

      public static <T> void sort(List<T> list)
      public static <T> int binarySearch(List<?> list,T key)
      public static <T> T max(Collection<?> coll)
      public static void reverse(List<?> list)
      public static void shuffle(List<?> list)
    

十一、集合框架(模拟斗地主洗牌和发牌)

  • 模拟斗地主洗牌和发牌

  • 程序

      //买一副牌
      String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
      String[] color = {"方片","梅花","红桃","黑桃"};
      HashMap<Integer, String> hm = new HashMap<>();          //存储索引和扑克牌
      ArrayList<Integer> list = new ArrayList<>();            //存储索引
      int index = 0;                                          //索引的开始值
      for(String s1 : num) {
          for(String s2 : color) {
              hm.put(index, s2.concat(s1));                   //将索引和扑克牌添加到HashMap中
              list.add(index);                                //将索引添加到ArrayList集合中
              index++;
          }
      }
      hm.put(index, "小王");
      list.add(index);
      index++;
      hm.put(index, "大王");
      list.add(index);
      //洗牌
      Collections.shuffle(list);
      //发牌
      TreeSet<Integer> gaojin = new TreeSet<>();
      TreeSet<Integer> longwu = new TreeSet<>();
      TreeSet<Integer> me = new TreeSet<>();
      TreeSet<Integer> dipai = new TreeSet<>();
      
      for(int i = 0; i < list.size(); i++) {
          if(i >= list.size() - 3) {
              dipai.add(list.get(i));                         //将list集合中的索引添加到TreeSet集合中会自动排序
          }else if(i % 3 == 0) {
              gaojin.add(list.get(i));
          }else if(i % 3 == 1) {
              longwu.add(list.get(i));
          }else {
              me.add(list.get(i));
          }
      }
      
      //看牌
      lookPoker("高进", gaojin, hm);
      lookPoker("龙五", longwu, hm);
      lookPoker("冯佳", me, hm);
      lookPoker("底牌", dipai, hm);     
    

    }

    public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer, String> hm) {
    System.out.print(name + "的牌是:");
    for (Integer index : ts) {
    System.out.print(hm.get(index) + " ");
    }
    System.out.println();
    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • 其实,我的愿望很低很小, 我只想做成一棵树, 安静地伫立在三亚,在亚龙湾。 晴天, 我抚摸阳光,仰望蓝天和白云。 ...
    青岛老黄阅读 324评论 1 3
  • 7月30日 23:32呜呜呜呜呜呜呜求之不得真的是最大的虐点……总感觉……像周泰这样的人,出身低微,又不够聪明,所...
    洞庭府君阅读 887评论 2 10
  • 丘峦风息寂无言,古木垂臂安绿荫。 草吐芳馨蝇飞舞,花闪银荜予独倾。 伊人熠熠鎏金闪,我惟初醒唱杜鹃。 茵梦去来无处...
    表观奇迹阅读 560评论 0 2
  • 程菲菲茫然的走在大街上,她不知道该去哪里,也不知道自己能去哪里,就是这样茫然的走着,孤独而无助。 该怎么办呢,该怎...
    曼曼语阅读 233评论 4 0