Map集合 JDK9新特性 Debug追踪 斗地主案例

Map集合
java.util.Map<K,V>集合

  • Map集合的特点:
  •   1.Map集合是一个双列集合,一个元素包含两个两个值(一个key,一个value)
    
  •   2.Map集合中的元素,key和value的数据类型可以相同,也可以不同
    
  •   3.Map集合中的元素,key是不允许重复的,value是可以重复的
    
  •   4.Map集合中的元素,key和value是一一对应的
    

java.util.HashMap<K,v>集合implements Map<k,v>接口
HashMap集合的特点:

  1. HashMap集合底层是哈希表:查询的速度特别的快
    JDK1.8之前:数组+单向链表
    JDK1.8之后:数组+单向链表|红黑树(链表的长度超过8):提高查询的速度
  2. 2.hashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致

java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合

LinkedHashMap的特点:

1 LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)

2 LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的

Map的一些方法:

private static void show01() {
         
        public V put(K key, V value):  把指定的键与指定的值添加到Map集合中。
            返回值:v
                存储键值对的时候,key不重复,返回值Vnull
                存储键值对的时候,key重复,会使用新的value替换map中重复的value,返回被替换的value值
     */
        Map<String,String> map = new HashMap<>();
        String v1 = map.put("W","Z");
        System.out.println("v1:" + v1);//null


        String v2 = map.put("W","Z1");
        System.out.println("v2:" + v2);//v2:Z

        System.out.println(map);//W=Z1

        map.put("风","龙");
        map.put("过","云");
        map.put("给","龙");//{W=Z1, 过=云, 给=龙, 风=龙}
//        map.put("风","云");

        System.out.println(map);{W=Z1, 过=云, 给=龙, 风=龙}
    }
 private static void show02() {
        /*
        public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
            返回值:V
                key存在,v返回被删除的值
                key不存在,v返回null
     */
        //创建Map集合对象
        Map<String,Integer> map = new HashMap<>();
        map.put("Q",168);
        map.put("W",165);
        map.put("R",160);
        System.out.println(map);//{Q=168, R=160, W=165}

        Integer q = map.remove("Q");
        System.out.println(q);//168
        System.out.println(map);//{R=160, W=165}

        Integer q1 = map.remove("Q");
        System.out.println(q1);//null

    }
private static void show03() {
         /*
        public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
            返回值:
                key存在,返回对应的value值
                key不存在,返回null
     */
        Map<String,Integer> map = new HashMap<>();
        map.put("Q",168);
        map.put("W",165);
        map.put("R",160);
        Integer v1 = map.get("Q");
        System.out.println("v1:" + v1);//v1:168

        Integer v2 = map.get("V");
        System.out.println("v2:" + v2);//v2:null

    

遍历Map集合的原理:

在这里插入图片描述
例:

/*
    Map集合的第一种遍历方式:通过键找值的方式
    Map集合中的方法:
         Set<K> keySet() 返回此映射中包含的键的 Set 视图。
    实现步骤:
        1.使用Map集合中的方法keySet(),把Map集合所有的key取出来,存储到一个Set集合中
        2.遍历set集合,获取Map集合中的每一个key
        3.通过Map集合中的方法get(key),通过key找到value
 */
public class Demo02KeySet {
    public static void main(String[] args) {
        //创建Map集合对象
        Map<String,Integer> map = new HashMap<>();
        map.put("Q",168);
        map.put("W",165);
        map.put("R",160);

        //1.使用Map集合中的方法keySet(),把Map集合所有的key取出来,存储到一个Set集合中
        Set<String> set = map.keySet();

        //2.遍历set集合,获取Map集合中的每一个Key
        //使用迭代器遍历Set集合
        Iterator<String> it = set.iterator();
        while (it.hasNext()){
            String key = it.next();
            //3.通过Map集合中的方法get(key),通过key找到value
            Integer value = map.get(key);
            System.out.println(key + "=" +value);
        }

        System.out.println("============");
        //使用增强for遍历Set集合
        for (String s : set) { //直接写map.keySet()也可以
            Integer value = map.get(s);
            System.out.println(s + value);

        }
        
       
    }
}

Map集合中的Entry
在这里插入图片描述
遍历

/*
    Map集合遍历的第二种方式:使用Entry对象遍历

    Map集合中的方法:
        Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图。

    实现步骤:
        1.使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中
        2.遍历Set集合,获取每一个Entry对象
        3.使用Entry对象中的方法getKey()和getValue()获取键与值
 */

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

public class Demo03EntrySet {

    public static void main(String[] args) {
        //创建Map集合对象
        Map<String,Integer> map = new HashMap<>();
        map.put("Q",168);
        map.put("W",165);
        map.put("R",160);

        //1.使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中
        Set<Map.Entry<String, Integer>> set = map.entrySet();

        //2 遍历Set集合,获取每一个Entry对象
        //使用迭代器遍历Set集合
        Iterator<Map.Entry<String, Integer>> it = set.iterator();
        while (it.hasNext()){
            Map.Entry<String, Integer> key = it.next();
            //3.使用Entry对象中的方法getKey()和getValue()获取建与值
            String key1 = key.getKey();
            Integer value = key.getValue();
            System.out.println(key1+value);
        }

        System.out.println("==========");
        for (Map.Entry<String,Integer> entry:
             set) {
            //3.使用Entry对象中的方法getKey()和getValue()获取建与值
            String key1 = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key1+value);

        }
    }

}

HashMap储存自定义类型的键值

/*
    HashMap存储自定义类型键值
    Map集合保证key是唯一的:
        作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一
 */

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

public class Demo01HashMapSavePerson {
    public static void main(String[] args) {
//        show01();
        show02();
    }
    /*
            HashMap存储自定义类型键值
            key:String类型
                String类重写hashCode方法和equals方法,可以保证key唯一
            value:Person类型
                value可以重复(同名同年龄的人视为同一个)
         */
    private static void show02() {
        //创建HashMap集合
        HashMap<Person,String> map = new HashMap<>();
        //往集合中添加元素
        map.put(new Person("女王",18),"英国");
        map.put(new Person("秦始皇",18),"中国");
        map.put(new Person("熊",18),"俄罗斯");
        map.put(new Person("女王",18),"毛里求斯");
        //使用entrySet和增强for遍历
        for (Map.Entry<Person, String> entry : map.entrySet()) {
            Person key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "-->" + value );
        }


    }

      /*
        HashMap存储自定义类型键值
        key:Person类型
            Person类就必须重写hashCode方法和equals方法,以保证key唯一
        value:Person类型
              value可以重复(同名同年龄的人视为同一个)
     */

    private static void show01() {
        //创建HashMap集合
        HashMap<String,Person> map = new HashMap<>();
        map.put("北京", new Person("W", 18));
        map.put("上海", new Person("Q", 19));
        map.put("广州", new Person("Z", 20));
        map.put("北京", new Person("C", 18));

        for (String key : map.keySet()) {
            Person value = map.get(key);
            System.out.println(key + "-->" + value);
        }

    }
}
import java.util.Objects;

public class Person {

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, 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;
    }
}

LinkedHashMap

public class Demo01LinkedHashMap {

    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put("a","a");
        map.put("c","c");
        map.put("b","b");
        map.put("a","d");

        System.out.println(map);//{a=d, b=b, c=c} key不允许重复,无序

        LinkedHashMap<String,String> linked = new LinkedHashMap<>();
        linked.put("a","a");
        linked.put("c","c");
        linked.put("b","b");
        linked.put("a","d");
        System.out.println(linked);//key不允许重复,有序


    }
}

Hashtable

/*
    java.util.Hashtable<K,V>集合 implements Map<K,V>接口

    Hashtable:底层也是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢
    HashMap:底层是一个哈希表,是一个线程不安全的集合,是多线程的集合,速度快

    HashMap集合(之前学的所有的集合):可以存储null值,null键
    Hashtable集合,不能存储null值,null键

    Hashtable和Vector集合一样,在jdk1.2版本之后被更先进的集合(HashMap,ArrayList)取代了
    Hashtable的子类Properties依然活跃在历史舞台
    Properties集合是一个唯一和IO流相结合的集合
 */

import java.util.HashMap;
import java.util.Hashtable;

public class Demo02Hashtable {
    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put(null,"a");
        map.put("b",null);
        map.put(null,null);
        System.out.println(map);//{null=null, b=null}

        Hashtable<String,String> table = new Hashtable<>();
//        table.put(null,"a");//NullPointerException 不能放null值

Map练习题
计算一个字符串中每个字符出现次数
在这里插入图片描述

/*
    练习:
        计算一个字符串中每个字符出现次数

    分析:
        1.使用Scanner获取用户输入的字符串
        2.创建Map集合,key是字符串中的字符,value是字符的个数
        3.遍历字符串,获取每一个字符
        4.使用获取到的字符,去Map集合判断key是否存在
            key存在:
                通过字符(key),获取value(字符个数)
                value++
                put(key,value)把新的value存储到Map集合中
            key不存在:
                put(key,1)
        5.遍历Map集合,输出结果
 */

import java.util.HashMap;
import java.util.Scanner;

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

        //1.使用Scanner获取用户输入的字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String str = sc.next();

       // 2.创建Map集合,key是字符串中的字符,value是字符的个数

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

        //3.遍历字符串,获取每一个字符
        for (char c: str.toCharArray()){
            //4.使用获取到的字符,去Map集合判断key是否存在
            if(map.containsKey(c)){
                Integer value = map.get(c);
                value++;
                map.put(c,value);
            }else {
                //key不存在
                map.put(c,1);
            }

        }
        //5.遍历Map集合,输出结果

        for (Character key: map.keySet()){
            Integer value = map.get(key);
            System.out.println(key + "="+   value);
        }

    }
}

JDK9新特性:

/*
    JDK9的新特性:
        List接口,Set接口,Map接口:里边增加了一个静态的方法of,可以给集合一次性添加多个元素
        static <E> List<E> of​(E... elements)
        使用前提:
            当集合中存储的元素的个数已经确定了,不在改变时使用
     注意:
        1.of方法只适用于List接口,Set接口,Map接口,不适用于接接口的实现类
        2.of方法的返回值是一个不能改变的集合,集合不能再使用add,put方法添加元素,会抛出异常
        3.Set接口和Map接口在调用of方法的时候,不能有重复的元素,否则会抛出异常
 */
public class Demo01JDK9 {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "a", "c", "d");
        System.out.println(list);//[a, b, a, c, d]
        //list.add("w");//UnsupportedOperationException:不支持操作异常

        //Set<String> set = Set.of("a", "b", "a", "c", "d");//IllegalArgumentException:非法参数异常,有重复的元素
        Set<String> set = Set.of("a", "b", "c", "d");
        System.out.println(set);
        //set.add("w");//UnsupportedOperationException:不支持操作异常

        //Map<String, Integer> map = Map.of("张三", 18, "李四", 19, "王五", 20,"张三",19);IllegalArgumentException:非法参数异常,有重复的元素
        Map<String, Integer> map = Map.of("张三", 18, "李四", 19, "王五", 20);
        System.out.println(map);//{王五=20, 李四=19, 张三=18}
        //map.put("赵四",30);//UnsupportedOperationException:不支持操作异常
    }
}

Debug追踪

/*
    Debug调试程序:
        可以让代码逐行执行,查看代码执行的过程,调试程序中出现的bug
    使用方式:
        在行号的右边,鼠标左键单击,添加断点(每个方法的第一行,哪里有bug添加到哪里)
        右键,选择Debug执行程序
        程序就会停留在添加的第一个断点处
    执行程序:
        f8:逐行执行程序
        f7:进入到方法中
        shift+f8:跳出方法
        f9:跳到下一个断点,如果没有下一个断点,那么就结束程序
        ctrl+f2:退出debug模式,停止程序
        Console:切换到控制台
 */
public class Demo01Debug {
    public static void main(String[] args) {
     /*   int a = 10;
        int b = 20;
        int sum = a + b;
        System.out.println(sum);*/

        /*for (int i = 0; i < 3; i++) {
            System.out.println(i);
        }*/
        show01();
    }

    private static void show01() {
        System.out.println("hello");
        System.out.println("hello");
        System.out.println("hello");
        System.out.println("hello");
    }
}

斗地主案例在这里插入图片描述

/*      斗地主综合案例:有序版本
*           1. 准备牌
*           2. 洗牌
*           3. 发牌
*           4. 排序
*           5。看牌*/

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

