苟有恒,何必三更眠五更起; 最无益,莫过一日曝十日寒。
Map集合
概述: Map集合是双列集合的顶层**接口,**他是来存储键值对对象的,其中键具有唯一性,而值是可以重复的.Map集合的常用子类主要有两个, 分别是: HashMap和TreeMap.
即:Map集合的数据结构只针对于键有效.
2 格式
public interface Map<K, V> //K: 键的类型, V: 值的类型.
例如:
itheima001 刘亦菲
itheima002 赵丽颖
itheima003 高圆圆
创建对象
因为Map 是接口,不能通过new关键字直接创建他的对象,我们可以通过多态的形式,创建其子类对象,从而实现创建Map集合对象的这个需求
2.1 Map入门
public V put(K key, V value)
解释:
往双列集合中添加元素, 键不存在则直接添加, 并返回null.
键存在则用新值覆盖旧值, 并返回被赋值之前的值.
3.4.1 需求
定义Map集合, 键是学号, 值是学生的名字. (键值都是字符串类型).
往Map集合中添加3对元素.
打印Map集合对象.
public static void main(String[] args) {
Map<String,String> map =new HashMap<>();
// 往Map集合中添加3对元素.
map.put("001","张三");
map.put("002","李四");
map.put("003","王五");
map.put("003","赵六");
System.out.println("map = " + map);
}
console:
map = {001=张三, 002=李四, 003=赵六}
如果k值相等则直接覆盖掉,用之后的值填入之前的值
可以反推出第一次什么都不添加的时候,这个map对象里面是null
2.2 Map集合的成员方法
2.2.1 方法描述
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
有些方法直接输出是boolean类型的
Map集合的获取功能
方法描述
方法名 | 说明 |
---|---|
V get(Object key) | 根据键获取值 |
Set keySet() | 获取所有键的集合 |
Collection values() | 获取所有值的集合 |
Set<Map.Entry<K,V>> entrySet() | 获取所有键值对对象的集合 |
set跟直接打印集合的数值是一样的
但是set是获取所有值,不是打印值
需求
定义Map集合, 键是丈夫, 值是妻子. (键值都是字符串类型).
分别测试上述的7个方法.
步骤分析
获取所有键的集合。
解释: 用Map#keySet()方法实现
遍历键的集合,获取到每一个键。
解释: 用增强for实现
根据键去找值。
解释: 用Map#get(K key)方法实现
public static void main(String[] args) {
Map<String,String> map =new HashMap<>();
map.put("001","tz");
map.put("002","tz1");
map.put("003","tz2");
//1获取所有键的集合。
Set<String> keys = map.keySet();
//2遍历键的集合,获取到每一个键。
for (String key : keys) {
String value = map.get(key);
System.out.println(key+ "..." + value);
}
public static void main(String[] args) {
Map<String,String> map =new HashMap<>();
map.put("鬼剑士","剑魂");
map.put("格斗家","花花");
map.put("神枪手","王大枪");
//1获取所有键的集合。
Set<Map.Entry<String,String>> entrys = map.entrySet();
//2遍历键的集合,获取到每一个键。
//for (String key : keys) {
// String value = map.get(key);
// System.out.println(key+ "..." + value);
//}
for (Map.Entry<String, String> entry : entrys) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"..." +value);
}
}
把Map看成是一个 -两个数- 的集合.(key,value)
利用map集合的entryset方法调用set的key和value值
通过Map#Set<Map.Entry<K,V>> entrySet()方法实现.
entrySet()方法的作用是: 获取所有键值对对象的集合
遍历键值对对象的集合,得到每一个键值对对象
解释:
用增强for实现,得到每一个Map.Entry
Map.Entry 就表示键值对对象的类型.
根据键值对对象获取键和值
用map.getKey()获取键
用map.getvalue() 获取值
public static void main(String[] args) {
Map<String,String> map =new HashMap<>();
map.put("鬼剑士","剑魂");
map.put("格斗家","花花");
map.put("神枪手","王大枪");
//1获取所有键的集合。
Set<Map.Entry<String,String>> entrys = map.entrySet();
//2遍历键的集合,获取到每一个键。
//for (String key : keys) {
// String value = map.get(key);
// System.out.println(key+ "..." + value);
//}
for (Map.Entry<String, String> entry : entrys) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"..." +value);
}
}
案例2
2.2.1 案例一: 键是String值是Student
创建HashMap集合, 键是学号(String), 值是学生对象(Student).
往HashMap集合中添加3组数据.
通过两种方式, 遍历HashMap集合.
2.2.2 参考代码
public static void main(String[] args) {
Map<String,Student> map =new HashMap<>();
map.put("鬼剑士",new Student("剑魂",19));
map.put("格斗家",new Student("花花",20));
map.put("神枪手",new Student("漫游",21));
Set<String> keys = map.keySet();
for (String key : keys) {
Student student = map.get(key);
System.out.println(key+"..." +student);
}
System.out.println("--------------");
//entryset
Set<Map.Entry<String, Student>> entries = map.entrySet();
for (Map.Entry<String, Student> entry : entries) {
String key = entry.getKey();
Student value = entry.getValue();
System.out.println(key +"..."+ value);
}
}
案例二: 键是Student值是String
创建HashMap集合, 键是学生对象(Student), 值是居住地(String).
往HashMap集合中添加3组数据.
通过两种方式, 遍历HashMap集合.
注意: HashMap集合想保证键的唯一性, 依赖hashCode()和equals()这两个方法.
public static void main(String[] args) {
Map<Student,String> map =new HashMap<>();
map.put(new Student("剑魂",19),"鬼剑士");
map.put(new Student("花花",20),"格斗家");
map.put(new Student("漫游",21),"神枪手");
Set<Student> keys = map.keySet();
for (Student key : keys) {
String student = map.get(key);
System.out.println(key+"..." +student);
}
System.out.println("--------------");
//entryset
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);
}
}
案例三: ArrayList嵌套HashMap
需求
定义ArrayList<HashMap<String, String>>集合, 存储三个元素, 每个元素都是一个双列集合, 具体如下:
第一个双列集合, 记录的信息如下:
(“剑魂”,“鬼剑士”)
(“花花”,“格斗家”)
第二个双列集合, 记录的信息如下:
(“漫游”,“神枪手”)
(“奶爸”,“圣职者”)
第三个双列集合, 记录的信息如下:
(“剑豪”,“女鬼剑”)
(“奶萝”,“女魔法师”
把上述的三个双列集合当做元素对象, 添加到ArrayList集合中.
遍历ArrayList集合, 输出每个元素.
public static void main(String[] args) {
ArrayList<HashMap<String,String>> arrayList =new ArrayList<>();
HashMap<String, String> hashMap1 = new HashMap<>();
hashMap1.put("剑魂","鬼剑士");
hashMap1.put("花花","格斗家");
HashMap<String, String> hashMap2 = new HashMap<>();
hashMap2.put("漫游","神枪手");
hashMap2.put("奶爸","圣职者");
HashMap<String, String> hashMap3 = new HashMap<>();
hashMap1.put("剑豪","女鬼剑");
hashMap1.put("奶萝","女魔法师");
arrayList.add(hashMap1);
arrayList.add(hashMap2);
arrayList.add(hashMap3);
for (int i = 0; i < arrayList.size(); i++) {
HashMap<String, String> hashMap = arrayList.get(i);
for (String key : hashMap.keySet()) {
String values = hashMap.get(key);
System.out.println(key +"..."+values);
}
}
System.out.println("--------------");
}
案例五: 统计每个字符的次数
4.5.1 需求
键盘录入一个字符串,要求统计字符串中每个字符出现的次数。
举例:键盘录入“aababcabcdabcde” 在控制台输出:“a(5)b(4)c(3)d(2)e(1)”
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一串字母:");
String result = scanner.nextLine();
//创建TreeMap集合对象,字符作键,次数做值.
TreeMap<Character, Integer> tm = new TreeMap<>();
//将接收到的字符串返回成char
char[] chs = result.toCharArray();
//遍历, 获取到每一个字符.
for (char ch : chs) {
//判断该字符在双列集合中是否存在.不存在,直接存储,次数为1
if(!tm.containsKey(ch)){
tm.put(ch,1);
//存在,次数+1
}else{
tm.put(ch,tm.get(ch)+1);
}
}
//将双列集合中的数据拼接成指定的字符串.
StringBuilder sb = new StringBuilder();
for (Character key : tm.keySet()) {
//Integer value = tm.get(key);
sb.append(key).append("(").append(tm.get(key)).append(")");
}
System.out.println(sb.toString());
}
Collections类
针对集合操作的工具类.
5.2 常用方法
5.2.1 常用方法如下
方法名 说明
public static void sort(List list) 将指定的列表按升序排序
public static void reverse(List<?> list) 反转指定列表中元素的顺序
public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
5.2.2 需求
定义ArrayList集合, 存储5个整数.
分别测试上述的3个方法.
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
arrayList.add("4");
arrayList.add("5");
arrayList.add("6");
arrayList.add("7");
System.out.println(arrayList);
Collections.sort(arrayList);
System.out.println(arrayList);
Collections.reverse(arrayList);
System.out.println(arrayList);
Collections.shuffle(arrayList);
System.out.println(arrayList);
}
斗地主案例
通过代码实现斗地主过程中的洗牌,发牌和看牌动作.
package Demo;
import javax.xml.ws.soap.Addressing;
import java.util.*;
public class Demo_03 {
public static void main(String[] args){
ArrayList<String> arrayList = new ArrayList<>();
//定义花色数组
String[] colors = {"♦", "♣", "♥", "♠"};
//定义点数数组
String[] numbers = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
for (String color : colors) {
for (String number : numbers) {
arrayList.add(color+number);
}
}
arrayList.add("小王");
arrayList.add("大王");
Collections.shuffle(arrayList);
ArrayList<String> lqxArray = new ArrayList<String>();
ArrayList<String> lyArray = new ArrayList<String>();
ArrayList<String> fqyArray = new ArrayList<String>();
ArrayList<String> dpArray = new ArrayList<String>();
//for (int i = 0; i < arrayList.size(); i++) {
// String poker = arrayList.get(i);
// if(i>= arrayList.size()-3){
// dpArray.add(poker);
// }else if(i%3 == 0){
// lqxArray.add(poker);
// }else if(i%3 == 1){
// lyArray.add(poker);
// }else if(i%3 == 2){
// fqyArray.add(poker);
// }
//}
lookPoker("林青霞", lqxArray);
lookPoker("柳岩", lyArray);
lookPoker("风清扬", fqyArray);
lookPoker("底牌", dpArray);
}
public static void lookPoker(String name, ArrayList<String> array) {
System.out.print(name + "的牌是:");
for (String poker : array) {
System.out.print(poker + " ");
}
System.out.println();
}
}
console:
林青霞的牌是:♥J ♦5 ♣K ♦4 ♠3 ♥K ♠5 ♣5 ♦6 ♦7 ♣7 ♥10 大王 ♥A ♠4 ♥5 ♣2
柳岩的牌是:♥7 ♦A ♣3 ♠J 小王 ♥2 ♥9 ♦9 ♦3 ♣A ♦10 ♦J ♠2 ♠8 ♥3 ♣10 ♣6
风清扬的牌是:♥6 ♠K ♥4 ♠6 ♠9 ♣Q ♠7 ♠Q ♣8 ♥8 ♣4 ♦8 ♦K ♠A ♠10 ♥Q ♣J
底牌的牌是:♦Q ♦2 ♣9
排序之后的写法
public static void main(String[] args){
HashMap<Integer,String> hm = new HashMap<>();
ArrayList<Integer> array = new ArrayList<>();
String[] colors = {"♦", "♣", "♥", "♠"};
String[] numbers = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
int index = 0;
for (String number : numbers) {
for (String color: colors) {
hm.put(index,color+number);
array.add(index);
index++;
}
}
hm.put(index, "小王");
array.add(index);
index++;
hm.put(index, "大王");
array.add(index);
Collections.shuffle(array);
TreeSet<Integer> lqxSet = new TreeSet<>();
TreeSet<Integer> lySet = new TreeSet<>();
TreeSet<Integer> fqySet = new TreeSet<>();
TreeSet<Integer> dpSet = new TreeSet<>();
for (int i = 0; i < array.size(); i++) {
int x = array.get(i);
if (i >= array.size() - 3) {
dpSet.add(x);
} else if (i % 3 == 0) {
lqxSet.add(x);
} else if (i % 3 == 1) {
lySet.add(x);
} else if (i % 3 == 2) {
fqySet.add(x);
}
}
lookPoker("林青霞", lqxSet, hm);
lookPoker("柳岩", lySet, hm);
lookPoker("风清扬", fqySet, hm);
lookPoker("底牌", dpSet, hm);
}
public static void lookPoker(String name, TreeSet<Integer> ts, HashMap<Integer, String> hm) {
System.out.print(name + "的牌是:");
for (Integer key : ts) {
String poker = hm.get(key);
System.out.print(poker + " ");
}
System.out.println();
}
console:
林青霞的牌是:♦4 ♣5 ♥5 ♣7 ♣8 ♠8 ♥9 ♠9 ♣10 ♦J ♥Q ♠Q ♦K ♦A ♣A ♠A ♦2
柳岩的牌是:♦3 ♣3 ♥3 ♠3 ♥4 ♦5 ♦6 ♣6 ♥6 ♥7 ♦8 ♦10 ♣J ♥J ♦Q ♣Q ♠2
风清扬的牌是:♣4 ♠4 ♠5 ♠6 ♦7 ♠7 ♥8 ♦9 ♣9 ♣K ♥K ♠K ♥A ♣2 ♥2 小王 大王
底牌的牌是:♥10 ♠10 ♠J