java中Map集合、模拟斗地主洗牌发牌、JDK9对集合添加的优化

1.1 Map集合概述

  • Map集合概述
  1. Map==>映射(一个对应一个)
  2. Map是一个接口,只要实现了该接口的类都是双列集合。
  3. 双列集合每次存储元素时都需要存储两个元素,一个元素称为键,一个元素称为值,简称键值对。
  4. 特点:键必须唯一值可以重复
  • Map集合常用实现类
  1. HashMap
  2. LinkedHasMap
  3. HashTable(过时了)

 1.2 Map接口中的常用方法

  • V put(K key,V value)  增改方法
  1. 存在键值对
  2. 如果键存在,则使用新值替换旧值,返回旧值
  3. 如果键不存在,则返回null
  • get(object key);
  1. 根据键获得对应的值
  2. 如果键不存在,则返回null
  • V removeObject key)
  1. 根据键删除键值对,返回键对应的值,如果键不存在,返回null
  • int size()
  1. 获得键值对个数
  • void clear()
  1. 清空集合,删除所有键值对
  • boolean containsKey(Object key)
  1. 判断集合中是否包含对应的键,包含返回true,否则返回false
  • boolean isEmpty()
  1. 判断集合是否为空,键值对个数是否为0,是返回true,否则false
import java.util.HashMap;
import java.util.Map;

public class MapDemo01 {
    public static void main(String[] args) {
        //创建Map集合
        Map map=new HashMap();

        //添加键值对
        String name=map.put("001","Jack");
        System.out.println("name="+name);//(如果键不存在,则返回null )name=null

        name=map.put("001","Rose");
        System.out.println("name="+name);//(如果键存在,则使用新值替换旧值,返回旧值 )name=Jack

        map.put("002","laowang");
        System.out.println(map);//{001=Rose, 002=laowang}

        System.out.println("-------------------------------");
        //根据键获得值
        System.out.println(map.get("001"));//Rose

        //根据键删除键值对
        System.out.println(map.remove("001"));//Rose
        System.out.println(map);//{002=laowang}

        System.out.println("-----------------------------------");
        //获得键值对个数
        System.out.println(map.size());//1

        //判断集合中是否包含指定的键
        System.out.println(map.containsKey("001"));//false
        System.out.println(map.containsKey("002"));//true

        System.out.println("---------------------------------------");
        //清空集合
        map.clear();
        System.out.println(map);//{}

        //判断集合是否为空
        System.out.println(map.isEmpty());//true
    }
}

1.3 Map集合遍历键找值方式

  • Map集合的遍历方式1:通过键找值方式遍历
  1. 调用Map集合的KeySet方法获得键集合
  2. 通过增强for或迭代器遍历键集合
  3. 通过调用Map集合的get方法根据键获得值
  • Map集合与遍历相关的方法
  1. Set keySet() 获得键集合

 

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

public class MapDemo02 {
    public static void main(String[] args) {
        //创建Map集合
        Map map=new HashMap<>();

        //存储键值对
        map.put("001","jack");
        map.put("002","rose");
        map.put("003","lily");
        map.put("004","lucy");

        //调用Map集合的KeySet方法获得键集合
        Set keySet=map.keySet();

        //通过增强for遍历集合
        for(String key:keySet){
            //通过调用Map集合的get方法根据键获得值
            String value=map.get(key);
            System.out.println(key+"="+value);//001=jack,002=rose,003=lily,003=lily
        }
        System.out.println("-----------------");

        //获取键集合对应的迭代器对象
        Iterator  it=keySet.iterator();

        while (it.hasNext()){
            //获得键
            String key=it.next();
            //获得值
            String value=map.get(key);
            System.out.println(key+"="+value);//001=jack,002=rose,003=lily,003=lily
        }
    }
}

1.4 Entry键值对对象

  • 我们已经知道,Map中存放两种对象,一种称为Key(键),一种称为Value(值),它们在Map中是一一对应的关系,这一对对象又称作Map中的一个Entry(项)。Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。
  • Entry对象概述
  1. 每一个键值对都对应一个Entry对象
  2. Entry对象又称为键值对对象
  • Entry对象常用方法
  1. K getKey();获得键
  2. V getValue();获得值 

