您对学生人数的while 循环验证有点晚了。您希望在声明和初始化数组之前执行此操作。然而,while 循环实际上被用于尝试某种形式的验证这一事实是一个非常好的迹象。这比大多数新程序员倾向于做的要多。所有输入都应经过验证,并为用户提供提供正确解决方案的机会。这只会为用户带来更流畅、无故障的应用程序和更好的体验。看看你的代码中的这个 while 循环:
while (amount < 0) {
System.out.println("Invalid student amount");
}
如果用户提供-1(这是+1 的有效整数值)会发生什么?没错...您的应用程序将进入无限循环,将Invalid student amount 输出到控制台窗口。您的验证方案应该包含整个提示,然后应该更合理地定义退出它的方法。对于while 循环,最好的退出是通过其条件语句完成,如果条件为假则退出循环,例如:
Scanner scan = new Scanner(System.in);
// Number Of Students...
String inputString = "";
while (inputString.isEmpty()) {
System.out.print("How many students do you have?: --> ");
inputString = scan.nextLine().trim();
/* Is the supplied Number Of Students valid and within
range (1 to 50 inclusive)? */
if (!inputString.matches("\\d+") || Integer.valueOf(inputString) < 1
|| Integer.valueOf(inputString) > 50) {
// No...
System.err.println("Invalid entry (" + inputString + ") for Student "
+ "amount! Try again...");
inputString = ""; // Empty inputString so we loop again.
System.out.println();
}
}
// Valid amount provided.
int amount = Integer.valueOf(inputString);
String[] student = new String[amount];
int grade[] = new int[amount];
您会立即注意到这里有一些明显的变化。整个How many students do you have? 提示包含在while 循环块中。如果用户未提供有效响应,则要求该用户重试。 student 和 grade parallel arrays 仅在为学生人数提供有效响应后声明和初始化。
您还会注意到while 循环条件不依赖于整数值,而是依赖于实际的字符串内容(不管它是什么)。如果变量为空(“”),则再次循环。这是因为Scanner#nextLine() 方法用于收集用户输入,而不是Scanner#nextInt() 方法。提示仍然需要提供一个整数值,只是一个整数值的字符串表示形式,并且使用String#matches() 方法和一个小的Regular Expression(正则表达式)来验证。
出于多种原因,我个人更喜欢使用Scanner#nextLine() 方法。我个人觉得它更灵活,特别是如果您想从单个提示中同时接受 Alpha 和数字输入。如果上面的提示是:
How many students do you have? (q to quit)
您只需在数字验证代码上方添加另一个if 语句,以查看是否提供了“q”或“Q”,例如:
// If either q or Q is entered then quit application.
if (amountString.matches("[qQ]")) {
System.out.println("Bye-Bye");
System.exit(0);
}
另外,通过将一个好的表达式传递给matches()方法,不需要为了进行验证而捕获异常,并不是说这有什么问题,很多人都这样做,我特别不但是当我不需要这样做时。
旁注:我要在这里陈述显而易见的事情,我相信你已经听过一百次了,你已经厌倦了,但我要再告诉你一次:
您的类方法应该以小写字母开头(请参阅Java Naming
Conventions)。
我知道你没有听到编译器抱怨,但它确实使它成为
(有时)更难阅读代码。每个读书的人
你的代码会感谢你的。
因为student 和grade 数组是parallel arrays,您可能希望minGrade() 和maxGrade() 方法返回特定的数组索引值到最低或最高等级,以便可以对包含确定的特定等级的学生建立参考关系。所以,这会更有用:
public static int minGrade(int[] arr, int size) {
// Initialize min to have the highest possible value.
int min = Integer.MAX_VALUE;
int returnableIndex = -1;
// loop to find lowest grade in array
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}
public static int maxGrade(int[] arr, int size) {
int max = Integer.MIN_VALUE;
int returnableIndex = -1;
// loop to find highest grade in array
for (int i = 0; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}
所有内容都在运行,您的代码可能如下所示:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// Number Of Students...
String amountString = "";
while (amountString.isEmpty()) {
System.out.print("How many students do you have?: --> ");
amountString = scan.nextLine().trim();
// Is the supplied Number Of Students valid and within
// range (1 to 50 inclusive)?
if (!amountString.matches("\\d+") || Integer.valueOf(amountString) < 1
|| Integer.valueOf(amountString) > 50) {
// No...
System.err.println("Invalid entry (" + amountString + ") for Student "
+ "amount! Try again...");
amountString = ""; // Empty inputString so we loop again.
System.out.println();
}
}
// Valid amount provided.
int amount = Integer.valueOf(amountString);
// Declare and initialize parallel arrays
String[] student = new String[amount];
int grade[] = new int[amount];
// Student Names and Grade...
for (int i = 0; i < amount; i++) {
// Student Name...
String name = "";
while (name.isEmpty()) {
System.out.print("Enter student #" + (i + 1) + " name: --> ");
name = scan.nextLine().trim();
/* Is the name valid (contains upper or lower case letters from
A-Z and a single whitespaces separating first and last name?
Whitespace and last name is optional. */
if (!name.matches("(?i)([a-z]+)(\\s{1})?([a-z]+)?")) {
// No..
System.err.println("Invalid Student #" + (i + 1) + " name ("
+ name + ")! Try Again...");
System.out.println();
name = ""; // Empty name so we loop again.
}
}
// Valid Student name provided...
student[i] = name;
// Student Grade...
String gradeString = "";
while (gradeString.isEmpty()) {
System.out.print("Enter student #" + (i + 1) + " grade: --> ");
gradeString = scan.nextLine().trim();
// Is the supplied grade valid and within range (0 to 100 inclusive)?
if (!gradeString.matches("\\d+")
|| Integer.valueOf(gradeString) < 0
|| Integer.valueOf(gradeString) > 100) {
// No...
System.err.println("Invalid entry (" + gradeString + ") for "
+ "Student #" + (i + 1) + " grade! Try again...");
gradeString = "";
System.out.println();
}
}
// Valid Student grade provided...
grade[i] = Integer.valueOf(gradeString);
}
// Display everyone's grade
System.out.println();
for (int i = 0; i < amount; i++) {
System.out.println(student[i] + " received the final grade of " + grade[i]);
}
System.out.println();
//Display who is highest and lowest...
int index = maxGrade(grade, amount);
System.out.println("The highest grade in the class was by '" + student[index]
+ "' with a grade of: " + grade[index]);
index = minGrade(grade, amount);
System.out.println("The lowest grade in the class was by '" + student[index]
+ "' with a grade of: " + grade[index]);
}
public static int minGrade(int[] arr, int size) {
// Initialize min to have the highest possible value.
int min = Integer.MAX_VALUE;
int returnableIndex = -1;
// loop to find lowest grade in array
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}
public static int maxGrade(int[] arr, int size) {
int max = Integer.MIN_VALUE;
int returnableIndex = -1;
// loop to find highest grade in array
for (int i = 0; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
returnableIndex = i;
}
}
return returnableIndex;
}