Java基础集合篇03-Map集合

1. Map集合

1.1 Map集合介绍

  • Map集合是一个存储数据的容器。
  • Map集合存储数据的方式是键值对(key/value)。
    • key键不可以重复(若重复设置,则会覆盖原有key对应的值)。
    • value值可以重复。
  • Map集合的底层数据结构是哈希表(数组+链表/红黑树)。

1.2 Map集合和Collection集合区别

  • Collection集合是单例集合

    • 元素的种类是单个
  • Map集合是双例集合。
    • 元素的种类是一对
  • 图解:

    单例集合和双例集合

1.3 Map集合常用子类

  • HasMap

    • 是Map集合的一个子类
    • 底层数据结构是哈希表
    • 键不可以重复(键对应的类型需要重写了hashCode()和equals方法()),值可以重复。
    • 存取是无序的(存取顺序可能不一致)
  • LinkedHashMap
    • 是HashMap集合的一个子类
    • 底层数据结构是哈希表+链表(记录存取顺序)
    • 键不可以重复(键对应的类型需要重写了hashCode()和equals方法()),值可以重复。
    • 存取是有序的(存取的顺序一定是一致的)

注意事项:Map接口中的集合都有两个泛型变量,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量的数 据类型可以相同,也可以不同。

1.4 Map接口中常用方法

  • 方法

    public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。

    public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。

    public V get(Object key) 根据指定的键,在Map集合中获取对应的值。

    public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。

    public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。

  • 代码
        // 创建HashMap对象
        HashMap<String,String> hash = new HashMap<>();
        // 【添加数据-public V put(K key, V value)】
        hash.put("郭靖","华筝");
        hash.put("郭靖","黄蓉"); // 会覆盖之前重复的键值对
        hash.put("杨过","小龙女");
        hash.put("张无忌","赵敏");
        hash.put("宋青书","周芷若");
        System.out.println(hash); // {杨过=小龙女, 宋青书=周芷若, 郭靖=黄蓉, 张无忌=赵敏}
        // 【移除数据-public V remove(Object key)】
        hash.remove("宋青书");
        System.out.println(hash); // {杨过=小龙女, 郭靖=黄蓉, 张无忌=赵敏}
        // 【根据指定的键获取对应的值-public V get(Object key)】
        String value = hash.get("郭靖");
        System.out.println(value); // 黄蓉
        // 【获取Map集合中所有的键存储到Set集合中-public Set<K> keySet()】
        Set<String> set = hash.keySet();
        Iterator<String> iterator = set.iterator();
        while ((iterator.hasNext())){
          String key = iterator.next();
          System.out.println(key + "-" + hash.get(key));
        }
        // 【获取Map集合中的Entry对象-public Set<Map.Entry<K,V>> entrySet()】
        // Map集合中存储了一组Entry对象,entry对象包装了每一对key/value
        // Entry对象可以通过getKey()方法获取键,通过getValue方法获取对应的值
        Set<Map.Entry<String,String>> set2 = hash.entrySet();
        for (Map.Entry<String,String> entry:set2) {
          System.out.println(entry.getKey() + ‘|‘+entry.getValue());
        }

1.5 Map集合中定义自定义类型的键值对

  • 注意事项:对应自定义类型的键的类型中需要重新hashCode和equals方法
  • 代码:
    //【执行类】
    public class Main {
      public static void main(String[] args) {
        // 存储一组学生信息,要求集合中不允许出现同名同年龄的键
        HashMap<Student,Integer> hash = new HashMap<>();
        hash.put(new Student("张三",18),10010);
        hash.put(new Student("张三",18),10086);
        hash.put(new Student("李四",17),10010);
        hash.put(new Student("王五",17),10010);
        System.out.println(hash.size()); // 3个
      }
    }
    //【学生类】
    public class Student {
      private String name;
      private int age;
      public Student() {}
      public Student(String name, int age) {
        this.name = name;
        this.age = age;
      }
      public String getName() {
        return name;
      }
      public void setName(String name) {
        this.name = name;
      }
      public int getAge() {
        return age;
      }
      public void setAge(int age) {
        this.age = age;
      }
      @Override
      public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                name.equals(student.name);
      }
      @Override
      public int hashCode() {
        return Objects.hash(name, age);
      }
    }

1.6 LinkedHashMap

  • 介绍:是HashMap的子类,存取数据是有序的。
  • 代码:
        LinkedHashMap<String,String> hash = new LinkedHashMap<>();
        hash.put("郭靖","黄蓉");
        hash.put("杨过","小龙女");
        hash.put("张无忌","赵敏");
        hash.put("宋青书","周芷若");
        System.out.println(hash);//{郭靖=黄蓉, 杨过=小龙女, 张无忌=赵敏, 宋青书=周芷若}

