java - 如何判断某个键是否包含在 Hashmap 中的非命名 Hashmap 中? Java、JavaFX

标签 java javafx hashmap nested

我目前正在为学校做一项作业,我应该在 HashMap 中创建一个 HashMap ,如下所示:

Map<String, Map<String, Integer>> girlsByYear = new HashMap<>();
Map<String, Map<String, Integer>> boysByYear = new HashMap<>();

根据教授的说法,完成作业不需要任何其他 map 。这些 map 通过访问包中的文件来向其中添加元素,这些文件包含姓名、性别和按年份划分的婴儿姓名排名。程序编译并完成后,会创建一个 JavaFX 图表,要求输入女孩或男孩的名字。输入后,图表会按年份显示该名称的受欢迎程度排名。

目前,我已经弄清楚了大部分内容,但我无法理解如何在没有第一个 HashMap 的键的情况下访问第一个 HashMap 中的 HashMap 。我的意思是,我应该由 JavaFX 类的文本框执行检查,检查名称是否在 HashMap 中。这是我的代码:

public class NameHelper {

// Declare the hash maps.
Map<String, Map<String, Integer>> girlsByYear = new HashMap<>();

Map<String, Map<String, Integer>> boysByYear = new HashMap<>();

// Declare addition variables.
String firstWord = "";
String secondWord = "";
String thirdWord = "";
Integer rank;

String fileName;

// This method will load the files from the data package, review the files,
// and add each item respectively to either map.
public void load() throws FileNotFoundException {
    File dir = new File("src/data");
    File [] files = dir.listFiles();

    // for each file in the directory...
    for (File f : files)
    {

        // Get the file name and split the year from it to add to each name.
        String newFileName = f.getName();
        fileName = newFileName.replaceAll("[yobtxt.]","");

        Scanner scanner = new Scanner(f);

        // While the files are not empty.
        while(scanner.hasNextLine()) {

            // If the second column split by a delimiter is M then add the information
            // to the boys.  Else girls.

            String input = scanner.nextLine();  
            // Set the input to string values to enter into each hash map.
            String initial = input.split(",")[1];
            firstWord = fileName;
            secondWord = (input.split(",")[0]).toLowerCase();
            thirdWord = input.split(",")[2];
            rank = Integer.parseInt(thirdWord);

            // Use a switch statements since if statements aren't working.
            switch(initial) {
            case "M":
                boysByYear.put(firstWord, new HashMap<String, Integer>());
                boysByYear.get(firstWord).put(secondWord, rank);


                break;
            case "F":
                girlsByYear.put(firstWord, new HashMap<String, Integer>());
                girlsByYear.get(firstWord).put(secondWord, rank);

                break;
                default:
                    System.out.println("This is an issue");
                    break;
            }

        }

        // Close the scanner.
        scanner.close();

    }

}


// This method will return a sorted set of years by getting the keyset from the hashmaps.
public Set<String> getYears() {

    // Create the set.
    Set<String> set = new HashSet<>();

    // Add all the years of the listed by file name.
    for(String key : girlsByYear.keySet()) {
        set.add(key);
    }

    // Convert the set to a sorted set.
    TreeSet<String> treeSet = new TreeSet<>(set);
    return treeSet;
}

// This method will return true if the supplied name is found in the data structure.
// Use the gender input to determine which map to search by using "containsKey".
public boolean isNamePresent(String name, String gender) {


    if(gender == "M") {


        //Check if the name is within the map's map.
        if(boysByYear.get(name).containsKey(name)) {
            return true;
        }

    }
    else if(gender == "F") {
        if(girlsByYear.containsKey(name.toLowerCase())) {
            return true;
        }
    }
    return false;
}

我需要帮助的部分是 isNamePresent 方法。我需要检查名称是否在以此格式设置的第二个 HashMap 的键中(字符串年份,HashMap(字符串名称,整数排名))

任何帮助或指导将不胜感激!

附加说明:图表的 JavaFx 部分由教授提供。

最佳答案

您首先需要解决的一件事是使用 == 比较字符串。除非作为 gender 参数传递的字符串都是字符串文字,否则这不起作用。您需要使用 equals 代替,请参阅 How do I compare strings in Java? (switch 自动执行此操作)。

此外,您应该通过将映射检索到局部变量来避免重复代码:

Map<String, Map<String, Integer>> map;
switch (gender) {
    case "M":
        map = boysByYear;
        break;
    case "F":
        map = girlsByYear;
        break;
    default:
        return false; // alternatively throw new IllegalArgumentException();
}

要查明是否至少有一个映射包含 name 作为键,请遍历所有值并检查映射:

final String nameLower = name.toLowerCase();
return map.values().stream().anyMatch(m -> m.containsKey(nameLower));
<小时/>

顺便说一句:您需要修复读取数据的方式。否则,由于您替换了 map ,因此您每年最多会获得一个名字和性别。此外,我建议存储 split 的结果,而不是调用它 3 次。另外,不要将字段用作仅在循环中需要的变量,并选择更具描述性的变量名称:

Map<String, Integer> boys = new HashMap<>();
Map<String, Integer> girls = new HashMap<>();

boysByYear.put(fileName, boys);
girlsByYear.put(fileName, girls);

while(scanner.hasNextLine()) {

    // If the second column split by a delimiter is M then add the information
    // to the boys.  Else girls.

    String input = scanner.nextLine();
    String[] parts = input.split(",");

    // Set the input to string values to enter into each hash map.
    String gender = parts[1];

    String name = parts[0].toLowerCase();
    int rank = Integer.parseInt(parts[2]);

    switch(gender) {
        case "M":
            boys.put(name, rank);
            break;
        case "F":
            girls.put(name, rank);
            break;
        default:
            System.out.println("This is an issue");
            break;
    }

}

关于java - 如何判断某个键是否包含在 Hashmap 中的非命名 Hashmap 中? Java、JavaFX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53474076/

相关文章:

java - 将提示文本的样式与 JFXTextField 中的文本分开

java - 按值 Java 对 ObservableList 对象进行排序

java - 为什么不直接比较 e.key 而不是将其分配给变量?

java - 如果使用数组作为HashMap中某个键对应的值,如何获取数组的单个值?

java - 无法使用源选项编译 Java 11 代码

Java:对数字字符串数组进行排序

java - 在 OpenJFX 中使用 SwingNode 出现不满意的链接错误

java - 我可以在不提供 URL 中的端口的情况下访问我的 Spring Boot 应用程序吗?

java - 创建 1MB 字符串的好方法是什么?

java - 为json数据编写junit测试用例