问题描述
我正在尝试创建显示以下内容的排名:
(即使我输入30个值和30个昵称,总共10次)
以下是我的工作代码:
public class Methods {
private static final ArrayList<Double> nbAll = new ArrayList<>();
private static final ArrayList<String> pseudoAll = new ArrayList<>();
public static void test() {
try (Scanner scanner = new Scanner(System.in)) {
System.out.print(ANSI_RED + "Please enter the number of notes you want to calculate : ");
double nb = scanner.nextInt();
String pseudo = scanner.next();
for (int i = 0; i < nb; i++) {
double temp = scanner.nextDouble();
nbAll.add(temp);
}
System.out.println("------------");
System.out.println("Ranking: ");
nbAll.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);
retry();
}
}
我尝试过:为了让第二个for循环强制以字符串形式输入用户名,但它不起作用,而且对于排名,我还没有成功
所需操作屏幕:https://i.imgur.com/0QlGHd8.png
推荐答案
在这种情况下,我个人认为如果您使用HashMap或Map Interface来存储所需的数据可能会更好一些。这类事情相当理想,因为用户名应该是唯一的,并且可以用作关键字,排名可以用作值,因为多个用户可能包含相同的排名值:
Map<String, Integer> map = new HashMap<>();
另一件可能会让工作更轻松的事情是,用户可以在一行中输入排名和与该排名相关的用户名,用空格或制表符或其他任何字符分隔,例如:
Ranking #1:
Enter a Rank value followed by a User Name separated with space,
for example: 250 John Doe. Enter 'd' when done.
Your entry: --> |
当然需要执行验证以确保正确输入,但是使用String#matches()方法和一个小的Regular Expression(Regex)并不是很困难,例如:
if (!myString.matches("^\d+\s+.{1,}$")) {
System.err.println("Invalid Entry! Try again...");
System.err.println();
myString = "";
continue;
}
上面传递给string#matches()方法的正则表达式所做的是,它验证了所提供的用户条目的第一个组件实际上是由一个或多个数字组成的整数值的字符串表示形式。然后,它检查以确保该数值后面至少有一个空格,然后在空格之后,它预计会看到空格后面至少有1个(或更多)个字符,该空格实质上就是用户名。当然,如果用户输入的数据不正确,则会发出无效输入警告,并且用户有机会再次尝试输入。
获取有效的输入后,数据在应用于Map Interface对象之前,当然需要拆分为其各自的数据类型。这当然是通过String#split()方法完成的:
String[] stringParts = myString.split("\s+");
这将创建一个名为string Parts的String[]数组。\s+
正则表达式告诉Split()方法在一个或多个空格' '
(或制表符、换行符
、回车符
、换页符
f
和垂直制表符x0B
)上拆分字符串。这几乎涵盖了用户所需条目的所有案例。
int rank = Integer.parseInt(stringParts[0]);
现在我们需要用户名。因为在本例中,我们还允许使用多个名字,如名字和姓氏,所以将这些名字加在一起会涉及到更多内容,以便从所有名字中生成单个用户名字符串。请记住,我们在空格上拆分数据条目,因此如果有多个名称,string Parts[]数组中可能有两个以上的元素。我们需要构建用户名字符串。我们使用for
循环和StringBuilder类来执行此操作,例如:
String[] stringParts = tmp.split("\s+");
int rank = Integer.parseInt(stringParts [0]);
StringBuilder sb = new StringBuilder("");
for (int i = 1; i < stringParts .length; i++) {
if (!sb.toString().isEmpty()) {
sb.append(" ");
}
sb.append(stringParts [i]);
}
String userName = sb.toString();
好的……现在我们有了用户名,所以让我们确保映射:
中尚未包含具有该用户名的排名:if (map.containsKey(userName)) {
System.err.println("A ranking for '" + userName
+ "' has already been supplied! Try again...");
System.err.println();
myString = "";
continue;
}
如果我们通过了这一点,则一切正常,我们可以将数据添加到映射:
map.put(userName, rank);
这可能看起来有点长篇大论,但在我看来,事实并非如此。以下是正在使用的工作示例或以上全部内容:
Scanner userInput = new Scanner(System.in);
Map<String, Integer> map = new HashMap<>();
int count = 0;
String tmp = "";
while (tmp.isEmpty()) {
System.out.println("Ranking #" + (count+1) + ":");
System.out.print("Enter a Rank value followed by a User Name separated "
+ "with space,
for example: 250 John Doe. Enter 'd' when done.
"
+ "Your entry: --> ");
tmp = userInput.nextLine();
if (tmp.equalsIgnoreCase("d")) {
break;
}
if (!tmp.matches("^\d+\s+.{1,}$")) {
System.err.println("Invalid Entry! Try again...");
System.err.println();
tmp = "";
continue;
}
String[] parts = tmp.split("\s+");
int rank = Integer.parseInt(parts[0]);
StringBuilder sb = new StringBuilder("");
for (int i = 1; i < parts.length; i++) {
if (!sb.toString().isEmpty()) {
sb.append(" ");
}
sb.append(parts[i]);
}
String userName = sb.toString();
if (map.containsKey(userName)) {
System.err.println("A ranking for '" + userName
+ "' has already been supplied! Try again...");
System.err.println();
tmp = "";
continue;
}
count++;
map.put(userName, rank);
tmp = "";
System.out.println();
}
// Sort the map by RANK value in 'descending' order:
Map<String, Integer> sortedMap = map.entrySet().stream().sorted(Map.Entry.<String,
Integer>comparingByValue().reversed()).collect(java.util.stream.Collectors.toMap(Map.Entry::
getKey, Map.Entry::getValue,(e1, e2) -> e1, java.util.LinkedHashMap::new));
// If you want the Rank values sorted in 'Ascending' order then use below instead:
/* Map<String, Integer> sortedMap2= map.entrySet().stream().sorted(Map.Entry.<String,
Integer>comparingByValue()).collect(java.util.stream.Collectors.toMap(Map.Entry::
getKey, Map.Entry::getValue,(e1, e2) -> e1, java.util.LinkedHashMap::new)); */
// Display the rankings in Console Window:
System.out.println();
System.out.println("You entered " + count + " rankings and they are as follows:");
System.out.println();
// Table header
String header = String.format("%-4s %-15s %-6s",
"No.", "User Name", "Rank");
System.out.println(header);
// The header underline
System.out.println(String.join("", java.util.Collections.nCopies(header.length(), "=")));
// The rankings in spaced format...
count = 1;
for (Map.Entry<String,Integer> enties : sortedMap.entrySet()) {
System.out.printf("%-4s %-15s %-6d %n",
String.valueOf(count) + ")",
enties.getKey(),
enties.getValue());
count++;
}
当运行上面的代码时,要求用户提供一个等级值和一个与该等级相关的用户名。然后要求用户输入另一个、另一个和另一个,直到该用户输入"d"(表示Done)。然后,提供的所有条目都会以表格形式显示在控制台窗口中。地图中的排名在显示之前已按降序排序(最高排名在前)。如果您喜欢升序,则也会提供该代码,但当前已将其注释掉。 这篇关于能够在java扫描仪中输入值和字符串来输出排名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!