简体   繁体   中英

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. 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. 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. For example: 1 Jacob 24,797 Emily 21,365 would be the input from the file for line 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. 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.

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:

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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