如何判断密钥是否包含在哈希映射中的非命名哈希映射中?Java、JavaFX



我目前正在为学校做一项作业,我应该在这样的哈希图中创建一个哈希图:

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

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

目前,我已经解决了大部分问题,但如果没有第一个哈希映射的密钥,我无法理解如何访问第一个哈希贴图中的哈希映射。我的意思是,我应该通过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是以这种格式设置的(String year,hashmap(String name,Integer rank((

如有任何帮助或指导,我们将不胜感激!

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

首先需要解决的一件事是使用==比较字符串。除非作为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));

BTW:您需要修复读取数据的方式。否则,你每年最多只能得到一个名字&性别,因为您替换了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;
}
}

要在不知道外部映射键的情况下访问内部哈希映射,可以迭代外部映射的每个条目。

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;
}
}

最新更新