Java基础----【Map】

Java基础:Map集合 Collection中的集合,元素是孤立存在的,向集合中存储元素采用一个个元素的方式存储。Map中的集合,元素是成对存在的。每个元素由键与值两部分组成,通过键可以找对所对应的值。Collection中的集合称为单列集合,Map中的集合称为双列集合。需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。HashMap:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。 阅读详情

主要内容

  • Map集合

第一章 Map集合

1.1 概述

现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即java.util.Map接口。

我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图。
Collection与Map

  • Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。
  • Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
  • Collection中的集合称为单列集合,Map中的集合称为双列集合。
  • 需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

1.2 Map常用子类

通过查看Map接口描述,看到Map有多个实现类,这里我们主要讲解常用的HashMap集合、LinkedHashMap集合。

  • HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
  • LinkedHashMap<K,V>:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

tips:Map接口中的集合都有两个泛型变量<K,V>,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量<K,V>的数据类型可以相同,也可以不同。

1.3 Map接口中的常用方法

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集合)。

Map接口的方法演示

import java.util.HashMap;

public class Test {
    public static void main(String[] args) {

        // HashMap 哈希映射表集合 :
        HashMap<String, Integer> map = new HashMap<>();

        // 1. 增加 put
        map.put("刘德华", 18);
        map.put("张学友", 22);
        map.put("黎明", 19);
        map.put("郭富城", 21);
        map.put("郭德刚", 30);
        map.put("王宝强", 10);

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

        // 2. 删除 remove
        Integer value = map.remove("郭德刚");
        System.out.println("value = " + value);

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

        // 3. 修改 put
        Integer value2 = map.put("王宝强", 20);
        System.out.println("value2 = " + value2);

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

        // 4. 查询 get
        Integer value3 = map.get("王宝强");
        System.out.println("value3 = " + value3);

        System.out.println("map = " + map);
    }
}

输出结果 :
map = {黎明=19, 郭富城=21, 张学友=22, 王宝强=10, 郭德刚=30, 刘德华=18}
value = 30
map = {黎明=19, 郭富城=21, 张学友=22, 王宝强=10, 刘德华=18}
value2 = 10
map = {黎明=19, 郭富城=21, 张学友=22, 王宝强=20, 刘德华=18}
value3 = 20
map = {黎明=19, 郭富城=21, 张学友=22, 王宝强=20, 刘德华=18}

tips:

使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;

若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。

1.4 Map集合遍历键找值方式

键找值方式:即通过元素中的键,获取键所对应的值

分析步骤:

  1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:keyset()
  2. 遍历键的Set集合,得到每一个键。
  3. 根据键,获取键所对应的值。方法提示:get(K key)

代码演示:

import java.util.HashMap;
import java.util.Set;

public class Test {
    public static void main(String[] args) {

        // HashMap 哈希映射表集合 :
        HashMap<String, Integer> map = new HashMap<>();

        // 添加元素
        map.put("刘德华", 18);
        map.put("张学友", 22);
        map.put("黎明", 19);
        map.put("郭富城", 21);
        map.put("郭德刚", 30);
        map.put("王宝强", 10);

        // 通过 `键找值` 的方法遍历 map 集合
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            Integer value = map.get(key);
            System.out.println(key + " = " + value);
        }
    }
}

输出结果 :
黎明 = 19
郭富城 = 21
张学友 = 22
王宝强 = 10
郭德刚 = 30
刘德华 = 18

1.5 Entry键值对对象

我们已经知道,Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在Map中是一一对应关系,这一对对象又称做Map中的一个Entry(项)。Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。

既然Entry表示了一对键和值,那么也同样提供了获取对应键和对应值的方法:

  • public K getKey():获取Entry对象中的键。
  • public V getValue():获取Entry对象中的值。

在Map集合中也提供了获取所有Entry对象的方法:

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

1.6 Map集合遍历键值对方式

键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。

操作步骤与图解:

  1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。方法提示:entrySet()。
  2. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
  3. 通过键值对(Entry)对象,获取Entry对象中的键与值。 方法提示:getkey() getValue()
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {

        // HashMap 哈希映射表集合 :
        HashMap<String, Integer> map = new HashMap<>();

        // 添加元素
        map.put("刘德华", 18);
        map.put("张学友", 22);
        map.put("黎明", 19);
        map.put("郭富城", 21);
        map.put("郭德刚", 30);
        map.put("王宝强", 10);

        // 通过获取 `键找对对象` 的方法遍历 map 集合
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
        for (Map.Entry<String, Integer> entry : entrySet) {
            // 1. getKey() 获取键值对对象的 key
            // 2. getValue() 获取键值对对象的 value
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key + " = " + value);
        }
    }
}

输出结果 :
黎明 = 19
郭富城 = 21
张学友 = 22
王宝强 = 10
郭德刚 = 30
刘德华 = 18

tips:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。

1.7 HashMap存储自定义类型键值

练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。

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

编写学生类:

import java.util.Objects;

public class Student {
    // 属性
    private String name;
    private int age;

    // 注意 : 如果自定义对象作为 `HashMap` 的 key, 那么该自定义对象所属的类就必须要重写 Object 类的 equals() 与 toString() 方法.
    @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 &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public Student() {
    }

    public Student(String name, int age) {

        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

编写测试类:

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {

        // HashMap 哈希映射表集合 :
        HashMap<Student, String> map = new HashMap<>();

        // 添加元素
        map.put(new Student("郭德刚", 30), "哈尔冰");
        map.put(new Student("王宝强", 10), "北京");
        map.put(new Student("刘德华", 18), "香港");
        map.put(new Student("张学友", 22), "上海");
        map.put(new Student("黎明", 17), "大陆");
        map.put(new Student("郭富城", 21), "台湾");
        map.put(new Student("郭德刚", 30), "哈尔冰");
        map.put(new Student("王宝强", 10), "北京");

        // 通过获取 `键找对对象` 的方法遍历 map 集合
        Set<Map.Entry<Student, String>> entrySet = map.entrySet();
        for (Map.Entry<Student, String> entry : entrySet) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + " = " + value);
        }
    }
}

输出结果 :
Student{name='黎明', age=17} = 大陆
Student{name='郭富城', age=21} = 台湾
Student{name='刘德华', age=18} = 香港
Student{name='王宝强', age=10} = 北京
Student{name='郭德刚', age=30} = 哈尔冰
Student{name='张学友', age=22} = 上海
  • 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
  • 如果要保证map中存放的key和取出的顺序一致,可以使用java.util.LinkedHashMap集合来存放。

1.8 LinkedHashMap

我们知道HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?

在HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {

        // HashMap 哈希映射表集合 :
        HashMap<Student, String> map = new LinkedHashMap<>();

        // 添加元素
        map.put(new Student("郭德刚", 30), "哈尔冰");
        map.put(new Student("王宝强", 10), "北京");
        map.put(new Student("刘德华", 18), "香港");
        map.put(new Student("张学友", 22), "上海");
        map.put(new Student("黎明", 17), "大陆");
        map.put(new Student("郭富城", 21), "台湾");
        map.put(new Student("郭德刚", 30), "哈尔冰");
        map.put(new Student("王宝强", 10), "北京");

        // 通过获取 `键找对对象` 的方法遍历 map 集合
        Set<Map.Entry<Student, String>> entrySet = map.entrySet();
        for (Map.Entry<Student, String> entry : entrySet) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + " = " + value);
        }
    }
}

结果:

Student{name='郭德刚', age=30} = 哈尔冰
Student{name='王宝强', age=10} = 北京
Student{name='刘德华', age=18} = 香港
Student{name='张学友', age=22} = 上海
Student{name='黎明', age=17} = 大陆
Student{name='郭富城', age=21} = 台湾

1.9 Map集合练习

需求:

计算一个字符串中每个字符出现次数。

分析:

  1. 获取一个字符串对象
  2. 创建一个Map集合,键代表字符,值代表次数。
  3. 遍历字符串得到每个字符。
  4. 判断Map中是否有该键。
  5. 如果没有,第一次出现,存储次数为1;如果有,则说明已经出现过,获取到对应的值进行++,再次存储。
  6. 打印最终结果

代码:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

public class HashMapTest {
    public static void main(String[] args) {

        // 需求 : 计算一个字符串中每个字符出现次数。

        // 1. 创建一个键盘录入对象
        Scanner sc = new Scanner(System.in);
        System.out.println("亲, 请输入一个字符串 :");
        String str = sc.nextLine();
        sc.close();

        // 2. 调用方法
        findCharacter(str);
    }

    // 定义方法, 查找每一个字符出现的次数
    public static void findCharacter(String str) {
        // 1. 定义一个 Map 集合, 用于统计每一个字符出现的次数
        HashMap<Character, Integer> map = new HashMap<>();

        // 2. 遍历字符串
        for (int i = 0; i < str.length(); i++) {
            // 3. 取出当前遍历的每一个字符
            char c = str.charAt(i);
            // 4. 判断 map 集合中是否包含 c 这个 key 值.
            if (map.containsKey(c)) {
                // 4.1 包含 (该键不是第一次出现)
                // 4.1.1 取出该键对应的值
                Integer value = map.get(c);
                // 4.1.2 将 value += 1, 重新存入到 map 集合中
                map.put(c, ++value);
            } else {
                // 4.2 不包含 (说明该键是第一次出现, 将值设置为 1 集合.
                map.put(c, 1);
            }
        }

        // 5. 查看集合中每一个字符对应出现的次数
        Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
        for (Map.Entry<Character, Integer> entry : entrySet) {
            Character key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key + " = " + value);
        }
    }
}

输出结果 :
亲, 请输入一个字符串 :
asdfaskdywerwibbnmzsdf
a = 2
b = 2
d = 3
e = 1
f = 2
i = 1
k = 1
m = 1
n = 1
r = 1
s = 3
w = 2
y = 1
z = 1

第二章 补充知识点

2.1 Debug追踪

使用IDEA的断点调试功能,查看程序的运行过程

  1. 在有效代码行,点击行号右边的空白区域,设置断点,程序执行到断点将停止,我们可以手动来运行程序
    Debug1

  2. 点击Debug运行模式
    Debug2

  3. 程序停止在断点上不再执行,而IDEA最下方打开了Debug调试窗口

Debug3
Debug4
4. Debug调试窗口介绍

Debug5
5. 快捷键F8,代码向下执行一行,第九行执行完毕,执行到第10行(第10行还未执行)
Debug6

  1. 切换到控制台面板,控制台显示 请录入一个字符串: 并且等待键盘录入
    Debug7

  2. 快捷键F8,程序继续向后执行,执行键盘录入操作,在控制台录入数据 ababcea
    Debug8
    回车之后效果:
    Debug9
    调试界面效果:
    Debug10

  3. 此时到达findChar方法,快捷键F7,进入方法findChar
    Debug11

  4. 快捷键F8 接续执行,创建了map对象,变量区域显示
    Debug12

  5. 快捷键F8 接续执行,进入到循环中,循环变量i为 0,F8再继续执行,就获取到变量c赋值为字符‘a’ 字节值97

Debug13

  1. 快捷键F8 接续执行,进入到判断语句中,因为该字符 不在Map集合键集中,再按F8执行,进入该判断中
    Debug14

  2. 快捷键F8 接续执行,循环结束,进入下次循环,此时map中已经添加一对儿元素
    Debug15

  3. 快捷键F8 接续执行,进入下次循环,再继续上面的操作,我们就可以看到代码每次是如何执行的了
    Debug16

  4. 如果不想继续debug,那么可以使用快捷键F9,程序正常执行到结束,程序结果在控制台显示
    Debug17

2.2 JDK9对集合添加的优化

通常,我们在代码中创建一个集合(例如,List 或 Set ),并直接用一些元素填充它。 实例化集合,几个 add方法调用,使得代码重复。

import java.util.*;

public class JDK9Of {
    public static void main(String[] args) {

        // 需求 : 往集合中添加元素
        // 1. 方式一 : add
        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        System.out.println("list = " + list);

        // 2. 方式二 : 集合工具类 addAll
        ArrayList<Integer> list2 = new ArrayList<>();
        Collections.addAll(list2, 10, 20, 30);
        Collections.addAll(list2, 40, 50);
        System.out.println("list2 = " + list2);

        // 3. 方式三 : JDK 9 出现了静态方法. of (List, Set, Map)
        // 注意 : 该集合返回的是不可变的集合. 不可以操作集合中的元素.
        List<Integer> list3 = List.of(10, 20, 30, 40, 50);
        // UnsupportedOperationException 不支持的操作异常.
        // list3.add(60);
        System.out.println("list3 = " + list3);

        // Set 接口
        Set<Integer> set = Set.of(10, 20, 30, 40, 50);
        System.out.println("set = " + set);

        // Map 接口
        Map<String, Integer> map = Map.of("Jack", 18, "Rose", 16, "Peter", 20);
        // map.put("Lindi", 20); UnsupportedOperationException 
        System.out.println("map = " + map);
    }
}

输出结果 :
list = [10, 20, 30, 40, 50]
list2 = [10, 20, 30, 40, 50]
list3 = [10, 20, 30, 40, 50]
set = [20, 40, 30, 50, 10]
map = {Jack=18, Rose=16, Peter=20}

Java 9,添加了几种集合工厂方法,更方便创建少量元素的集合、map实例。新的List、Set、Map的静态工厂方法可以更方便地创建集合的不可变实例。

需要注意以下两点:

1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和实现类并没有这个方法,比如 HashSet,ArrayList, Collection等等.

2:返回的集合是不可变的;

第三章 模拟斗地主洗牌发牌

3.1 案例介绍

按照斗地主的规则,完成洗牌发牌的动作。

具体规则:

  1. 组装54张扑克牌将
  2. 54张牌顺序打乱
  3. 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
  4. 查看三人各自手中的牌(按照牌的大小排序)、底牌

规则:手中扑克牌从小到大的摆放顺序:3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A, 小王, 大王

3.2 案例需求分析

  1. 准备牌:

完成数字与纸牌的映射关系:

使用双列Map(HashMap)集合,完成一个数字与字符串纸牌的对应关系(相当于一个字典)。

  1. 洗牌:

通过数字完成洗牌发牌

  1. 发牌:

将每个人以及底牌设计为ArrayList,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。

存放的过程中要求数字大小与斗地主规则的大小对应。

将代表不同纸牌的数字分配给不同的玩家与底牌。

  1. 看牌:

通过Map集合找到对应字符展示。

通过查询纸牌与数字的对应关系,由数字转成纸牌字符串再进行展示。

思路说明 :

public class PokersTest {
    public static void main(String[] args) {

        // 1. 准备一副 `扑克牌映射表`
        // 3♥ 3♦ 3♣ 3♠ 4♥ 4♦ 4♣ 4♠ 5♥ 5♦ 5♣ 5♠ ...... 2♥ 2♦ 2♣ 2♠ 小☺ 大☠         value
        //  0  1  2  3  4  5   6   7  8  9  10  11 ...... 48 49 50  51  52  53     key

        // 2. 准备一副 `数字牌`, 发给玩家的数字牌
        // [0  1  2  3  4  5   6   7  8  9  10  11 ... 53]

        // 3. 给数字牌洗牌 (Collections.shuffle)

        // 4. 给玩家发牌 (玩家手中的牌是数字牌, 注意: 这个数字牌是乱序的)

        // 5. 给玩家手中的数字排序实现排序. (Collections.sort)  玩家手中的数字牌就已经有序了.

        // 6. 根据玩家手中的数字牌去 `映射表` 中取出对应的字符串牌.
        // 因为玩家手中的数字牌排序, 因此从映射表中取出的字符串牌也是有序的.

        // 7. 查看每个玩家手中的排序.
    }
}

准备扑克牌方式一 :

        // 1.1 创建一个 `映射表对象` 集合
        HashMap<Integer, String> map = new HashMap<>();
        // 1.2 创建一个 `数字` 集合
        ArrayList<String> numbers = new ArrayList<>();
        Collections.addAll(numbers, "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2");
        System.out.println("numbers = " + numbers);
        // 1.3 创建一个 `花色` 集合
        ArrayList<String> colors = new ArrayList<>();
        Collections.addAll(colors, "♥", "♦", "♣", "♠");
        System.out.println("colors = " + colors);

说明 : 由于 numbers 和 colors 集合中的元素后期是不需要进行 增删改 操作, 因此, 我们有一种更加简单的方式实现, 使用 JDK9 提供的接口 List, Set, Map 静态方法 : of 就可以实现.

3.3 实现代码步骤

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

public class PokersTest {
    public static void main(String[] args) {

        // 1. 准备一副 `扑克牌映射表`
        // 3♦ 3♣ 3♥ 3♠ 4♦ 4♣ 4♥ 4♠ 5♦ 5♣ 5♥ 5♠ ... 2♦ 2♣ 2♥ 2♠ 小☺ 大☠    value
        // 0   1  2  3  4  5   6   7  8  9  10  11 ... 48 49 50 51  52   53      key
        // 1.1 准备一个 `扑克牌映射表`, 存储每一张扑克牌
        HashMap<Integer, String> map = new HashMap<>();
        // 1.2 准备一个 `数字` 集合
        /*
        ArrayList<String> numbers = new ArrayList<>();
        for (int i = 3; i <= 10; i++) {
            numbers.add(i + "");
        }
        Collections.addAll(numbers, "J", "Q", "K", "A", "2");
        System.out.println("numbers = " + numbers);
        */
        List<String> numbers = List.of("3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2");
        System.out.println("numbers = " + numbers);
        // 1.3 准备一个 `花色` 集合
        List<String> colors = List.of("♦", "♣", "♥", "♠");
        System.out.println("colors = " + colors);
        // 1.4 遍历 `数字 + 花色` 集合, 拼接每一张扑克牌
        int map_key = 0;
        for (String number : numbers) {
            for (String color : colors) {
                String poker = number + color;
                // 1.5 将拼接完成的 poker 存储到映射表中
                map.put(map_key++, poker);
            }
        }
        // 1.6 最后添加 `大小王`
        map.put(map_key++, "小☺");
        map.put(map_key, "大☠");

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

        // 2. 准备一副数字牌.
        // [0, 1, 2, 3, 4, 5, 6, ... 53]
        ArrayList<Integer> numbers_poker = new ArrayList<>();
        for (int i = 0; i < 54; i++) {
            numbers_poker.add(i);

        }

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

        // 3. 洗牌 (数字牌 Collections.shuffle)
        Collections.shuffle(numbers_poker);

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

        // 4.1 发牌 (数字牌 -> 三个玩家, 一个底牌, 获取到的都是数字)
        ArrayList<Integer> num_player1 = new ArrayList<>();
        ArrayList<Integer> num_player2 = new ArrayList<>();
        ArrayList<Integer> num_player3 = new ArrayList<>();
        ArrayList<Integer> num_base = new ArrayList<>();
        // 4.2 for i 循环, 取模判断
        for (int i = 0; i < numbers_poker.size(); i++) {
            // 4.3 取出当前遍历的数组
            Integer num_poker = numbers_poker.get(i);

            // 4.4 判断底牌
            if (i >= numbers_poker.size() - 3) {
                num_base.add(num_poker);
            } else {
                // 4.5 玩家
                if (i % 3 == 0) {
                    num_player1.add(num_poker);
                } else if (i % 3 == 1) {
                    num_player2.add(num_poker);
                } else {
                    num_player3.add(num_poker);
                }
            }
        }

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

        System.out.println("num_player1 = " + num_player1);
        System.out.println("num_player2 = " + num_player2);
        System.out.println("num_player3 = " + num_player3);
        System.out.println("num_base = " + num_base);

        // 5. 排序 (Integer类本身具备 `自然排序` Collections.sort)
        System.out.println("------------------------------------");
        Collections.sort(num_player1);
        Collections.sort(num_player2);
        Collections.sort(num_player3);
        Collections.sort(num_base);

        System.out.println("num_player1 = " + num_player1);
        System.out.println("num_player2 = " + num_player2);
        System.out.println("num_player3 = " + num_player3);
        System.out.println("num_base = " + num_base);

        // 6. 玩家可以根据手中的数字牌从映射表中取出对应的 `字符串牌`, 放入到字符串的扑克牌集合中
        // 6.1 创建三个玩家, 和一个底牌 (泛型为 String)
        ArrayList<String> str_player1 = new ArrayList<>();
        ArrayList<String> str_player2 = new ArrayList<>();
        ArrayList<String> str_player3 = new ArrayList<>();
        ArrayList<String> str_base = new ArrayList<>();

        // 6.2 根据玩家手中的数字牌. 从映射表取出对应的 `字符串牌`
        for (Integer key : num_player1) {
            String poker = map.get(key);
            str_player1.add(poker);
        }
        for (Integer key : num_player2) {
            String poker = map.get(key);
            str_player2.add(poker);
        }
        for (Integer key : num_player3) {
            String poker = map.get(key);
            str_player3.add(poker);
        }
        for (Integer key : num_base) {
            String poker = map.get(key);
            str_base.add(poker);
        }

        // 7. 看牌 (输出集合即可)
        System.out.println("张三丰 : " + str_player1);
        System.out.println("张无忌 : " + str_player2);
        System.out.println("张学友 : " + str_player3);
        System.out.println("底牌 : " + str_base);
    }
}

输出结果 :
numbers = [3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A, 2]
colors = [♦, ♣, ♥, ♠]
map = {0=3♦, 1=3♣, 2=3♥, 3=3♠, 4=4♦, 5=4♣, 6=4♥, 7=4♠, 8=5♦, 9=5♣, 10=5♥, 11=5♠, 12=6♦, 13=6♣, 14=6♥, 15=6♠, 16=7♦, 17=7♣, 18=7♥, 19=7♠, 20=8♦, 21=8♣, 22=8♥, 23=8♠, 24=9♦, 25=9♣, 26=9♥, 27=9♠, 28=10♦, 29=10♣, 30=10♥, 31=10♠, 32=J♦, 33=J♣, 34=J♥, 35=J♠, 36=Q♦, 37=Q♣, 38=Q♥, 39=Q♠, 40=K♦, 41=K♣, 42=K♥, 43=K♠, 44=A♦, 45=A♣, 46=A♥, 47=A♠, 48=2♦, 49=2♣, 50=2♥, 51=2♠, 52=小☺, 53=大☠}
numbers_poker = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53]
numbers_poker = [20, 36, 0, 27, 17, 30, 37, 46, 52, 1, 31, 18, 10, 28, 53, 6, 5, 38, 33, 14, 24, 21, 44, 25, 47, 50, 16, 39, 43, 45, 49, 29, 40, 35, 11, 41, 32, 19, 22, 15, 34, 7, 42, 8, 13, 4, 48, 9, 2, 3, 26, 51, 23, 12]
------------------------------------
num_player1 = [20, 27, 37, 1, 10, 6, 33, 21, 47, 39, 49, 35, 32, 15, 42, 4, 2]
num_player2 = [36, 17, 46, 31, 28, 5, 14, 44, 50, 43, 29, 11, 19, 34, 8, 48, 3]
num_player3 = [0, 30, 52, 18, 53, 38, 24, 25, 16, 45, 40, 41, 22, 7, 13, 9, 26]
num_base = [51, 23, 12]
------------------------------------
num_player1 = [1, 2, 4, 6, 10, 15, 20, 21, 27, 32, 33, 35, 37, 39, 42, 47, 49]
num_player2 = [3, 5, 8, 11, 14, 17, 19, 28, 29, 31, 34, 36, 43, 44, 46, 48, 50]
num_player3 = [0, 7, 9, 13, 16, 18, 22, 24, 25, 26, 30, 38, 40, 41, 45, 52, 53]
num_base = [12, 23, 51]
张三丰 : [3♣, 3♥, 4♦, 4♥, 5♥, 6♠, 8♦, 8♣, 9♠, J♦, J♣, J♠, Q♣, Q♠, K♥, A♠, 2♣]
张无忌 : [3♠, 4♣, 5♦, 5♠, 6♥, 7♣, 7♠, 10♦, 10♣, 10♠, J♥, Q♦, K♠, A♦, A♥, 2♦, 2♥]
张学友 : [3♦, 4♠, 5♣, 6♣, 7♦, 7♥, 8♥, 9♦, 9♣, 9♥, 10♥, Q♥, K♦, K♣, A♣, 小☺, 大☠]
底牌 : [6♦, 8♠, 2♠]
Java基础知识Map练习作业—01 Java基础知识Map作业—01 1.分析以下需求,并用代码实现: (1)定义一个学生类Student,包含属性:姓名(String name)、年龄(int age) (2)定义Map集合,用Student对象作为key,用字符串(此表示表示学生的住址)作为value (3)利用四种方式遍历Map集合中的内容,格式:key::value /*1.分析以下需求,并用代码实现: (1... 阅读详情

相关推荐

计组实验4 控制冒险与分支预测

目录前言实验内容背景知识分支预测技术⭐阻塞周期计算方法不开启 BTB开启 BTBpart 1 矩阵乘法与优化未开启 BTB 的分析开启 BTB 的分析part 2 设计代码使 BTB 无效part 3 循环展开优化矩阵乘法未开启 BTB开启 BTB结束语结论 前言 上一篇博客:计组实验3 mips冒险之流水线冒险 摸了半个月了。。。咕咕咕 今天来写计组实验 4 这个实验非常简单,就是有点难。 这个实验比较容易算错,或者是被模拟器出人意料的结果搞的神神叨叨的,所以今天来记录并且详细分析该实验。 注:请务必阅

AKGWSB 's blog 5668

(JAVA)Map集合的两种遍历方法

直接上代码! 方法一: import java.util.HashMap; import java.util.Map; import java.util.Set; //Map集合的遍历方法一 /* 思路:1.获取所有的键的集合 2.遍历键的集合,找出每个键对应的值 */ public class MapDemo4 { public static void main(String[] args) { //创建集合对象 Map<String, S

热爱技术,热爱生活! 815

从零搭建YOLOv2硬件加速器:基于PYNQ-Z2的Vivado HLS与Jupyter Notebook实战

本文详细介绍了如何从零搭建YOLOv2硬件加速器,基于PYNQ-Z2开发板,结合Vivado HLS与Jupyter Notebook实现高效目标检测。通过硬件加速,YOLOv2推理速度提升8倍,功耗降低80%。文章涵盖硬件准备、Vivado HLS工程配置、IP核集成、PYNQ部署及常见问题解决,为开发者提供完整实战指南。

weixin_29188997的博客 1008

map的4中创建方式

第一种 最常见的方式(新建Map对象) public class Demo{ private static final Map<String, String> myMap = new HashMap<String, String>(); myMap.put("a", "b"); myMap.put("c", "d"); } 1 2 3 4 5 第二种 java8新特性–双括号初始化 HashMap<String, String

qq_40250122的博客 5912

超详细MySQL 8.0安装与配置

MySQL的安装与配置 还不会安装MySQL的同学们,还不会配置MySQL的同学们,赶紧按照下面步骤操作起来,超详细安装步骤如下: 进入MySQL官网 1、点击download 2、点击MySQL Community Server 3、选好选项点击go to download page 4、点击download 5、点击no thanks,just start my download 6、选Server only,点击Next 7、点击Execute 8、点击

Turniper的博客 8756

Mac OS X 工具技巧:一文搞定个性化命令行窗口(iTerm2 + zsh + oh-my-zsh 配置Powerline风格)

本不想写这篇文章的,因为在Linux下已经配置过很多次,想着mac应该找篇文章一次就搞定了,结果还是踩坑,看了很多文章,不是某一点没不清楚,就是截图有问题或者命令有问题,官网又难得找等等……花了3个多小时才搞定,所以,还是来总结一篇文章就能够搞定的教程。 为什么要用zsh?用了这么多年的bash,不能说bash不好,不过当我用了zsh后发现,什么叫更好用。 配置过程稍微有点繁琐,但是你看过效果...

mickjoust的技术小屋 1万+

Map

day04 【Map】 主要内容 Map集合 教学目标 能够说出Map集合特点 使用Map集合添加方法保存数据 使用”键找值”的方式遍历Map集合 使用”键值对”的方式遍历Map集合 能够使用HashMap存储自定义键值对的数据 能够使用HashMap编写斗地主洗牌发牌案例 第一章 Map集合 1.1 概述 现实生活中,我...

qq_34272315的博客 535

Python实现高光谱图像生成与增强:从RGB到多光谱转换(附完整代码)

本文分享一个基于Python的实用工具,能够将普通RGB图像转换为模拟高光谱图像,并进一步生成增强的彩色可见图像。为了直观展示图像细节,程序通过对特定波段的组合,生成了一幅增强的 RGB 彩色图像。该函数的主要目标是将一张普通的 RGB 图像转换为包含多个波段的高光谱图像。通过该函数,我们能直观地看到高光谱图像经过波段组合后所得到的彩色图像效果。通过以上代码,我们可以实现对海量图像数据的自动化处理,极大地提升工作效率。已附在文中,欢迎下载测试!通过以上步骤,我们可以生成一幅包含多个光谱波段信息的图像。

m0_74824642的博客 3666

集合Map创建及方法

1.Map集合创建 import java.util.HashMap; import java.util.Map; public class Fire { public static void main(String[] args) { Map<String,Integer> nums=new HashMap<>(); } }...

SignalFire的博客 7671

定位分析RCU stall问题

在编译内核时打开或者在启动参数中增加这样统计信息是在采样周期中收集的。其中number行分别是发生stalled的cpu上的硬中断,软中断,和上下文的切换次数cputime行的前三列分别是硬中断,软中断和任务消耗的cpu时间,单位为ms.最后一个数字是统计的周期时间(ms).因为用户态的任务通常不会引起RCU CPU stalls,所以任务通常是内核任务,这也是为什么只统计system cpu的原因.

happyAnger6的专栏 1994

AOSP 8.0.0编译中的ANDROID_DATA缺失问题解决方案

在AOSP编译过程中,环境变量和路径设置的正确性至关重要。遇到相关的错误时,检查并修正环境配置通常是解决问题的关键。希望本文提供的分析和解决方案能帮助你顺利编译AOSP。

m0_74337424的博客 398

java基础——java集合map详解

Java Map 是一个存储键值对的接口,具有键唯一、值可重复的特性。主要实现类包括: HashMap:基于哈希表,无序高效,允许null键值 LinkedHashMap:保持插入顺序 TreeMap:基于红黑树,按键排序 Hashtable:线程安全但性能较低 ConcurrentHashMap:高并发优化的线程安全实现 Map提供put/get/remove等核心方法,支持快速查找(O(1)或O(log n))。不同实现类适用于不同场景,如HashMap适合缓存,TreeMap适合有序数据,Concur

likuoelie的博客 1714

基于YOLO26深度学习框架的文档表格识别系统的算法研究实现方法

本文研究了基于YOLO26深度学习框架的文档表格识别系统实现方法。系统采用YOLO26网络架构,通过数据预处理、模型训练、检测推理和表格分析四个模块实现高效表格识别。研究详细阐述了数据归一化、增强等技术处理,以及采用迁移学习策略优化模型训练过程。实验表明,该系统能有效识别多种表格结构并生成结构化数据,为文档自动化处理提供了可靠解决方案。

一键难忘的博客 972

Java基础之Map集合

Java基础之Map集合 Map集合是一种双列集合,存储形式为键值对的形式(Map集合中的键是唯一性的) 如:以学生的学号为键值,姓名为值. 创建对象格式: Map<String ,String> map = new HashMap<>(); map.put(“001”,“张三”); map.put(“002”,“李四”); ...

weixin_43239554的博客 181

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

JAVA基础之Map

昨天学习了Map集合、简单记录学习完了容器还得继续加油回顾之前的代码!!

柯南的博客 130

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Java基础学习Map

底层是由HashMap维护 底层结构 : 哈希表(jdk1.8之前 : 数组+链表 jdk1.8及之后 : 数组+链表+红黑树)3.Set entrySet() 返回此映射中包含的映射的Set视图。键值对的value,可重复,无序的 --- > Collection。2.Set keySet() 返回此映射中包含的键的Set视图。键值对的key的唯一的,去重的,无序的 --- > Set。键值对的集合| 映射的集合。

qq_52992141的博客 462

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java基础-List、Set、Map

List Set Map

Asssshzy的博客 307

java基础——Map

练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。注意,学生姓名相同并且年龄相同视为同一名学生。//构造方法 //get/set @Override public boolean equals(Object o) {} }//1,创建Hashmap集合对象。//2,添加元素。map . put(new Student("lisi" , 28) , "上海");

Flipped7777的博客 6818

Java基础——Map集合

1

CNNSU的博客 164

Java Map基础篇

Java Map基础篇

似霰的博客 1184

【Java 基础篇】Java Map 详解

Map接口是一个键值对的集合,它继承自Collection接口中的size()和isEmpty()等方法,同时还提供了根据键查找值的方法,以及添加、删除和更新键值对的方法。在Java中,Map接口有几个常见的实现类,每个实现类都具有不同的性能和用途。HashMap:基于哈希表实现,具有快速的查找和插入操作,适用于需要快速查找键值对的场景。TreeMap:基于红黑树实现,可以对键进行排序,并提供了一系列与排序相关的方法,适用于需要对键进行排序的场景。

繁依Fanyi的博客 4万+

Java基础:Map

Map

KaiSarH 448

Java基础语法之Map集合

学习目标: Map集合的特点; 使用Map集合添加方法保存数据; 两种遍历Map集合的方法:(“键找值”、“键值对”) 能够使用HashMap存储自定义键值对数据 能够使用HashMap编写斗地主洗牌发牌案例 Java中的java.util.Map<k,v>集合类用来存放映射(一一对应)关系的对象,它是一个双列集合。其中,键k是不能重复的,值v可以重复。 Collection<E...

WAH 548

Java基础 Map集合

主要内容 Map集合 教学目标 能够说出Map集合特点 使用Map集合添加方法保存数据 使用”键找值”的方式遍历Map集合 使用”键值对”的方式遍历Map集合 能够使用HashMap存储自定义键值对的数据 能够使用HashMap编写斗地主洗牌发牌案例 第一章 Map集合 1.1概述 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的...

kai46385076的专栏 9043

c++ map的存储结构_Java基础 Map集合

主要内容Map集合教学目标能够说出Map集合特点使用Map集合添加方法保存数据使用”键找值”的方式遍历Map集合使用”键值对”的方式遍历Map集合能够使用HashMap存储自定义键值对的数据能够使用HashMap编写斗地主洗牌发牌案例第一章 Map集合1.1概述现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Ja...

weixin_31714129的博客 2662
上一篇: Java基础----【List、Set、数据结构、Collections】
下一篇: Java基础----【异常、线程】
CoderBoom
博客等级 码龄8年 62粉丝 75原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值