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.