1.7 Map集合练习

  • 需求:计算一个字符串中每个字符出现次数。
  • 业务分析:
    • 接受用户输入的内容
    • 提取每一个字符并统计次数
    • 打印统计结果
  • 代码:
        // 1. 接受用户输入的内容
        String text = new Scanner(System.in).next();
        // 2. 创建Map集合key存储字符,value存储次数
        LinkedHashMap<Character,Integer> hash = new LinkedHashMap<>();
        // 3. 循环遍历字符串中的字符,并统计
        for(int i = 0; i < text.length();i++) {
          // 3.1 取出单个字符
          char ch = text.charAt(i);
          // 3.2 检测集合中是否存在这样的键
          boolean isHas = hash.containsKey(ch);
          // 3.3 若存在,则设置key的值次数加1
          if(isHas) {
            int count = hash.get(ch) + 1;
            hash.put(ch,count);
          }else {// 否则,则向集合中添加key并设置次数为1
            hash.put(ch,1);
          }
    
        }
        // 4.遍历并打印
        // 4.1 获取集合中的键
        Set<Character> set = hash.keySet();
        // 4.2 遍历
        for(Character ch:set){
          System.out.println(ch+":" + hash.get(ch));
        }

1.8 JDK9对集合添加的优化

  • 在创建少量元素的集合时,使用JDK9中提供的静态方法of添加更加合适
  • 注意事项:
    • of方法只能被接口List、Set、Map接口调用,不能用子类或实现类调用。
    • of方法初始化后的集合不能更改。
  • 代码:
        List<String> list = List.of("张三","李四","王五","赵六");
        Set<String> set = Set.of("张三","李四","王五","赵六");
        Map<String,Integer> map = Map.of("张三",10,"李四",12);
        System.out.println(list); // [张三, 李四, 王五, 赵六]
        System.out.println(set);  // [李四, 赵六, 张三, 王五]
        System.out.println(map);  // {张三=10, 李四=12}

1.9 HashTable

  • HashTable集合

    • 底层是线程是安全的,单线程,执行速度慢
    • 底层数据结构是哈希表
    • 之前学习的集合可以存储null键和null值,但是HashTable不可以
  • 代码:
        HashMap<String,Integer>  map = new HashMap<>();
        map.put(null,1);
        map.put("a",null);
        System.out.println(map);
        Hashtable<String,Integer> table = new Hashtable<>();
        table.put(null,1); // 报错NullPointerException
        table.put("a",null);
        System.out.println(table);

2. 模拟斗地主洗牌发牌

  • 需求:

    • 实现洗牌、发牌、看片、玩家牌排序(从小到大)的功能
  • 代码:
      public static void main(String[] args) {
        // 1. 定义Map集合用来装牌
        HashMap<Integer,String> map = new HashMap<>();
        // 2. 定义数组存放花色
        String[]colors={"♥","♠","♣","♦"};
        // 3. 定义数组存放牌数字
        String[]nums = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
        // 4. 定义List集合存放牌的索引
        ArrayList<Integer> listIndex = new ArrayList<>();
        // 5. 定义初始化牌的索引为0
        int index = 0;
        // 添加大小王
        map.put(index,"大王");
        listIndex.add(index);
        index++;
        map.put(index,"小王");
        listIndex.add(index);
        index++;
        // 6. 组装牌
        for (int i = 0; i < nums.length; i++) {
          for (int i1 = 0; i1 < colors.length; i1++) {
            listIndex.add(index);
            map.put( index,colors[i1]+nums[i]);
            index++;
          }
        }
        // 7.洗牌
        Collections.shuffle(listIndex);
        // 8. 定义玩家牌和底牌集合
        ArrayList<Integer> player01ListIndex = new ArrayList<>();
        ArrayList<Integer> player02ListIndex = new ArrayList<>();
        ArrayList<Integer> player03ListIndex = new ArrayList<>();
        ArrayList<Integer> diPai3ListIndex = new ArrayList<>();
        // 9. 发牌
        for (int i = 0; i < listIndex.size(); i++) {
          if(i>=51) {
            diPai3ListIndex.add(listIndex.get(i));
          }else if(i%3==0) {
            player01ListIndex.add(listIndex.get(i));
          }else if(i%3==1) {
            player02ListIndex.add(listIndex.get(i));
          }else if(i%3==2) {
            player03ListIndex.add(listIndex.get(i));
          }
        }
        // 10. 看牌
        show(map,player01ListIndex,"周星驰");
        show(map,player02ListIndex,"刘德华");
        show(map,player03ListIndex,"周润发");
        show(map,diPai3ListIndex,"底牌");
    
      }
      // 看牌方法
      public static void show(HashMap<Integer,String> map,ArrayList<Integer> listIndex,String name){
        System.out.println("================【"+name+"】===================");
        Collections.sort(listIndex);
        for (int i = 0; i < listIndex.size(); i++) {
          int key = listIndex.get(i);
          System.out.print("【"+map.get(key)+"】");
        }
        System.out.println("");
      }

原文地址:https://www.cnblogs.com/bruce1993/p/11830213.html

时间: 2024-07-31 16:20:34

Java基础集合篇03-Map集合的相关文章

Java基础学习篇---------String、集合的学习

一.String常用的方法: 二.集合学习 原文地址:https://www.cnblogs.com/liunx1109/p/9775588.html

java基础进阶篇(六)_HashTable------【java源码栈】

一.概述 ??前面介绍了HashMap的结构和原理,这里介绍个类似HashMap的结构Hashtable. ??HashTable 官方解释是HashMap的轻量级实现, 和HashMap一样,Hashtable 也是一个散列表,它存储的内容是键值对(key-value)映射. ??所以我们结合HashMap来介绍HashTable, 比较下两者的区别. ??HashTable 使用的很少, 它支持线程安全, 通过内部方法加上 synchronized 实现, 因此同步锁的密度太大了, 在实际情

java基础进阶篇(七)_LinkedHashMap------【java源码栈】

目录 一.概述 二.特点 三.应用场合 四.构造方法 1.参数为空 2.accessOrder 五.源码结构分析 六.常见问题 1.如何实现的元素有序? 2.如何保证顺序的正确以及同步 3.如何实现两种顺序(插入顺序或者访问顺序)? 4.为什么重写containsValue()而不重写containsKey()? 七.常用方法 一.概述 ??LinkedHashMap是HashMap的子类,关于HashMap可以看下前面的章节:java基础进阶篇 HashMap public class Lin

夯实Java基础(十九)——集合

1.前言 集合在Java中的地位想必大家都知道,不用多BB了.无论是在我们现在的学习中还是在今后的工作中,集合这样一个大家族都无处不在,无处不用.在前面讲到的数组也是一个小的容器,但是数组不是面向对象对象的,它存在明显的缺陷,而集合恰好弥补了数组带来的缺陷.集合比数组更加灵活.更加实用.而且不同的集合框架可用于不同的场景. 我们简单来比较一下数组和集合区别: 1.数组能存放基本数据类型和对象,而集合类中只能存放对象. 2.数组容量固定无法动态改变,集合类容量可以动态改变. 3.数组无法判断其中实

Java基础知识总结之类的集合

集合也叫作容器类.它的功能相当于一个容器. Java的集合(容器),它是用来”装对象的“. Set集合 Set集合几乎等同于Collection集合.它们的行为几乎一致. 遍历Set的两种方式: 1.用迭代器 2.用foreach循环 HashSet HashSet的存储机制: 1.当有元素加进来的时,HashSet会调用该对象的hashCode()方法,得到一个int值. 2.根据hashCode的()返回的int值,计算出它在HashSet中的存储位置(底层实际采用数组存储元素的索引,计算得

I学霸官方免费教程三十三:Java集合框架之Map集合

Map接口 Map集合采用键值对(key-value)的方式存储数据,其中键不可以重复.值可以重复. 常用类有HashMap.TreeMap和Properties HashMap类 假如,现在我有一个集合,集合中存储着一批WiFi的名称和密码,现在要求通过名称快速找到密码.这样的需求使用List集合实现起来非常困难,Java为我们提供了另一种形式的集合,可以很好的解决这样的问题.就是Map集合. 实例: package map.hashMap; import java.util.HashMap;

黑马程序员----java基础--JDK新特性和集合其他类

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.JDK1.5新特性 JDK升级的三大原因: (1).提高代码的复用性 (2).提高代码的安全性 (3).简化书写 1.泛型机制 JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. (1).泛型概念 泛型是根据数组的思想设计出来的,因为数组一旦建立成功就已经明确了数据类型,所以可根据数组思想给集合指定类型. 如:数组:int[] arr=new int[4]; 而集合的泛

键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:&quot;java&quot;,&quot;txt&quot;)作为key, 用个数作为value,放入到map集合中,遍历map集合

package cn.it.zuoye5; import java.io.File;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Scanner;import java.util.Set; /** 键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:"java","txt&qu

Java基础学习笔记十五 集合、迭代器、泛型

Collection 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数组既然都是容器,它们有啥区别呢? 数组的长度是固定的.集合的长度是可变的. 集合中存储的元素必须是引用类型数据 集合继承关系图 ArrayList的继承关系: 查看ArrayList类发现它继承了抽象类AbstractList同时实现接口List,而List接口又继承了Collection接口.Collec

Java集合类学习笔记(Map集合)

Map用于保存具有映射关系的数据,因此Map集合里保存着两组数据,一组用于保存Map的key,一组用于保存key所对应的value. Map的key不允许重复. HashMap和Hashtable都是Map接口的典型实现类,他们的关系类似于ArrayList和Vector的关系. HashMap和Hashtable的区别: Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现. Hashtable不允许使用null作为key和value,HashMap可以使用. Li