简体   繁体   English

将.txt文件读入Hashmap并进行操作

[英]Reading .txt File into a Hashmap and manipulating it

Most likely my biggest problem here is not fully understanding Hashmaps and how to manipulate them despite looking at some tutorials. 尽管在看了一些教程之后,我最大的问题很可能是没有完全了解Hashmaps以及如何操作它们。 Hopefully you wise souls will be able to point me in the right track. 希望您明智的灵魂能够指出我正确的方向。

I'm trying to read a .txt file into a hashmap. 我正在尝试将.txt文件读入哈希图中。 The text file contains the popularity of names for 2006. Each line of the inputFile contains a boys name and a girls name as well as how many were named that. 文本文件包含2006年流行的名称。inputFile的每一行包含一个男孩名和一个女孩名,以及被命名的名字。 For example: 1 Jacob 24,797 Emily 21,365 would be the input from the file for line 1. 例如:1 Jacob 24,797 Emily 21,365将是文件中第1行的输入。

I want to put the boys name into one list, and the girls names into a second list maintaining their current positions so that the user can search for jacob and be told it was the number 1 boys name that year, and so on for other names. 我想将男孩名字放在一个列表中,并将女孩名字放在第二个列表中,以保持其当前位置,以便用户可以搜索jacob并被告知那是那一年的第一个男孩名字,以此类推。 。 Previously I was just reading the file line by line and seeing what line the file contained the name i was searching for. 以前,我只是逐行读取文件,然后查看文件包含我要搜索的名称的行。 This worked, but it was unable to tell if it was a boys name or a girls name, resulting in errors where if I said i was searching for how popular Jacob was for girls, it would still say number 1. I determined a hashmap would be the best way around this, but can't really get it working. 这行得通,但是无法分辨是男孩还是女孩,这会导致错误,如果我说我正在搜索雅各布在女孩中的流行程度,它仍然会说数字1。我确定哈希表会是解决此问题的最佳方法,但却无法真正发挥作用。

My Code 我的密码

public void actionPerformed(ActionEvent e)
    {
        //Parse Input Fields
        String name = inputArea.getText();
        if (name.equals(""))
        {
            JOptionPane.showMessageDialog(null, "A name is required.", "Alert", JOptionPane.WARNING_MESSAGE );
            return;
        }
        String genderSelected = genderList.getSelectedItem().toString();
        String yearSelected = yearList.getSelectedItem().toString();

        String yearFile = "Babynamesranking"+yearSelected+".txt";    //Opens a different name file depending on year selection    
        boolean foundName = false;
        Map<String, String> map = new HashMap<String,String>(); //Creates Hashmap

        try
        {
            File inputFile = new File(yearFile);                    //Sets input file to whichever file chosen in GUI
            FileReader fileReader = new FileReader(inputFile);      //Creates a fileReader to open the inputFile
            BufferedReader br = new BufferedReader(fileReader);     //Creates a buffered reader to read the fileReader

            String line;
            int lineNum = 1;                                        //Incremental Variable to determine which line the name is found on
            while ((line = br.readLine()) != null)
            {
                if (line.contains(name))
                {
                    outputArea.setText(""+name+" was a popular name during "+yearSelected+".");
                    outputArea.append("\nIt is the "+lineNum+" most popular choice for "+genderSelected+" names that year.");
                    foundName = true;
                }
                String parts[] = line.split("\t");
                map.put(parts[0],parts[1]);

                lineNum++;
            }
            fileReader.close();
        }
        catch(IOException exception)
        {
            exception.printStackTrace();
        }

        String position = map.get(name);
        System.out.println(position);
}

Sample inputFile: 样本inputFile:

1   Jacob   24,797  Emily   21,365
2   Michael 22,592  Emma    19,092
3   Joshua  22,269  Madison     18,599
4   Ethan   20,485  Isabella    18,200
5   Matthew 20,285  Ava     16,925
6   Daniel  20,017  Abigail     15,615
7   Andrew  19,686  Olivia  15,474
8   Christopher 19,635  Hannah  14,515

You'll want two hashmaps, one for boys' names and one for girls' names - at present you're using boys' names as keys and girls' names as values, which is not what you want. 您将需要两个哈希图,一个用于男孩的名字,一个用于女孩的名字-目前,您正在使用男孩的名字作为键,而使用女孩的名字作为值,这不是您想要的。 Instead, use two Map<String, IntTuple> data structures where the String is the name and the IntTuple is the line number (rank) and the count of people with this name. 而是使用两个Map<String, IntTuple>数据结构,其中String是名称, IntTuple是行号(行)和具有此名称的人数。

class IntTuple {
  final int rank;
  final int count;

  IntTuple(int rank, int count) {
    this.rank = rank;
    this.count = count;
  }
}

Well, the problem is that by using 好吧,问题在于

if (line.contains(name))

You're checking if the name exists in the whole line, regarding if it's a boy's name or a girl's name. 您正在检查名称是否存在于整行中,这涉及的是男孩的名字还是女孩的名字。 What you can do is to read them separately, then decide which value you want to check. 您可以做的是分别阅读它们,然后确定要检查的值。 You can do something like this: 您可以执行以下操作:

while ((line = br.readLine()) != null)
{
    Scanner sc = new Scanner(line);
    int lineNumber = sc.nextInt();
    String boyName = sc.next();
    int boyNameFreq = sc.nextInt();
    String girlName = sc.next();
    int girlNameFreq = sc.nextInt();

    if(genderSelected.equals("male") && name.equals(boyName)){
        // .. a boy's name is found
    }
    else if(genderSelected.equals("female") && name.equals(girlName)){
        // .. a girl's name is found
    }

}

Scanner class is used to parse the line, and read it token-by-token, so you can know if the name is for a boy or girl. 扫描程序类用于解析该行,并逐个令牌读取它,因此您可以知道该名称是男孩还是女孩。 Then check on the name that you need only. 然后检查仅需要的名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM