HashMap集合练习
一、练习:存储学生对象并遍历
需求
- 创建一个HashMap集合,键是学生对象(Student),值是籍贯(String)。
- 存储三个键值对元素,并遍历。
- 要求:同姓名,同年龄认为是同一个学生。
- 核心点:HashMap的键位置如果存储的是自定义对象,需要重写equals和hashCode方法。
学生类
package com.app.demo30_hashmap_test;
import java.util.Objects;
/*
学生类
*/
public class Student {
private String name; // 姓名
private int age; // 年龄
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
// 由于学生对象是作为键,因此需要重写equals和hashCode方法
@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 String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
测试类
package com.app.demo30_hashmap_test;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
/*
练习:存储学生对象并遍历
需求:
创建一个HashMap集合,键是学生对象(Student),值是籍贯(String)。
存储三个键值对元素,并遍历。
要求:同姓名,同年龄认为是同一个学生。
核心点:
HashMap的键位置如果存储的是自定义对象,需要重写equals和hashCode方法。
*/
// 创建HashMap集合
HashMap<Student, String> hashMap = new HashMap<>();
// 创建学生对象
Student s1 = new Student("zhangsan", 33);
Student s2 = new Student("lisi", 34);
Student s3 = new Student("wangwu", 35);
Student s4 = new Student("wangwu", 35);
// 添加元素到集合中
hashMap.put(s1, "广州");
hashMap.put(s2, "澳大利亚");
hashMap.put(s3, "马来西亚");
hashMap.put(s4, "广东");
// 遍历集合
// 1.第一种方式
// 获取到所有键的集合
Set<Student> keys = hashMap.keySet();
// 遍历键集合,依次得到每个键
for (Student key : keys) {
// 根据键获取对应的值
String value = hashMap.get(key);
// 输出键值对
System.out.println(key + " = " + value);
}
System.out.println("------------------------------------");
// 2.第二种方式
// 获取所有键值对的集合
Set<Map.Entry<Student, String>> entries = hashMap.entrySet();
// 遍历键值对集合,依次得到每个键值对
for (Map.Entry<Student, String> entry : entries) {
// 根据键值对对象获取到每个键
Student key = entry.getKey();
// 根据键值对对象获取到每个值
String value = entry.getValue();
// 输出键值对
System.out.println(key + " = " + value);
}
System.out.println("------------------------------------");
// 3.第三种方式:Lambda表达式
hashMap.forEach((student, s) -> System.out.println(student + " = " + s));
}
}
测试结果
Student{name = lisi, age = 34} = 澳大利亚
Student{name = zhangsan, age = 33} = 广州
Student{name = wangwu, age = 35} = 广东
------------------------------------
Student{name = lisi, age = 34} = 澳大利亚
Student{name = zhangsan, age = 33} = 广州
Student{name = wangwu, age = 35} = 广东
------------------------------------
Student{name = lisi, age = 34} = 澳大利亚
Student{name = zhangsan, age = 33} = 广州
Student{name = wangwu, age = 35} = 广东
Process finished with exit code 0
二、练习:统计投票人数
需求
-
某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。
-
核心点:判断集合中是否已包含该景点。
不包含:表示该景点是第一次投票,投票次数是1;
包含:表示该景点已经投过票了,在原有的投票次数上+1
测试类
package com.app.demo30_hashmap_test;
import java.util.*;
public class VoteTest2 {
public static void main(String[] args) {
/*
练习:统计投票人数
需求:
某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),
每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。
核心点:判断集合中是否已包含该景点
不包含:表示该景点是第一次投票,投票次数是1
包含:表示该景点已经投过票了,在原有的投票次数上 +1
*/
// 1.由于景点目前已经明确给出,因此定义数组来存储景点即可!
String[] scenicArr = {"A", "B", "C", "D"};
// 2.利用随机数模拟80名学生投票,并将投票结果存储起来
// 创建List集合,用于存储学生的投票结果
ArrayList<String> voteList = new ArrayList<>();
// 创建随机数对象,用于生成一个随机数
Random rd = new Random();
// 循环80次,模拟80名学生投票
for (int i = 0; i < 80; i++) {
// 每循环1次,就随机生成一个随机索引
int rdIndex = rd.nextInt(scenicArr.length);
// 每循环1次,就根据随机索引进行投票,得到投票结果
String vote = scenicArr[rdIndex];
// 将投票结果存储到voteList集合中
voteList.add(vote);
}
// 3.统计80名学生的投票结果
// 如果要统计的东西比较多,不方便使用计算器思想,此时可以使用Map集合进行统计
// 创建HashMap集合,键:景点;值:投票次数
HashMap<String, Integer> hm = new HashMap<>();
// 遍历voteList集合,依次得到所有学生的投票结果
for (String scenicName : voteList) {
// (1)判断该景点在Map集合中是否已存在
if (hm.containsKey(scenicName)) {
// 是,则说明存在,该景点已经投过票了,在原有的票数上 +1
// 根据键:景点 获取对应的 值:票数
int voteNumber = hm.get(scenicName);
// 该景点又被投了1次,票数+1
voteNumber++;
// 将新的票数再次添加到集合中
hm.put(scenicName, voteNumber);
} else {
// 否,则说明不存在,将该景点存入集合中,票数记录1
hm.put(scenicName, 1);
}
}
// 4.统计出最终哪个景点想去的人数最多(最大值)
hm.forEach((scenicName, voteNumber) -> System.out.println("景点" + scenicName + "=" + voteNumber + "票"));
// 定义最大值变量,初始值为0
int max = 0;
// 获取所有键值对的Set集合
Set<Map.Entry<String, Integer>> entries = hm.entrySet();
// 遍历集合,得到每个键值对对象
for (Map.Entry<String, Integer> entry : entries) {
// 获取票数
int voteNumber = entry.getValue();
// 判断当前获取到的票数是否大于最大值
if (voteNumber > max) {
// 是,则替换最大值为当前票数
max = voteNumber;
}
// 否,则继续获取下一个票数进行判断
}
// 循环结束,最大值已求出
// 6.判断哪个景点的票数与最大值一样,如果一样,打印出来!
// 遍历集合,得到每个键值对对象
for (Map.Entry<String, Integer> entry : entries) {
// 判断当前获取到的票数是否等于最大值
if (entry.getValue() == max) {
// 是,则输出提示!
System.out.println("想去" + entry.getKey() + "景点的同学比较多~");
}
// 否,则继续获取下一个票数进行判断
}
}
}
测试结果
景点A=16票
景点B=25票
景点C=22票
景点D=17票
想去B景点的同学比较多~
Process finished with exit code 0