原题
7-4 sdut-Colleciton-5 学生信息的添加与查询(HashMap)
分数 20
作者 周雪芹
单位 山东理工大学
设计一个学生信息添加和查询的系统,从键盘读入学生的数据,然后通过屏幕进行显示。
输入格式:
第一行有1个整数N,表示学生数量;
接下来有N行学生数据,分别表示学生的id(编号)、name(姓名)、birthday(生日)、score(成绩)属性的值,关键字(id)相同的记录代表同一个学生(如果id相同,后来读入的学生信息会覆盖已有的学生信息)
输出格式:
按照id从小到大的顺序,输出所有学生的属性名称及属性值,其中score(成绩)保留1位有效数字,具体输出格式见输出样例。
提示:可以利用Student类的toString()方法来实现类对象属性的展示。
输入样例:
5
0001 Mike 1990-05-20 98.5
0002 John 1992-05-20 67
0003 Hill 1994-05-20 36.5
0004 Christ 1996-05-20 86.5
0001 Jack 1998-05-20 96
输出样例:
Student [id=0001, name=Jack, birthday=1998年05月20日, score=96.0]
Student [id=0002, name=John, birthday=1992年05月20日, score=67.0]
Student [id=0003, name=Hill, birthday=1994年05月20日, score=36.5]
Student [id=0004, name=Christ, birthday=1996年05月20日, score=86.5]
答案
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
class Student{
private String id;
private String name;
private String birthday;
private double score;
public Student(String id, String name, String birthday, double score) {
this.id = id;
this.name = name;
this.birthday = birthday;
this.score = score;
}
// Getter和Setter方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
// 重写toString方法,用于输出学生信息
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", birthday=" + birthday + ", score=" + String.format("%.1f", score) + "]";
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 输入学生的数量
int n = sc.nextInt();
// 创建一个TreeMap来存储学生信息,方便输出的时候按学号自动排序
Map<String, Student> stuMap = new TreeMap<>();
// 循环输入学生信息,.trim()可以去除字符串两端的空格,返回一个去除了前导和尾部空格后的结果
for(int i = 0;i<n;i++) {
String id = sc.next().trim();
String name = sc.next().trim();
String birthday = sc.next().trim();
double score = sc.nextDouble();
// 将生日格式化为"yyyy年mm月dd日"的形式
String[] birStrings = birthday.split("-");
birthday = birStrings[0]+"年"+birStrings[1]+"月"+birStrings[2]+"日";
// 创建学生对象并添加到stuMap中
Student student = new Student(id, name, birthday, score);
stuMap.put(id, student);
}
// 遍历stuMap,输出学生信息(利用键值对Map.Entry类,记得先用.entrySet()获取键值对集合)
for (Map.Entry<String, Student> entry : stuMap.entrySet()) {
System.out.println(entry.getValue());
//自动调用student类的tostring,按照提前设置好的格式输出
}
// 关闭Scanner
sc.close();
}
}
String.format("%.1f", score)什么东西?
String类中的format()方法可以用于创建格式化的字符串以及连接多个字符串对象。
String.format("%.1f", score)
是一个用于格式化字符串的方法。它接受一个格式化字符串和一个参数,并返回一个按照指定格式进行格式化后的字符串。
在这个例子中,"%.1f"
是格式化字符串,它表示将参数score
格式化为一个带有一位小数的浮点数。%.1f
中的%
是格式化字符串的标志,表示要进行格式化操作。.1
表示保留一位小数,f
表示格式化为浮点数。
所以,String.format("%.1f", score)
的作用是将score
的值格式化为一个带有一位小数的字符串。例如,如果score
的值为89.567
,那么String.format("%.1f", score)
将返回"89.6"
。
TreeMap<>是什么?
TreeMap是Java中的一种有序映射表,它可以根据键的自然顺序进行排序。
本题中便是可以以String类型的键id进行键值对的排序,因为String
类重写了compareTo
方法,用于比较字符串的大小;在TreeMap
中,当插入键值对时,会使用键的compareTo
方法来确定键的顺序。对于String
类型的键,TreeMap
会调用键的compareTo
方法来比较字符串的大小,并根据比较结果进行排序。当使用TreeMap
来存储学号和学生对象时,由于id是String
类型的,TreeMap
会根据学号字符串的自然顺序进行排序。
如果你想根据自定义的排序规则对键进行排序,可以使用带有比较器的TreeMap构造函数。例如:
TreeMap<KeyType, ValueType> treeMap = new TreeMap<>(comparator);
其中,comparator
是实现了Comparator<KeyType>
接口的比较器对象。
我偏要用HashMap咋办?
Map<String, Student> stuMap = new HashMap<>();
对学号进行排序,将学号存放到List中,利用Collections类里的sort对List进行排序升序
List<String> sortedIds = new ArrayList<>();
//把stuMap中的键集合添加到List sortedIds里面
sortedIds.addAll(stuMap.keySet());
Collections.sort(sortedIds);
for (String id : sortedIds) {
System.out.println(stuMap.get(id));
}