您的位置:首页 > 编程语言 > Java开发

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

2018-08-03 18:30 591 查看

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 remove(Object key)
  1. 根据键删除键值对,返回键对应的值,如果键不存在,返回null
  • int size()
  1. 获得键值对个数
  • void clear()
  1. 清空集合,删除所有键值对
  • boolean containsKey(Object key)
  1. 判断集合中是否包含对应的键,包含返回true,否则返回false
  • boolean isEmpty()
  1. 判断集合是否为空,键值对个数是否为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:通过键找值方式遍历
  1. 调用Map集合的KeySet方法获得键集合
  2. 通过增强for或迭代器遍历键集合
  3. 通过调用Map集合的get方法根据键获得值
  • Map集合与遍历相关的方法:
  1. 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对象概述:
  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<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++, "
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: