查看代码很明显,您需要处理三 (3) 个特定的用户输入提示。用户必须提供 First Name,然后用户需要提供 Middle Name,最后用户需要提供 Last Name .与任何输入一样,这些名称中的每一个都需要针对正确的上下文进行验证。这将包括姓名规则,例如,每个人都有一个First Name和Last Name,但不是每个人都有一个Middle Name同时也是第一个和最后一个名称可以包含两个名称词(例如:De Vanderholt)。
当您需要用户填写三个特定提示时,请让他们确切地知道他们在哪里。在屏幕上显示用户预期输入的内容。将每个提示放入一个循环中总是一个好主意,这样可以验证输入,如果有问题,用户有机会提供实际的有效数据(在这种情况下是一个有效的名称)。
在您的代码中,您使用 Scanner#next() 方法来检索 First Name 和 Middle Name(s) 的输入,但是此方法不适用于 multi单词名称,因为 next() 方法是基于标记的。这意味着,如果向 First Name 提示提供了两个单词的名称,则只会检索第一个单词,而第二个单词会自动应用于 Middle Name 提示。你甚至没有机会输入中间名。除非设置特殊代码来处理这种情况,否则这是不好的。在这种情况下,最好不要使用 next() 方法,而只需对 all 提示使用 Scanner#nextLine() 方法。但是请记住,如果您知道用户只会提供一个名称单词,Scanner#next() 方法将可以正常工作,但此方法最好与 Scanner#hasNext() 方法结合使用。
查看您的代码。如前所述,每个人都有一个姓氏,但不是每个人都有一个中间名,那么为什么要有这行代码(除非您的规则包括姓氏可以是什么):
if (lastName.contains("")){
实际上不应该允许出现姓氏不包含任何内容的情况,甚至不要接受这个事实,除非它是中间名。如果提供的姓氏经过验证,那么您将永远不必担心这种情况,除非您的规则当然允许。下面的示例代码不允许这样做。
因为有三个提示,它们基本上做同样的事情并需要相同的基本验证,所以使用辅助方法(getName())来消除重复代码的需要:
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
// First Name:
String firstName = getName(scnr, "First");
// Middle Name:
String middleName = getName(scnr, "Middle");
// Last Name:
String lastName = getName(scnr, "Last");
System.out.println(new StringBuilder("")
.append(lastName).append(", ")
.append(firstName.charAt(0))
.append(". ")
.append(middleName.isEmpty() ? "" : middleName.charAt(0))
.append(middleName.isEmpty() ? "" : ".").toString());
// O R
/*
System.out.println(new StringBuilder("")
.append(lastName).append(", ")
.append(firstName)
.append(" ")
.append(middleName)
.toString());
*/
// O R
/*
System.out.println(new StringBuilder("")
.append(firstName)
.append(" ")
.append(middleName)
.append(middleName.isEmpty() ? "" : " ")
.append(lastName)
.toString());
*/
}
辅助方法(getName()):
private static String getName(final Scanner scnr, final String nameTitle) {
String name = "";
while (name.isEmpty()) {
System.out.print("Enter your " + nameTitle + " Name: --> ");
// Get input and trim off leading/trailing whitespaces, etc
name = scnr.nextLine().trim();
// Is this for a Middle Name?
if (nameTitle.equalsIgnoreCase("middle")) {
// If nothing was supplied then there is no
// middle name so break out of prompt loop.
if (name.isEmpty()) {
break;
}
}
// Validate name...
/* Does the supplied name only contain A to Z characters
in any letter case. Add characters to the regular
expression as you see fit. (?i) means any letter case. */
if (name.matches("(?i)[A-Z. ]+")) {
// Yes, it does...
/* Ensure 'first' character of each name word (if more than one)
is upper letter case. */
String[] tmp = name.split("\\s+");
StringBuilder nme = new StringBuilder("");
for (String str : tmp) {
if (!Character.isUpperCase(str.charAt(0))) {
str = str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
}
if (!nme.toString().isEmpty()) {
nme.append(" ");
}
nme.append(str);
}
name = nme.toString();
}
// No it doesn't so inform User of the mistake and to try again.
else {
System.err.println("Invalid " + nameTitle + " Name Supplied! (" + name + ") Try Again...");
name = ""; // Set to null string so as to re-prompt.
}
}
return name;
}