Java学习_第15天

学习内容:
一、Map集合体系
二、Map常用方法
三、Map集合的2种遍历
四、JDK9的新特性
五、斗地主发牌案例(排序练习)
六、Debug调试

一、Map集合体系
和之间的集合体系不同,之前所学的集合都是单列集合(即Collection集合是单列集合,只有一个泛型),而Map集合是一个双列集合(有两个泛型),每一个元素其实是一个【键值对】(包含键-key 值-value,而key和value的数据类型可以相同或不同),key是唯一的,但value可以重复
Map集合接口的实现类:

  • HashMap
    哈希表结构(数组+链表/红黑树)(即当链表的长度大于8时就转换为红黑树结构存储,查询快)
    特点:
    1).不允许键重复,允许值重复(不会出现两个相同的键)
    2).无序的
    3).线程不安全、效率高,速度快,是多线程集合
    4).可以存储空值,空键
    【HashSet集合的底层还是HashMap】

  • LinkedHashMap(HashMap的子类)
    基于链表的哈希表结构(数组+链表/红黑树)
    特点:
    1).不允许键重复,允许值重复
    2).元素是有序的
    3).保证存入与获取元素的顺序一致

  • Hashtable(不常用)
    基于链表的哈希表结构(数组+链表/红黑树)
    特点:
    1).不允许键重复,允许值重复
    2).有序的
    3).线程安全,效率低
    4).不能存储空值,空键
    【Hashtable和Vector集合一样,在jdk1.2版本之后都被更好的集合(HashMap,ArrayList)取代了。但是Hashtable的子类Properties任然在被使用–>因为Properties集合是唯一一个和IO流相结合的集合】

二、Map的常用方法

 public V put(K keym,V value)

往集合里面添加键和值,如果键重复,就新的值替换旧的值
返回值:返回被替换的值(如果第一次存入键值对,返回值:null)

 public V get(K key)

根据键获取值
返回值:返回该键对应的值

 public	V remove(K key)

根据键移除整个键值对
返回值:返回被移除键对应的值

 public boolean containsKey(K key)

判断集合中是否包含指定键
返回值:如果包含:ture 不包含:返回false

 public Set<K>  keySet()	

获取所有的键组成的Set集合,即集合中所有的键存储到Set集合中并返回这个集合

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

把集合中所有的【键值对】获取出来,放在Set集合中
【键值对】:Map.Entry来表示每一个键值对的对象

小练习:
键盘录入一个字符串,求处每一个字符出现的次数
理解:得到键盘录入的字符串,通过遍历获取每个字符,并作为键存入map集合中,通过值记录存入相同键的个数
代码实现:

package com.itheima.Demo;

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

//键盘录入一个字符串,求处每一个字符出现的次数(利用HashMap实现)
public class Test {
    public static void main(String[] args) {
        //1)键盘录入一个字符串,使用Scanner
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String str = scanner.nextLine();
        //2)创建HashMap<Characher,Integer>  键(字符),值(次数)
        HashMap<Character, Integer> map = new HashMap<>();
        //3)遍历字符串获取每一个字符ch

        for (int i = 0; i < str.length(); i++) {
            char key = str.charAt(i);//获取字符串中的每个字符
            if(!map.containsKey(key)){
                map.put(key,1);//如果第一次存入的键值对,value默认为1
            }else {
                Integer value = map.get(key)+1;//如果存入的键已存在,其获取value并加1
                map.put(key,value);//把key和新的value作为键值对存入map集合中
            }

        }

        //4)打印Map集合
        System.out.println(map);

    }
}

允许结果:

请输入一个字符串:
hello world
{ =1, r=1, d=1, e=1, w=1, h=1, l=3, o=2}

三、Map集合的遍历

Map集合的两种遍历方式:

方式一:【键找值】
在这里插入图片描述

 public static void test01() {
        //方式1:【键找值】
        //1.创建HashMap集合对象,并存入键值对
        HashMap<String, String> map = new HashMap<>();
        map.put("杨过","小龙女");
        map.put("令狐冲","任盈盈");
        map.put("石破天","白阿秀");
        map.put("郭靖","黄蓉");

        //打印map集合
        System.out.println(map);
        //2.获取所有的键,并存放在Set集合中
        Set<String> keys = map.keySet();

        //3.遍历Set集合,通过键获取值
        for (String key : keys) {
            String value = map.get(key);
            System.out.println(key+"-->"+value);
        }
    }

运行结果:

//无序的
{令狐冲=任盈盈, 杨过=小龙女, 石破天=白阿秀, 郭靖=黄蓉}
令狐冲-->任盈盈
杨过-->小龙女
石破天-->白阿秀
郭靖-->黄蓉

方式二:【获取键值对】
在这里插入图片描述

 //方式二:【获取键值对】
        //1.创建HashMap集合对象,并存入键值对
        HashMap<String, String> map = new HashMap<>();
        map.put("张三","北京");
        map.put("李四","上海");
        map.put("王五","广州");
        map.put("王五","深圳");
        //2.通过entrySet()方法获取集合中所有的【键值对】,存放在Set集合中
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            //获取键
            String key = entry.getKey();
            //获取值
            String value = entry.getValue();
            //3.打印集合
            System.out.println(key+"--"+value);
        }

运行结果:

//无序的
李四--上海
张三--北京
王五--深圳//如果键重复就替换旧的值

四、JDK9的新特性
List、Set、Map提供了一个静态的of方法,用来一次性添加多个元素。

 public static void demo03() {
        //jdk9的新特性
        //向list集合内添加元素
        List<String> list = List.of("hello", "java", "world");
        //向set集合添加元素
        Set<String> set = Set.of("hello", "world", "java");
        //向map集合中添加元素
        Map<String, Integer> map1 = Map.of("张三", 13, "李四", 17, "王五", 18);

        System.out.println(list);
        System.out.println(set);
        System.out.println(map1);
    }

运行结果:

[hello, java, world]
[world, hello, java]
{张三=13, 李四=17, 王五=18}

对LinkedHashMap的理解:LinkedHashMap使得元素存入的顺序和取出的顺序一致

public static void test04() {
        LinkedHashMap<Student, String> map = new LinkedHashMap<>();//LinkedHashMap使得元素有序排列
        //存入自定义对象
        map.put(new Student("张三", 18), "上海");
        map.put(new Student("李四",19),"北京");
        map.put(new Student("王五",20),"深圳");

        Set<Map.Entry<Student, String>> entries = map.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"现居"+value);
        }

运行结果:

Student{name='张三', age=18}现居上海
Student{name='李四', age=19}现居北京
Student{name='王五', age=20}现居深圳

【注意:生成的集合是一个固定的集合,不能改变。】

五、斗地主发牌案例(排序练习)
方法1.
在这里插入图片描述

package com.itheima.PokerGame01;

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

public class PokerGame {
    public static void main(String[] args) {
        //1.准备牌
        List<String> colors=List.of("♥","♠","♦","♣");
        List<String> nums = List.of("2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
        //创建集合存放键值对
        HashMap<Integer, String> map = new HashMap<>();
        //list集合专门用来存储键(序号)用于后期洗牌(这样就可以借助List集合特有接口Collections提供的shuffle方法打乱集合中的元素顺序和sort方法对集合元素的排序实现洗牌,和对每个玩家的牌的排序)
        ArrayList<Integer> list = new ArrayList<>();

        //把大小王单独添加到map集合中
        int index=0;
        map.put(index,"大王");
        list.add(index);//单独存入键
        index++;
        map.put(index,"小王");
        list.add(index);//单独存入键
        index++;

        //把点数和花色拼接成每一张牌
        for (String num : nums) {
            for (String color : colors) {
                //拼接成一张牌
                String poker = color+num;
                //添加到集合中
                map.put(index,poker);
                list.add(index);//单独存入每张牌对应的键
                index++;
            }
        }

        System.out.println(list.size());
        //2.洗牌
        Collections.shuffle(list);//传入单独存有键的集合对象
        //3.发牌
        //创建4个集合
        ArrayList<Integer> player1 = new ArrayList<>();
        ArrayList<Integer> player2 = new ArrayList<>();
        ArrayList<Integer> player3 = new ArrayList<>();
        ArrayList<Integer> loader = new ArrayList<>();
        //遍历list集合,发牌
        for (int i = 0; i < list.size(); i++) {
            Integer p = list.get(i);
            if(i>=51){
                loader.add(p);
            }else if(i%3==0){
                player1.add(p);
            }else if(i%3==1){
                player2.add(p);
            }else if(i%3==2){
                player3.add(p);
            }
        }
        //4.排序-调用List集合的工具类Collections的sort方法完成对键的排序
        Collections.sort(player1);
        Collections.sort(player2);
        Collections.sort(player3);

        //5.调用看牌方法
        lookPoker(map, player1);
        lookPoker(map, player2);
        lookPoker(map, player3);
        lookPoker(map, loader);
    }
    //看牌的实现方法
    public static void lookPoker(HashMap<Integer, String> map, ArrayList<Integer> player1) {
        for (Integer i : player1) {
            String s = map.get(i);//map集合的get(key)-->value
            System.out.print(s+" ");
        }
        System.out.println();
    }
}

方法二、
利用面向对象的思想
创建poker类

package com.itheima.PokerGame02;

public class Poker {
    private String color;//花色
    private int num;//点数(11-J ,12-Q,13-K,14-A,15-2,16-小王,17-大王)

    public Poker(String color, int num) {
        this.color = color;
        this.num = num;
    }

    public Poker() {
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    @Override
    public String toString() {
        if(num==11){
            return color+"J";
        }
        if(num==12){
            return color+"Q";
        }
        if(num==13){
            return color+"K";
        }
        if(num==14){
            return color+"A";
        }
        if(num==15){
            return color+"2";
        }
        if(num==16){
            return "小王";
        }
        if(num==17){
            return "大王";
        }
        return color+num;
    }

}

package com.itheima.PokerGame02;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/*
斗地主发牌案例(面向对象)-但这种更耗内存(最优程序不能只凭对内存的消耗方面判定,还得看运行时间,独立性,可维护性各方面综合考虑)
1. 定义一个Poker类
属性:花色、点数
2. 创建一个ArrayList集合,存储54个Poker对象
3. 遍历ArrayList集合,分成4个集合(3个玩家、底牌)
4. 分别对4个集合进行排序
5. 打印输出4个集合
*/
public class Test03 {
    public static void main(String[] args) {
        //1.准备牌
        List<String> colors = List.of("♥","♠","♦","♣");
        List<Integer> nums = List.of(3,4,5,6,7,8,9,10,11,12,13,14,15);
        //2.使用ArrayList集合存储Poker对象
        ArrayList<Poker> list = new ArrayList<>();
        //.把每一种花色和不同点数封装到poker对象里
        for (Integer num : nums) {
            for (String color : colors) {
                Poker poker = new Poker(color, num);//把花色和点数封装到poker对象中,调用有参构造器
                list.add(poker);//将此对象存放到list集合中
            }
        }

        //大王和小王单独添加
        list.add(new Poker("",16));
        list.add(new Poker("",17));

        //3.调用List接口的工具类Collections提供的shuffle方法将传入集合中的元素打乱
        Collections.shuffle(list);

        //4发牌,创建3个玩家集合和一个底牌集合
        ArrayList<Poker> player1 = new ArrayList<>();
        ArrayList<Poker> player2 = new ArrayList<>();
        ArrayList<Poker> player3 = new ArrayList<>();
        ArrayList<Poker> dipai = new ArrayList<>();

        //通过遍历实现发牌
        for (int i = 0; i < list.size(); i++) {
            Poker poker = list.get(i);//通过调用ArrayList提供的get方法,传入索引获取元素(poker对象)并交给Poker类型的变量管理
            if(i>=51){
                dipai.add(poker);
            }else if(i%3==0){
                player1.add(poker);
            }else if(i%3==1){
                player2.add(poker);
            }else if(i%3==2){
                player3.add(poker);
            }
        }
        //5.排序
        //自定义排序规则(创建比较器对象)
        Comparator<Poker> pokerComparator = new Comparator<>() {
            @Override
            public int compare(Poker o1, Poker o2) {
                return o1.getNum()-o2.getNum();//升序排序
            }
        };
        //调用Collections工具类的sort方法实现排序
        Collections.sort(player1,pokerComparator);
        Collections.sort(player2,pokerComparator);
        Collections.sort(player3,pokerComparator);
        Collections.sort(dipai,pokerComparator);

        //6.看牌
        System.out.println(player1);
        System.out.println(player2);
        System.out.println(player3);
        System.out.println(dipai);
    }
}

运行结果:

54
小王 ♦A ♣K ♣Q ♠J ♦J ♥10 ♦10 ♣10 ♥9 ♦8 ♣8 ♠6 ♠5 ♦5 ♣5 ♠4 
♣2 ♠A ♣A ♥K ♠K ♦Q ♥J ♠9 ♣9 ♥8 ♠7 ♦7 ♣7 ♥6 ♥4 ♦4 ♣3 
大王 ♥2 ♠2 ♥A ♦K ♥Q ♠Q ♣J ♠10 ♦9 ♥7 ♦6 ♥5 ♣4 ♥3 ♠3 ♦3 
♠8 ♣6 ♦2 

六、Debug调试【重点】
Debug可以让程序一步一步的执行,便于观察程序的执行流程,变量的变化情况。调试程序出现的bug

使用大体步骤
        1)打断点
			在代码编辑区域的最左边,点击即可(出现一个小圆点)
		2)Debug执行
			代码会停在打断点的那一行
			
			单步执行(f8)
				让代码逐行执行
			进入方法执行(f7)
			
			执行到下一个断点(f9)
			
			停止调试(ctrl+f2)

详细图文说明:
1.在有效代码行,点击行号右边的空白区域,设置断点,程序执行到断点将停止,我们可以手动来运行程序
在这里插入图片描述
2.点击Debug运行模式
在这里插入图片描述
3.程序停止在断点上不再执行,而IDEA最下方打开了Debug调试窗口
在这里插入图片描述
4.Debug调试窗口介绍
在这里插入图片描述
5.快捷键F8,代码向下执行一行,第九行执行完毕,执行到第十行(还未执行)
在这里插入图片描述
6.点击切换到控制台面板
在这里插入图片描述
7.继续F8,程序继续向后执行,执行键盘录入操作,在控制台录入字符串
在这里插入图片描述
8.此时执行到findChar方法,快捷键F7,进入方法findChar里
在这里插入图片描述9.继续快捷键F8,程序继续执行,创建了map对象,变量区域显示
在这里插入图片描述

10.快捷键F8继续执行,进入到循环中,循环变量i=0,F8再继续执行
在这里插入图片描述

11.继续F8,进入到判断语句中,应为该字符不再Map集合键集中,再按F8执行,进入该判断中
在这里插入图片描述
12.继续F8执行,循环结束,进入下一次循环,此时map集合中已经存在一对元素
在这里插入图片描述
13.继续F8,进入下次循环,再继续上面的操作,我们就可以看到代码每次是如何执行的了
在这里插入图片描述
14.F9让程序直接执行下去,跳出debug
在这里插入图片描述Java第16天学习内容链接:
https://blog.csdn.net/LJN951118/article/details/89256443

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值