逻辑错误;名称搜索编程挑战 Java

Logical Error; Name Search Programming Challenge Java

我正在为我的 Intro Java class 准备一个编程挑战。问题是编写一个程序,将最流行的名字(一个 'boys' 和另一个 'girls')的两个 .txt 文件存储到一个 ArrayList 中,并要求用户输入一个名字,程序将告诉用户它是否是最受欢迎的。为了减轻一些混乱,我没有使用 FileReader 或 BufferedReader。

.txt 文件格式为“1 Jacob”列表格式。这是我的错误弹出的地方。如果我在程序中输入 "Jacob",它会告诉我它不在列表中,但如果我输入“1 Jacob”,它会说它在列表中。有没有办法省略列表中的所有整数和制表符空间?还是有更好的方法来解决这个编程挑战?

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;


public class NameSearch {

public static void main(String args[]) throws IOException {

        //Open files and add to ArrayList
        Path boyNames = Paths
                .get("BoyNames.txt")
                .toAbsolutePath();

        List<String> boys = Files.lines(boyNames)
                .collect(Collectors.toList());

        Path girlNames = Paths
                .get("GirlNames.txt")
                .toAbsolutePath();

        List<String> girls = Files.lines(girlNames)
                .collect(Collectors.toList());

        //Ask user for input
        Scanner keyboard = new Scanner(System.in);

        System.out.println("Enter a Boy or Girl's name to see if it's a popular name: ");

        String name = keyboard.nextLine();

        keyboard.close();

        //Compare user input with ArrayList and print
        if (boys.contains(name) || girls.contains(name))
        {
            System.out.println(name + " is a popular name!");
        }

        else
        {
            System.out.println("Sorry, " + name + " is not a popular name.");
        }
    }
}

当您逐行读取文件时,它会按原样添加该行:例如“1 Jacob”。如果只需要添加名称,如 "Jacob",则需要拆分字符串。为简单起见,您可以将以下内容添加到您的代码中:

List<String> girlNames = new ArrayList<String>();
for (String girl: girls){
    girlNames.add(girl.split(" ")[1]);
}

您可以对 "boys" 执行相同的操作。而在比较部分,您只需要检查仅包含名称的集合:

if (boyNames.contains(name) || girlNames.contains(name))
{
    System.out.println(name + " is a popular name!");
}

如果认为合适,您可以通过简单地添加 map 操作来删除名称前面的前缀,如下所示:

List<String> boys = Files.lines(boyNames)
                         .map(s -> s.substring(s.indexOf(" ") + 1))
                         .collect(Collectors.toList());

另一个列表也一样:

List<String> girls = Files.lines(girlNames)
                          .map(s -> s.substring(s.indexOf(" ") + 1))
                          .collect(Collectors.toList());

但是,如果您无法修改在那个时间点传入的数据,那么您可以从列表创建流并执行 map 操作并收集到新列表中:

List<String> tempBoys = boys.stream()
                            .map(s -> s.substring(s.indexOf(" ") + 1))
                            .collect(Collectors.toList());

另一个列表也一样:

List<String> tempGirls = girls.stream()
                .map(s -> s.substring(s.indexOf(" ") + 1))
                .collect(Collectors.toList());

然后把条件改成:

if (tempBoys.contains(name) || tempGirls.contains(name)){ ... }

很简单:

List<String> boys = Files.lines(boyNames)
            .map(name -> name.replaceAll("\d", "")) // remove numeric values
            .map(name -> name.replaceAll(" ", ""))   // remove spaces
            .collect(Collectors.toList());

 List<String> girls = Files.lines(girlNames)
                .map(name -> name.replaceAll("\d", "")) // remove numeric values
                .map(name -> name.replaceAll(" ", ""))   // remove spaces
                .collect(Collectors.toList());