Java集合-Map集合体系概述

一、Map集合

1. Map集合概述

  • 为什么要有Map集合
    • 在Collection集合体系中,我们每次只能存储一个元素,但是遇到像学生的学号与姓名、身份证号与姓名等信息时,无法将两个信息联系起来,两个信息是分开存储的
  • Map集合的特点
    • Map集合是双列的,存储数据时是成对存储的,将其中一个作为键,另一个作为值,键与值是映射的关系。一个键只能对应一个值,也就是Map集合中键是唯一的,不能重复。
    • Map集合的数据结构只与键有关,与值无关
  • Map集合体系与Collection集合体系的不同
    • Map集合是双列的,元素成对存储;Collection集合是单列的,元素单个存储
    • Map集合的键不能重复,Collection集合的Set分支的元素是唯一的
    • Map集合的数据结构只针对键有效,与值无关;Collection集合的数据结构是针对值的

2. Map集合的功能

  • 添加功能
    • V put(K key,V value)
      • 向Map集合中添加一个键值对,如果添加的键集合中已有,则用新键的值覆盖旧键的值
      • 如果是第一次添加该键,则返回null,否则返回该键对应的旧值
  • 删除功能
    • void clear()
      • 删除集合中的所有键值对
    • V remove(Object key)
      • 删除指定键对应的键值对,并将值返回
    • boolean containsKey(Object key)
      • 判断集合是否包含指定的键
    • boolean containsValue(Object value)
      • 判断集合是否包含指定的值
    • boolean isEmpty()
      • 判断集合是否为空
  • 获取功能
    • Set<Map.Entry<K,V>> entrySet()
      • 将指定的集合拆分成键值对形式,并将键值对集合返回
    • V get(Object key)
      • 得到指定键对应的值
    • Set keySet()
      • 得到集合中所有键的集合
    • Collection values()
      • 得到集合中所有值的集合
  • 集合长度
    • int size()
      • 返回结合中键值对的数量

3. Map集合的两种遍历方式

  • 根据键找值
    • 先通过keySet方法得到集合中所有的键的集合
    • 遍历键的集合
    • 通过get方法找到键对应的值
  • 根据键值对找值
    • 先通过entrySet方法得到所有键值对的集合
    • 遍历键值对集合
    • 通过getKey方法得到键,通过getVaule方法得到值

二、Map集合体系下的三个集合

1. HashMap

  • 特点
    • 底层用哈希表实现
    • 允许插入null键与null值
    • 键值唯一,但存取顺序不一致
  • 注意
    • 如果键是自定义对象需要重写hashcode方法与equals方法

2. LinkedHashMap

  • 特点
    • 底层用使用哈希表与链表实现
    • 元素唯一,有序

3. TreeMap

  • 特点
    • 数据结构是红黑树
    • 元素唯一,且能按照给定的规则排序
    • 线程安全,但效率高
  • 练习
    • 统计字符串中每个字符出现的次数
public class StatiNums {//统计一个字符串中每个字符出现的次数

    public static void main(String[] args) {
        String str = "asdasdfasdadsasddsdasdaasdasd";
        HashMap<Character, Integer> hashMap = new HashMap<>();//定义HashMap集合

        char[] arrs = str.toCharArray();//将字符串转换为字符数组
        for (char ch : arrs) {
            hashMap.put(ch, (!hashMap.containsKey(ch)) ? 1 : (hashMap.get(ch) + 1));//当包含的时候给值加一
        }
        for (Character key : hashMap.keySet()) {//遍历哈希表,输出键和值
            System.out.println(key + ":" + hashMap.get(key));
        }
    }
}
//运行结果
//a:9
//s:9
//d:10
//f:1

4. 集合嵌套

  • 打印如下所示图形文字

    传智播客
    就业班
    王五 20
    赵六 20
    基础班
    张三 20
    李四 20

    • 代码示例
public class MyTest {//完成集合嵌套,并遍历

    public static void main(String[] args) {
        /**
         * 集合的嵌套
         */
        HashMap<String, ArrayList> totalHashMap = new HashMap<>();//定义HashMap集合
        ArrayList<Student> basicList = new ArrayList<>();//定义基础班列表
        basicList.add(new Student("张三", 20));
        basicList.add(new Student("李四", 20));
        ArrayList<Student> employeeList = new ArrayList<>();//定义就业班列表
        employeeList.add(new Student("王五", 20));
        employeeList.add(new Student("赵六", 20));
        totalHashMap.put("基础班", basicList);//将基础班列表存放进HashMap集合中
        totalHashMap.put("就业班", employeeList);//将就业班列表存放进HashMap集合中
        HashMap<String, HashMap> finalHashSet = new HashMap<>();//定义最终的集合
        finalHashSet.put("传智播客", totalHashMap);//将HashMap集合totalHashMap放进最终的集合中

        /**
         * 遍历方法一,使用键的集合遍历
         */
        for (String s : finalHashSet.keySet()) {//得到所有的键并遍历
            System.out.println(s);//打印键
            totalHashMap = finalHashSet.get(s);//得到键对应的值
            Set<String> keys = totalHashMap.keySet();//先得到所有的键,根据键去遍历集合,取出元素
            for (String key : keys) {
                System.out.println("\t"+key);
                ArrayList list = totalHashMap.get(key);
                for (Object o : list) {
                    Student stu = (Student) o;
                    System.out.println("\t\t" + stu.getName() + "\t\t" + stu.getAge());
                }
            }
        }
    }
}
//运行结果
//    传智播客
//            就业班
//                    王五		20
//                    赵六		20
//            基础班
//                    张三		20
//                    李四		20

5. HashMap与Hashtable的区别

  • HashMap线程不安全,效率高,允许null键与null值
  • Hashtable线程安全,效率低,不允许null键与null值

6. 例题:模拟斗地主进行洗牌发牌

  • 模拟斗地主进行洗牌发牌
    • public static void shuffle(List<?> list)
      • Collections类中的一个方法,能够将Collection集合体系中的元素随机打乱
    • 代码
public class PokerGame {//完成模拟斗地主案例

    public static void main(String[] args) {
        /**
         * 1.创建牌盒子与索引器
         */
        String[] color = {"♥", "♠", "♦", "♣"};
        String[] value = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
        int index = 1;
        HashMap<Integer, String> pokerBox = new HashMap<>();//牌盒子,存储54张牌
        ArrayList<Integer> indexs = new ArrayList<>();//索引,用来洗牌和发牌

        /**
         * 2.给牌盒子与索引器内填充数据
         */

        for (int j = 0; j < value.length; j++) {//外层是面值
            for (int i = 0; i < color.length; i++) {//里层是花色,将同一面值的牌放在一起
                pokerBox.put(index, color[i].concat(value[j]));
                indexs.add(index);
                index++;
            }
        }
        pokerBox.put(index, "🃏");
        indexs.add(index);
        pokerBox.put(++index, "🃏");
        indexs.add(index);//手动添加大小王

        /**
         * 3.洗牌
         */
        Collections.shuffle(indexs);

        /**
         * 4.发牌(平民1,平民2,地主,底牌)
         */
        TreeMap<Integer, String> 平民1 = new TreeMap<>();
        TreeMap<Integer, String> 平民2 = new TreeMap<>();
        TreeMap<Integer, String> 地主 = new TreeMap<>();
        TreeMap<Integer, String> 底牌 = new TreeMap<>();
        //indexs.get(i)是得到索引器中存储的索引
        //pokerBox.get(indexs.get(i))是得到牌盒子中对应索引的牌
        for (int i = 0; i < indexs.size(); i++) {
            if (i < 3) {
                底牌.put(indexs.get(i), pokerBox.get(indexs.get(i)));
            } else if (i % 3 == 0) {
                平民1.put(indexs.get(i), pokerBox.get(indexs.get(i)));
            } else if (i % 3 == 1) {
                平民2.put(indexs.get(i), pokerBox.get(indexs.get(i)));
            } else if (i % 3 == 2) {
                地主.put(indexs.get(i), pokerBox.get(indexs.get(i)));
            }
        }

        /**
         * 5.看牌
         */
        showPoker(地主, "地主");
        showPoker(平民1, "平民1");
        showPoker(平民2, "平民2");
        showPoker(底牌, "底牌");
    }

    /**
     * 得到传入TreeMap对象(玩家的牌)的值
     */
    private static void showPoker(TreeMap<Integer, String> map, String name) {
        System.out.print(name + ":\t");
        for (Integer key : map.keySet()) {
            System.out.print(map.get(key) + "\t");
        }
        System.out.println();
    }
}
//运行结果:
//地主:	♥A	♣A	♥2	♥3	♠4	♥5	♦5	♣5	♠6	♥7	♥9	♥J	♠J	♦J	♦Q	♥K	♠K	
//平民1:	♠A	♦2	♣2	♠3	♦3	♣3	♥6	♦6	♣6	♣7	♦8	♣8	♠9	♣10	♥Q	♣Q	♣K	
//平民2:	♦A	♠2	♥4	♦4	♣4	♠5	♦7	♥8	♠8	♦9	♣9	♥10	♣J	♠Q	♦K	🃏	🃏	
//底牌:	♠7	♠10	♦10	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值