小明来到某学校当老师,需要将学生按考试总分或单科分数进行排名。输入包括学生人数、科目数量、科目名称、每个学生的姓名和对应科目的成绩,最后输入一个用作排名的科目名称。如果输入的排名科目不存在,则按总分进行排序。输出一行,按成绩排序后的学生名字,名字之间用空格隔开。成绩相同的按照学生姓名字典顺序排序。
输出一行,按成绩排序后的学生名字,名字之间用空格隔开。
示例1:
3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 95
minmin 100 82
shuxue
xiaohua fangfang minmin
说明:按shuxue成绩排名,依次是xiaohua、fangfang、minmin。
示例2:
3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 95
minmin 90 95
zongfen
fangfang minmin xiaohua
说明:排序科目不存在,按总分排序,fangfang和minmin总分相同,按姓名的字典顺序,fangfang排在前面。
import lombok.Data;
import lombok.Getter;
import java.io.Serializable;
@Data
public class Student implements Serializable {
// 获取学生姓名的方法
@Getter
private String name;
private int[] scores;
// 假设有一个构造函数来初始化这些字段
public Student(String name, int[] scores) {
this.name = name;
this.scores = scores;
}
// 获取科目成绩的方法
public int getScores(int index) {
return scores[index];
}
// 如果需要,可以添加计算总分的方法
public int getTotalScore() {
int total = 0;
for (int score : scores) {
total += score;
}
return total;
}
public Student getStudent() {
return new Student(name, scores);
}
}
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class SmartGradeSheet {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // 学生人数
int m = scanner.nextInt(); // 科目数量
scanner.nextLine(); // 跳过行尾
String[] subjects = scanner.nextLine().split("\\s+"); // 读取科目名称
List<Student> students = new ArrayList<>();
for (int i = 0; i < n; i++) {
String[] inputs = scanner.nextLine().split("\\s+");
String name = inputs[0];
int[] scores = new int[m];
for (int j = 1; j <= m; j++) {
scores[j - 1] = Integer.parseInt(inputs[j]);
}
students.add(new Student(name, scores));
}
String rankingSubject = scanner.nextLine(); // 读取用作排名的科目名称
Comparator<Student> comparator = null;
if (contains(subjects, rankingSubject)) {
// 按指定科目成绩排序
int subjectIndex = getIndex(subjects, rankingSubject);
comparator = Comparator.comparingInt( (**Student student**) -> student.getScores(subjectIndex))
.thenComparing(Student::getName, Comparator.naturalOrder());
} else {
// 按总分排序
comparator = Comparator.comparingInt(Student::getTotalScore)
.thenComparing(Student::getName);
}
students.sort(comparator);
// 输出结果
for (int i = 0; i < students.size(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(students.get(i).getName());
}
System.out.println();
scanner.close();
}
// 辅助方法:检查科目名称是否存在于数组中
private static boolean contains(String[] array, String target) {
for (String item : array) {
if (item.equals(target)) {
return true;
}
}
return false;
}
// 辅助方法:获取科目名称在数组中的索引
private static int getIndex(String[] array, String target) {
for (int i = 0; i < array.length; i++) {
if (array[i].equals(target)) {
return i;
}
}
throw new IllegalArgumentException("Subject not found: " + target);
}
// 注意:这里需要给Student类添加getTotalScore()方法,但为了简洁,我直接在构造函数中计算了总分
// 如果需要,可以添加如下方法到Student类中
// public int getTotalScore() {
// return totalScore;
// }
}
记一下写代码过程中提示的报错:
最先:
comparator = Comparator.comparingInt( student -> student.getScores(subjectIndex))
SmartGradeSheet.java:41:68 java: 找不到符号 符号: 方法 getScores(int) 位置: 类型为java.lang.Object的变量 student。 网上查了说这种是因为 Student类缺少了getScores(int subjectIndex)方法,但实际是有的。 继续排查说:Comparator 中的 student 被隐式地当作 java.lang.Object 类型处理,而不是 Student 类型,但实际早就定义为了Comparator<Student>,所以问题不在这里。 最后发现: 应该使用 (Student student) -> student.getScores(subjectIndex) 明确指定 student 的类型为 Student
在 Java 中,Lambda 表达式的参数类型可以通过类型推断来确定。然而,在某些情况下,类型推断可能会出现问题,导致编译器无法正确识别参数类型。以下是一些具体的原因和解释: