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
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:通过键找值方式遍历
- 调用Map集合的KeySet方法获得键集合
- 通过增强for或迭代器遍历键集合
- 通过调用Map集合的get方法根据键获得值
- Map集合与遍历相关的方法:
- 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对象概述:
- 每一个键值对都对应一个Entry对象
- Entry对象又称为键值对对象
- Entry对象常用方法:
- K getKey();获得键
- V getValue();获得值
1.5 Map集合遍历键值对方式
- Map集合遍历方式2:通过键值对对象遍历
- 调用Map集合的entrySet方法获得Entry对象集合
- 使用增强for或迭代器遍历Entry对象集合
- 调用Entry对象的getKey和getValue方法获得键和值
- Map集合中与遍历相关的方法:
- 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 模拟斗地主洗牌发牌
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++, "