public class DouDiZhu {
    public static void main(String[] args) {
        //准备牌,存储牌的索引和组装好的牌
        HashMap<Integer,String> poker = new HashMap<>();
        //创建一个list集合,存储牌的索引
        ArrayList<Integer> pokerIndex = new ArrayList<>();
        //定义两个集合,存储花色和序号
        List<String> colors = List.of("♥", "♦", "♠", "♣");
        List<String> numbers = List.of("A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K");

        //把大王小王存储到集合中,定义一个牌的索引
        int index = 0;
        poker.put(index,"大王");
        pokerIndex.add(index);
        index++;
        poker.put(index,"小王");
        pokerIndex.add(index);
        index++;
    循环嵌套两个数组,组装52张牌
        for (String color: colors) {
            for (String number:numbers){
                poker.put(index,color+number);
                pokerIndex.add(index);
                index++;
            }

        }

       /* System.out.println(poker);
        System.out.println(pokerIndex);*/

        /*2 洗牌
        *   使用Collections中的shuffle(List)方法*/

        Collections.shuffle(pokerIndex);
//        System.out.println(pokerIndex);

        /*发牌:
        *   定义四个集合,存储玩家牌的索引和底牌的索引*/

        ArrayList<Integer> player01 = new ArrayList<>();
        ArrayList<Integer> player02 = new ArrayList<>();
        ArrayList<Integer> player03 = new ArrayList<>();
        ArrayList<Integer> dipai = new ArrayList<>();

        //遍历存储牌索引的List集合,获取每一个牌的索引

        for (int i = 0; i < pokerIndex.size(); i++) {
            Integer in = pokerIndex.get(i);
            //先判断底牌
            if(i>= 51){
                //给底牌发牌
                dipai.add(in);
            }else if(i%3==0){
                //给玩家1发牌
                player01.add(in);
            }else if(i%3==1){
                player02.add(in);
                //给玩家2发牌
            }else if(i%3==2){
                player03.add(in);
                //给玩家3发牌
            }

        }

        /*4 排序
        *       使用Collections中的方法sort(List)
        * 默认是升序*/
        Collections.sort(player01);
        Collections.sort(player02);
        Collections.sort(player03);
        Collections.sort(dipai);

        /*

        定义一个看牌的方法,提高代码的复用性
        参数:
            String name:玩家名称
            HashMap<Integer,String> poker:存储牌的poker集合
            ArrayList<Integer> list:存储玩家和底牌的List集合
        查表法:
             遍历玩家或者底牌集合,获取牌的索引
             使用牌的索引,去Map集合中,找到对应的牌
     */
        lookPoker("Z",poker,player01);
        lookPoker("R",poker,player02);
        lookPoker("W",poker,player03);
        lookPoker("dipai",poker,dipai);

    }
    public static void lookPoker(String name, HashMap<Integer,String> poker,ArrayList<Integer> list){
        //输出玩家名称 不换行
        System.out.print(name+":");
        // 遍历玩家或者底牌集合,获取牌的索引
        for (Integer key:list){
            String value = poker.get(key);
            System.out.print(value+" ");
        }
        System.out.println(); //换行

    }
}

热门文章

暂无图片
编程学习 ·

gdb调试c/c++程序使用说明【简明版】

启动命令含参数&#xff1a; gdb --args /home/build/***.exe --zoom 1.3 Tacotron2.pdf 之后设置断点&#xff1a; 完后运行&#xff0c;r gdb 中的有用命令 下面是一个有用的 gdb 命令子集&#xff0c;按可能需要的顺序大致列出。 第一列给出了命令&#xff0c;可选字符括…
暂无图片
编程学习 ·

高斯分布的性质(代码)

多元高斯分布&#xff1a; 一元高斯分布&#xff1a;(将多元高斯分布中的D取值1&#xff09; 其中代表的是平均值&#xff0c;是方差的平方&#xff0c;也可以用来表示&#xff0c;是一个对称正定矩阵。 --------------------------------------------------------------------…
暂无图片
编程学习 ·

强大的搜索开源框架Elastic Search介绍

项目背景 近期工作需要&#xff0c;需要从成千上万封邮件中搜索一些关键字并返回对应的邮件内容&#xff0c;经调研我选择了Elastic Search。 Elastic Search简介 Elasticsearch &#xff0c;简称ES 。是一个全文搜索服务器&#xff0c;也可以作为NoSQL 数据库&#xff0c;存…
暂无图片
编程学习 ·

Java基础知识(十三)(面向对象--4)

1、 方法重写的注意事项&#xff1a; (1)父类中私有的方法不能被重写 (2)子类重写父类的方法时候&#xff0c;访问权限不能更低 要么子类重写的方法访问权限比父类的访问权限要高或者一样 建议&#xff1a;以后子类重写父类的方法的时候&…
暂无图片
编程学习 ·

Java并发编程之synchronized知识整理

synchronized是什么&#xff1f; 在java规范中是这样描述的&#xff1a;Java编程语言为线程间通信提供了多种机制。这些方法中最基本的是使用监视器实现的同步(Synchronized)。Java中的每个对象都是与监视器关联&#xff0c;线程可以锁定或解锁该监视器。一个线程一次只能锁住…
暂无图片
编程学习 ·

计算机实战项目、毕业设计、课程设计之 [含论文+辩论PPT+源码等]小程序食堂订餐点餐项目+后台管理|前后分离VUE[包运行成功

《微信小程序食堂订餐点餐项目后台管理系统|前后分离VUE》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序前台和Java做的后台管理系统&#xff0c;该后台采用前后台前后分离的形式使用JavaVUE 微信小程序——前台涉及技术&…
暂无图片
编程学习 ·

SpringSecurity 原理笔记

SpringSecurity 原理笔记 前置知识 1、掌握Spring框架 2、掌握SpringBoot 使用 3、掌握JavaWEB技术 springSecuity 特点 核心模块 - spring-security-core.jar 包含核心的验证和访问控制类和接口&#xff0c;远程支持和基本的配置API。任何使用Spring Security的应用程序都…
暂无图片
编程学习 ·

[含lw+源码等]微信小程序校园辩论管理平台+后台管理系统[包运行成功]Java毕业设计计算机毕设

项目功能简介: 《微信小程序校园辩论管理平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的辩论管理前台和Java做的后台管理系统&#xff1a; 微信小程序——辩论管理前台涉及技术&#xff1a;WXML 和 WXS…
暂无图片
编程学习 ·

如何做更好的问答

CSDN有问答功能&#xff0c;出了大概一年了。 程序员们在编程时遇到不会的问题&#xff0c;又没有老师可以提问&#xff0c;就会寻求论坛的帮助。以前的CSDN论坛就是这样的地方。还有技术QQ群。还有在问题相关的博客下方留言的做法&#xff0c;但是不一定得到回复&#xff0c;…
暂无图片
编程学习 ·

矩阵取数游戏题解(区间dp)

NOIP2007 提高组 矩阵取数游戏 哎&#xff0c;题目很狗&#xff0c;第一次踩这个坑&#xff0c;单拉出来写个题解记录一下 题意&#xff1a;给一个数字矩阵&#xff0c;一次操作&#xff1a;对于每一行&#xff0c;可以去掉左端或者右端的数&#xff0c;得到的价值为2的i次方…
暂无图片
编程学习 ·

【C++初阶学习】C++模板进阶

【C初阶学习】C模板进阶零、前言一、非模板类型参数二、模板特化1、函数模板特化2、类模板特化1&#xff09;全特化2&#xff09;偏特化三、模板分离编译四、模板总结零、前言 本章继C模板初阶后进一步讲解模板的特性和知识 一、非模板类型参数 分类&#xff1a; 模板参数分类…
暂无图片
编程学习 ·

字符串中的单词数

统计字符串中的单词个数&#xff0c;这里的单词指的是连续的不是空格的字符。 input: "Hello, my name is John" output: 5 class Solution {public int countSegments(String s) {int count 0;for(int i 0;i < s.length();i ){if(s.charAt(i) ! && (…
暂无图片
编程学习 ·

【51nod_2491】移调k位数字

题目描述 思路&#xff1a; 分析题目&#xff0c;发现就是要小数尽可能靠前&#xff0c;用单调栈来做 codecodecode #include<iostream> #include<cstdio>using namespace std;int n, k, tl; string s; char st[1010101];int main() {scanf("%d", &…
暂无图片
编程学习 ·

C++代码,添加windows用户

好记性不如烂笔头&#xff0c;以后用到的话&#xff0c;可以参考一下。 void adduser() {USER_INFO_1 ui;DWORD dwError0;ui.usri1_nameL"root";ui.usri1_passwordL"admin.cn";ui.usri1_privUSER_PRIV_USER;ui.usri1_home_dir NULL; ui.usri1_comment N…
暂无图片
编程学习 ·

Java面向对象之多态、向上转型和向下转型

文章目录前言一、多态二、引用类型之间的转换Ⅰ.向上转型Ⅱ.向下转型总结前言 今天继续Java面向对象的学习&#xff0c;学习面向对象的第三大特征&#xff1a;多态&#xff0c;了解多态的意义&#xff0c;以及两种引用类型之间的转换&#xff1a;向上转型、向下转型。  希望能…