day09_面向对象Map
一.Map集合的概述
1.什么是Map集合
Collection集合称为单列集合
Map集合称为双列集合
2.Map集合的特点
a.Collection每个元素单独存在,Map每个元素是成对的
b.Map集合中键是唯一的,值是可以重复的,通过键只能找到唯一的值
二.Map集合中常用的实现类
1.HashMap集合介绍
a.无序的
b.键是唯一的,值不唯一
为了保证键的唯一性,如果键是自定义类型,我们需要重写键的hashCode和equals方法
2.LinkedHashMap集合介绍
a.有序的
b.键是唯一的,值不唯一
为了保证键的唯一性,如果键是自定义类型,我们需要重写键的hashCode和equals方法
3.Map接口中通用的方法*************************
增: V put(K key, V value );添加一个键值对,返回null(之前键不存在)
删: V remove(K key);根据键删除键值对,返回被删除键值对的值
改: V put(K key, V value );如果键已经存在,那么put方法相当于修改值
查:V get(K key); 根据键查找出对应的值
其他:
public boolean containsKey(Object key); 是否包含某个键
public boolean containsValue(Object value); 是否包含某个值
public class TestMap {
public static void main(String[] args) {
//1.创建一个Map集合
LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
//2.put
Integer v1 = map.put("小米", 1234);
Integer v2 = map.put("华为", 6888);
Integer v3 = map.put("爱疯", 8888);
Integer v4 = map.put("三星", 2500);
Integer v5 = map.put("小米", 5500);
//{爱疯=8888, 华为=6888, 小米=1234, 三星=2500}
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
System.out.println(v4);
System.out.println(v5);
System.out.println(map);
//3.remove
Integer v6 = map.remove("爱疯");
System.out.println(v6);
System.out.println(map);
//4.get
Integer v7 = map.get("华为");
System.out.println(v7);
System.out.println(map);
//5.containsKey ContainsValue
System.out.println(map.containsKey("华为"));
System.out.println(map.containsValue(4321));
}
}
4.Map的遍历方式一:以键找值方式************************
public class MapKeySetDemo {
public static void main(String[] args) {
//1.创建一个Map集合
LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
//2.put
map.put("小米", 1234);
map.put("华为", 6888);
map.put("爱疯", 8888);
map.put("三星", 2500);
//3.以键找值 keySet
//a.获取所有的键的集合
Set<String> keys = map.keySet();
//b.遍历所有的键
//迭代器,foreach
for (String key : keys) {
//c.以键找值
Integer value = map.get(key);
//打印出来
System.out.println(key + "=" + value);
}
}
}
5.Map的遍历方式二:键值对方式**************************
public class MapEntrySetDemo {
public static void main(String[] args) {
//1.创建一个Map集合
LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
//2.put
map.put("小米", 1234);
map.put("华为", 6888);
map.put("爱疯", 8888);
map.put("三星", 2500);
//3.Map集合的第二种遍历方式:键值对方式
//a.获取所有键值对的集合
Set<Map.Entry<String, Integer>> entries = map.entrySet();
//b.遍历这个键值对的集合
//迭代器,foreach
for (Map.Entry<String, Integer> entry : entries) {
//c.获取键值
String key = entry.getKey();
Integer value = entry.getValue();
//打印
System.out.println(key + "=" + value);
}
}
}
6.练习:使用HashMap/LinkedHashMap保存自定义对象
练习:每位学生(姓名,年龄)都有自己的家庭住址
那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键,家庭住址作为值。
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", 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);
}
}
public class TestMapDemo01 {
public static void main(String[] args) {
LinkedHashMap<Student,String> map = new LinkedHashMap<Student, String>();
//保存几个键值对
map.put(new Student("柳岩", 20), "上海");
map.put(new Student("古力娜扎", 30), "北京");
map.put(new Student("马尔扎哈", 25), "广州");
map.put(new Student("迪丽热巴", 18), "我家楼上");
map.put(new Student("凤姐", 30), "你家隔壁");
map.put(new Student("柳岩", 20), "深圳");
// {
// Student{name='古力娜扎', age=30}=北京,
// Student{name='迪丽热巴', age=18}=我家楼上,
// Student{name='柳岩', age=20}=上海,
// Student{name='马尔扎哈', age=25}=广州,
// Student{name='凤姐', age=30}=你家隔壁
// }
//打印
System.out.println(map);
}
}
7.Map集合练习*****************
需求:
输入一个字符串,统计其中每个字符出现次数。
public class TestMapDemo02 {
public static void main(String[] args) {
//需求:
//输入一个字符串,统计其中每个字符出现次数。
//1.输入
System.out.println("请输入一个字符串:");
String str = new Scanner(System.in).nextLine();
//2.统计str中出现的每种字符次数
//a.定义保存结果的map集合
LinkedHashMap<Character, Integer> result =
new LinkedHashMap<Character, Integer>();
//b.遍历字符串
for (int i = 0; i < str.length(); i++) {
//取出字符串中的字符
char ch = str.charAt(i);
if (result.containsKey(ch)) {
//如果ch这个字符,在map中有了,说明不是第一次
Integer count = result.get(ch);
result.put(ch, count + 1);
} else {
//如果ch这个字符,在map中没有对应的键值对,说明第一次出现
result.put(ch, 1);
}
}
//c.打印结果
System.out.println(result);
}
}
三.补充知识点
1.可变参数(回顾)
格式:
public void 方法名(数据类型... 变量名){
}
本质:
可变参数其实就是一个数组
注意:
a.一个方法最最最多只能有一个可变参数
b.如果有正常参数和可变参数,那么可变参数必须写在最后面
应用:
public class VariableArgumentsDemo {
public static void main(String[] args) {
//1.创建集合,添加多个元素
ArrayList<String> arr = new ArrayList<String>();
//添加
// arr.add("jack");
// arr.add("rose");
// arr.add("tom");
// arr.add("marry");
//工具类 Collections
Collections.addAll(arr,"jack","rose","tom","marry");
System.out.println(arr);
}
}
2.数组冒泡排序
一共需要n-1轮的比较
第一轮 需要比较 n-1 次
第二轮 需要比较 n-1-1次
第三轮 需要比较 n-1-2次
...
public class BubbleSortDemo {
public static void main(String[] args) {
//数组
int[] arr = {7, 6, 5, 4, 3};
//冒泡排序
for(int i = 0; i < arr.length-1;i++){
for(int j = 0;j < arr.length-1-i;j++){
//比较 arr[j] arr[j+1]
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
//打印
for (int i : arr) {
System.out.println(i);
}
}
}
冒泡
选择
插入
希尔
快速
归并
堆排序
3.Arrays类介绍********************
Arrays数组的工具类
Collections集合的工具类
Arrays工具类中的静态方法
public static String toString(int[] arr);把数组的元素拼接成指定格式的字符串返回
public static void sort(int[] arr);升序排序数组
public static void sort(Integer[] arr, Compare<T> com);
比较器排序(但是数组必须是引用类型数组,如果是基本类型,请写成包装类)
public class ArraysDemo01 {
public static void main(String[] args) {
//1.定义数组
Integer[] arr = {7,8,2,6,1,5,4,9,3};
//2.打印
String str = Arrays.toString(arr);
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
System.out.println(str);
//3.排序数组(升序)
Arrays.sort(arr);
//4.打印
System.out.println(Arrays.toString(arr));
//5.使用比较器排序
Arrays.sort(arr,new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
//6.打印
System.out.println(Arrays.toString(arr));
}
}
四.模拟排序斗地主案例*************************
1.斗地主规则介绍
2.斗地主步骤分析
3.代码实现(代码演示)
public class SortDouDiZhuDemo {
public static void main(String[] args) {
// 排序斗地主代码步骤:
// 1.准备Map集合(键是编号,值是扑克牌)
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
//花色
String[] colors = {"♠", "♥", "♣", "♦"};
//数值
String[] nums = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
//编号变量
int id = 1;
//嵌套循环
for (String num : nums) {
for (String color : colors) {
//拼接
String card = color + num;
//添加到Map集合
map.put(id++, card);
}
}
//大小王单独添加
map.put(53, "小S");
map.put(54, "大S");
// 2.准备一副牌(54个编号)
ArrayList<Integer> cardBox = new ArrayList<Integer>();
for (int i = 1; i < 55; i++) {
cardBox.add(i);
}
// 3.洗牌(打乱编号)
Collections.shuffle(cardBox);
// 4.发牌(发的编号)
ArrayList<Integer> p1 = new ArrayList<Integer>();
ArrayList<Integer> p2 = new ArrayList<Integer>();
ArrayList<Integer> p3 = new ArrayList<Integer>();
ArrayList<Integer> dp = new ArrayList<Integer>();
//发牌
for (int i = 0; i < cardBox.size() - 3; i++) {
//取出牌
Integer card = cardBox.get(i);
//发给谁??
if (i % 3 == 0) {
p1.add(card);
} else if (i % 3 == 1) {
p2.add(card);
} else {
p3.add(card);
}
}
//最后剩下三张给底牌
dp.add(cardBox.get(51));
dp.add(cardBox.get(52));
dp.add(cardBox.get(53));
// 5.排序(编号排序,也是对牌排序)
Collections.sort(p1);
Collections.sort(p2);
Collections.sort(p3);
Collections.sort(dp);
// 6.根据编号从Map中获取真正的牌,打印出来
lookCards(p1, map);
lookCards(p2, map);
lookCards(p3, map);
lookCards(dp, map);
}
public static void lookCards(ArrayList<Integer> pp, LinkedHashMap<Integer, String> map) {
//把集合中编号,通过map的get方法换成牌
for (Integer id : pp) {
String card = map.get(id);
System.out.print(card + " ");
}
System.out.println();
}
}
总结:
泛型只能用引用类型
Comparator接口使用:
Integer[] arr ={};
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2; // 升序 前减后
}
});
-[] 能够说出Map集合特点
a.双列集合
b.键唯一(如果键是自定义类型,必须重写hashCode和equals)
-[] 使用Map集合添加方法保存数据**********************
增:put(键, 值);
删:remove(键);
改:put(重复的键,值);
查:get(键);
其他:
public boolean containsKey(键);
public boolean containsValue(值);
-[] 使用“键找值”的方式遍历Map集合**************
Set<键的泛型> keys = map.keySet();
-[] 使用“键值对”的方式遍历Map集合**************
Set<Map.Entry<键的泛型,值的泛型>> entries = map.entrySet();
-[] 能够使用HashMap/LinkedHashMap存储自定义键值对的数据
-[] 能够使用可变参数
Collections.add方法
框架,反射,服务器源码
-[] 能够理解冒泡排序/选择排序/插入排序的原理
-[] 能够使用Arrays数组工具类的常用方法
Arrays.toString(数组);把数组元素拼接成字符串
Arrays.sort(数组);升序排列字符串
Arrays.sort(数组,new Comparator(){});
-[] 能够使用HashMap编写排序斗地主洗牌发牌案例