Как мне узнать, содержится ли ключ в Hashmap без имени в Hashmap?Java, JavaFX - PullRequest
0 голосов
/ 26 ноября 2018

В настоящее время я работаю над заданием для школы, где я должен создать хеш-карту в хеш-карте, например:

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

По словам профессора, никаких других карт не требуетсявыполнить задание.Карты добавляют к ним элементы, получая доступ к файлам в пакете, которые содержат имена, пол и ранг имен детей по годам.Когда программа скомпилирована и завершена, создается диаграмма 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, который настроен в этом формате (String year, HashMap (String name, Integer rank))

Любая помощь или руководство будет с благодарностью!

Дополнительные примечания: Раздел JavaFx для диаграммы предоставлен профессором.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Чтобы получить доступ к внутренней хэш-карте, не зная ключа внешней карты, вы можете перебирать каждую запись внешней карты.

for(Map.Entry<String, Integer> mapEntry: boysByYear.entrySet()){
// Get the innerMap and check if the name exists
    Map<String, Integer> innerMap = mapEntry.getValue();
        if(innerMap.containsKey(name)){
            return true;
        }
}

0 голосов
/ 26 ноября 2018

Одна вещь, которую вам нужно исправить в первую очередь, это сравнение строк с использованием ==.Это не работает, если только строка, переданная как параметр gender, не является строковым литералом.Вместо этого вам нужно использовать equals, см. Как сравнить строки в 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;
    }

}
...