java中Map集合、模拟斗地主洗牌发牌、JDK9对集合添加的优化
1.1 Map集合概述
- Map集合概述
- Map==>映射(一个对应一个)
- Map是一个接口,只要实现了该接口的类都是双列集合。
- 双列集合每次存储元素时都需要存储两个元素,一个元素称为键,一个元素称为值,简称键值对。
- 特点:键必须唯一,值可以重复。
- Map集合常用实现类
- HashMap
- LinkedHasMap
- HashTable(过时了)
1.2 Map接口中的常用方法
- V put(K key,V value) 增改方法
- 存在键值对
- 如果键存在,则使用新值替换旧值,返回旧值
- 如果键不存在,则返回null
- get(object key);
- 根据键获得对应的值
- 如果键不存在,则返回null
- V remove(Object key)
- 根据键删除键值对,返回键对应的值,如果键不存在,返回null
- int size()
- 获得键值对个数
- void clear()
- 清空集合,删除所有键值对
- boolean containsKey(Object key)
- 判断集合中是否包含对应的键,包含返回true,否则返回false
- boolean isEmpty()
- 判断集合是否为空,键值对个数是否为0,是返回true,否则false
[code]import java.util.HashMap; import java.util.Map; public class MapDemo01 { public static void main(String[] args) { //创建Map集合 Map<String,String> map=new HashMap<String, String>(); //添加键值对 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:通过键找值方式遍历
- 调用Map集合的KeySet方法获得键集合
- 通过增强for或迭代器遍历键集合
- 通过调用Map集合的get方法根据键获得值
- Map集合与遍历相关的方法:
- Set<k> keySet() 获得键集合
[code]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<String,String> map=new HashMap<>(); //存储键值对 map.put("001","jack"); map.put("002","rose"); map.put("003","lily"); map.put("004","lucy"); //调用Map集合的KeySet方法获得键集合 Set<String> 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<String> 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对象概述:
- 每一个键值对都对应一个Entry对象
- Entry对象又称为键值对对象
- Entry对象常用方法:
- K getKey();获得键
- V getValue();获得值
1.5 Map集合遍历键值对方式
- Map集合遍历方式2:通过键值对对象遍历
- 调用Map集合的entrySet方法获得Entry对象集合
- 使用增强for或迭代器遍历Entry对象集合
- 调用Entry对象的getKey和getValue方法获得键和值
- Map集合中与遍历相关的方法:
- Set<Entry<k,v>> entrySet() 获得Entry对象集合
注意:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。
[code]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<String,String> map=new HashMap<>(); //存储键值对 map.put("001","jack"); map.put("002","rose"); map.put("003","lily"); map.put("004","lucy"); //调用Map集合的entrySet方法获得Entry对象集合 Set<Map.Entry<String,String>> entrySet = map.entrySet(); //使用增强for遍历集合 for(Map.Entry<String,String> 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<Map.Entry<String,String>> it=entrySet.iterator(); while(it.hasNext()){ //获得Entry对象 Map.Entry<String,String> entry=it.next(); System.out.println(entry); } } }
1.6 HashMap存储自定义类型键值
例如:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,即将学生对象和家庭住址存储到map集合中。学生作为键,家庭住址作为值。(假设学生姓名并且年龄相同视为同一名学生)
[code]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 + '}'; } }
[code]import java.util.HashMap; public class MapDemo04 { public static void main(String[] args) { //创建Map集合对象 HashMap<Student,String> 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,能够保证存取顺序有序
- 底层结构:哈希表+链表
[code]import java.util.HashMap; import java.util.LinkedHashMap; public class LinkedHashMapDemo { public static void main(String[] args) { //创建Map集合 HashMap<String,String> 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
需求:从键盘录入一个字符串:计算一个字符串中每个字符出现次数。
[code]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<Character,Integer> map=new LinkedHashMap<Character, Integer>(); //将字符串转为字符数组 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<Character> 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,查询到对应的商品为:西瓜”
[code]import java.util.*; public class MapDemo01 { public static void main(String[] args) { //定义随机数对象 Random random=new Random(); //创建集合存储水果名 ArrayList<String> fruits=new ArrayList<String>(); //添加水果 Collections.addAll(fruits,"苹果","香蕉","西瓜","橘子"); //创建Map集合存储商品号和水果名称 //Key:商品号 vaule:水果名 Map<String,String> 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 模拟斗地主洗牌发牌
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集合找到对应字符展示。
通过查询纸牌与数字的对应关系,由数字转成纸牌字符串再进行展示。
[code]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<String> colors = new ArrayList<>(); // 添加4种花色 Collections.addAll(colors, "♦","♣","♥","♠"); // 数字:13个数字 ArrayList<String> nums = new ArrayList<>(); // 添加数字 Collections.addAll(nums, "3","4","5","6","7","8","9","10","J","Q","K","A","2"); // 定义变量充当牌的索引值 int index = 0; Map<Integer,String> pokers = new HashMap<>(); // 遍历集合拼接牌 for(String num:nums){ // 3 for (String color:colors) { // 拼接牌 String poker = color.concat(num); // 添加牌到集合中 pokers.put(index++,poker); } } // 添加大小王 pokers.put(index++, "阅读更多
- 大数据之JAVA基础(十七):集合--模拟斗地主洗牌和发牌
- Java学习笔记34(集合框架八:综合案例:模拟斗地主的洗牌发牌)
- Java基础知识强化之集合框架笔记70:模拟斗地主洗牌和发牌(ArrayList)
- JAVA-11.3-模拟斗地主洗牌、发牌、并进行排序(集合)
- Java基础知识强化之集合框架笔记71:模拟斗地主洗牌和发牌并对牌进行排序的案例
- 利用JAVA数组模拟集合实现简单的对象数组的添加
- java学习笔记(二十五)模拟斗地主发牌与洗牌
- Java模拟斗地主洗牌、发牌和对牌排序
- 集合框架_模拟斗地主洗牌和发牌并对牌进行排序的代码实现
- Java模拟斗地主发牌和洗牌
- Java中的map集合顺序如何与添加顺序一样
- 集合框架-模拟斗地主洗牌和发牌并对牌进行排序案例
- 用java模拟斗地主洗牌和发牌
- Java_基础—模拟斗地主洗牌和发牌并对牌进行排序
- JAVA中的map集合顺序如何与添加顺序一样
- Java中的map集合顺序如何与添加顺序一样
- javascript:用object对象模拟java的map集合
- 模拟斗地主的发牌洗牌看牌的功能,主要用到了ArrayList(),HashMap(),的添加和遍历可以参考一下
- 集合框架_模拟斗地主洗牌和发牌并对牌进行排序的原理图解