1.5 Map集合遍历键值对方式

  •  Map集合遍历方式2:通过键值对对象遍历
  1. 调用Map集合的entrySet方法获得Entry对象集合
  2. 使用增强for或迭代器遍历Entry对象集合
  3. 调用Entry对象的getKey和getValue方法获得键和值
  • Map集合中与遍历相关的方法
  1. Set> entrySet() 获得Entry对象集合

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

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

public class MapDemo03 {
    public static void main(String[] args) {
        //创建Map集合
        Map map=new HashMap<>();

        //存储键值对
        map.put("001","jack");
        map.put("002","rose");
        map.put("003","lily");
        map.put("004","lucy");

        //调用Map集合的entrySet方法获得Entry对象集合
        Set> entrySet = map.entrySet();

        //使用增强for遍历集合
        for(Map.Entry  entry:entrySet){
            //获得键
            String key = entry.getKey();
            //获得值
            String value = entry.getValue();
            System.out.println(key+"="+value);//001=jack,002=rose,003=lily,004=lucy,
        }

        System.out.println("------------------------");
        //使用迭代器遍历
        Iterator>   it=entrySet.iterator();
        while(it.hasNext()){
            //获得Entry对象
            Map.Entry  entry=it.next();
            System.out.println(entry);
        }
    }
}

1.6 HashMap存储自定义类型键值

例如:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,即将学生对象和家庭住址存储到map集合中。学生作为键,家庭住址作为值。(假设学生姓名并且年龄相同视为同一名学生)

import java.util.Objects;
/*
    HashMap集合存储自定义对象:底层依赖hashCode和equals方法
    小结:
        1.如果自定义对象作为键,需要重写hashCode和equals方法才能实现去重效果。
        2.如果自定义对象作为值,不需要重写hashCode和equals方法。·
 */
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 &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.util.HashMap;

public class MapDemo04 {
    public static void main(String[] args) {
        //创建Map集合对象
        HashMap map=new HashMap<>();

        //添加学生
        map.put(new Student("马化腾",18),"深圳");
        map.put(new Student("马云",20),"杭州");
        map.put(new Student("李彦宏",24),"北京");
        map.put(new Student("马化腾",18),"广州");
        System.out.println(map);//{Student{name='李彦宏', age=24}=北京, Student{name='马化腾', age=18}=广州, Student{name='马云', age=20}=杭州}
    }
}
  • 当给HashMap中存放 自定义对象时,如果自定义对象作为Key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法。
  • 如果要保证map中存放的key和取出的顺序一致,可以使用Java.util.LinkedHashMap集合来存放

 1.7 LinkedHashMap

1.7.1 LinkedHashMap集合特点

  • 继承HashMap,能够保证存取顺序有序
  • 底层结构:哈希表+链表

 

import java.util.HashMap;
import java.util.LinkedHashMap;

public class LinkedHashMapDemo {
    public static void main(String[] args) {
        //创建Map集合
        HashMap map=new LinkedHashMap<>();

        //存储键值对
        map.put("001","Tony");
        map.put("002","Rose");
        map.put("003","Lily");
        map.put("004","Sunny");
        System.out.println(map);//{001=Tony, 002=Rose, 003=Lily, 004=Sunny}
    }
}

1.8 Map集合案例

1.8.1 案例01

需求:从键盘录入一个字符串:计算一个字符串中每个字符出现次数。

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

/*
    需求:从键盘录入一个字符串:计算一个字符串中每个字符出现次数。
 */
public class MapDemo001 {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc=new Scanner(System.in);

        System.out.println("请输入一个字符串:");
        String line =sc.nextLine();

        //创建Map集合对象
        //Key:字符  Value:字符出现的次数
        Map map=new LinkedHashMap();

        //将字符串转为字符数组
        char[] chs=line.toCharArray();

        //遍历数组
        for(char ch:chs){
            //ch:就是Map集合中的键
            //判断集合中是否包含键ch
            if(map.containsKey(ch)){
                //获得ch键对应的值
                int count = map.get(ch);
                map.put(ch,count+1);
            }else {
                //添加键值对
                map.put(ch,1);
            }
        }
        //遍历输出Map集合
        Set keySet=map.keySet();
        for(Character key:keySet){
            System.out.print(key+"="+map.get(key)+"\t");
        }

    }
}

1.8.2 案例02

需求:有四种水果(苹果、香蕉、西瓜、橘子)

1.给每种水果设定一个商品号,商品号是8个0-9的随机数,商品号码不能重复。

2.根据商品号查询对应的商品。

如果查不到输出:“查无此商品”

如果能查到打印:“根据商品号:12345678,查询到对应的商品为:西瓜”

import java.util.*;

public class MapDemo01 {
    public static void main(String[] args) {
        //定义随机数对象
        Random random=new Random();

        //创建集合存储水果名
        ArrayList fruits=new ArrayList();
        //添加水果
        Collections.addAll(fruits,"苹果","香蕉","西瓜","橘子");

        //创建Map集合存储商品号和水果名称
        //Key:商品号  vaule:水果名
        Map  map=new HashMap<>();

        for (int j = 0; j < fruits.size(); j++) {
            //创建可变字符串用来拼接商品号数字
            StringBuilder sb=new StringBuilder();
            for (int i = 0; i < 8; i++) {
                //获取0-9之间的随机数
                int number=random.nextInt(10);
                //拼接到可变字符串中
                sb.append(number);
            }
            //判断该商品号是否已经使用过
            if(map.containsKey(sb.toString())){
                j--;
                continue;
            }
            //添加键值对到Map集合中
            map.put(sb.toString(),fruits.get(j));
        }
        System.out.println(map);//{85024769=橘子, 54174423=苹果, 30539589=西瓜, 51819688=香蕉}

        //创建键盘录入对象
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入一个商品号:");
        String productNo=sc.nextLine();
        //根据商品号获得水果名称
        String name=map.get(productNo);
        if(name == null){
            System.out.println("查无此商品");
        }else {
            System.out.println("根据商品号:"+productNo+",c查询到对应的商品为:"+name);
        }
    }
}

2.1 模拟斗地主洗牌发牌

java中Map集合、模拟斗地主洗牌发牌、JDK9对集合添加的优化_第1张图片

a.具体规则:
1. 组装54张扑克牌将 2. 54张牌顺序打乱 3. 三个玩家参与游戏,三人交替摸牌,每人17张牌,后三张留作底牌。 4. 查看三人各自手中的牌(按照牌的大小排序)、底牌
规则:手中扑克牌从大到小的摆放顺序:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3 

 b.案例需求分析:

1. 准备牌:
完成数字与纸牌的映射关系:
使用双列Map(HashMap)集合,完成一个数字与字符串纸牌的对应关系(相当于一个字典)。
2. 洗牌:
通过数字完成洗牌发牌
3. 发牌: 将每个人以及底牌设计为ArrayList,将后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
存放的过程中要求数字大小与斗地主规则的大小对应。
将代表不同纸牌的数字分配给不同的玩家与底牌。
4. 看牌:
通过Map集合找到对应字符展示。
通过查询纸牌与数字的对应关系,由数字转成纸牌字符串再进行展示。

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

/**
    斗地主案例
        * 组牌
        * 洗牌
        * 发牌
        * 看牌
 */
public class DDZDemo01 {
    public static void main(String[] args){
        // 组牌: 花色+数字
        // 花色:4种花色
        ArrayList colors = new ArrayList<>();
        // 添加4种花色
        Collections.addAll(colors, "♦","♣","♥","♠");
        // 数字:13个数字
        ArrayList nums = new ArrayList<>();
        // 添加数字
        Collections.addAll(nums, "3","4","5","6","7","8","9","10","J","Q","K","A","2");


        // 定义变量充当牌的索引值
        int index = 0;

        Map pokers = new HashMap<>();
        // 遍历集合拼接牌
        for(String num:nums){ // 3
            for (String color:colors) {
                // 拼接牌
                String poker = color.concat(num);
                // 添加牌到集合中
                pokers.put(index++,poker);
            }
        }
        // 添加大小王
        pokers.put(index++, "

你可能感兴趣的:(Map)