2017-03-26 3 views
0

여기에서 가장 큰 문제는 해시 맵을 완벽하게 이해하지 못하고 일부 튜토리얼을 보면서 조작하는 방법이 아니라는 것입니다. 현명한 영혼이 나를 올바른 방향으로 안내 할 수 있기를 바랍니다..txt 파일을 해시 맵으로 읽어 들이고 조작하기

.txt 파일을 해시 맵으로 읽으려고합니다. 텍스트 파일에는 2006 년 이름의 인기가 포함되어 있습니다. inputFile의 각 행에는 소년 이름과 소녀 이름뿐만 아니라 그 이름이 몇 개인지가 포함되어 있습니다. 예를 들면 다음과 같습니다. 1 Jacob 24,797 Emily 21,365는 파일의 1 행 입력입니다.

소년 이름을 하나의 목록에 넣고 여자 이름을 두 번째 목록에 두어 자신의 현재 위치를 유지함으로써 사용자 jacob을 검색 할 수 있으며 그 해에 1 번 소년 이름이었고 다른 이름도 마찬가지라고 할 수 있습니다. 이전에는 줄 단위로 파일을 읽었을 때 파일에서 내가 찾고있는 이름이 포함 된 줄을 보았습니다. 이것은 효과가 있었지만 소년 이름인지 여자 이름인지 알 수 없었기 때문에 내가 Jacob이 여자들에게 인기가 있었는지 검색했다면, 여전히 1이라고 말할 것입니다. 해시 맵은 이 문제를 해결하는 가장 좋은 방법이지만 실제로 작동시키지는 못합니다.

내 코드

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

샘플 입력 _ : 두 HashMaps을, 소년을위한 하나의 이름과 소녀를위한 하나의 이름 할 것

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 
+0

소년의 이름 뒤에 소녀의 이름이 오는 경우가 항상 있습니까, 아니면 되돌릴 수 있습니까? –

+0

항상 그렇습니다 – Justiciar

+0

(소년이 선택됨) 부품 [0]을보고 그렇지 않으면 부품 [1]을보십시오. – ndlu

답변

0

음, 문제는 이름이 전체 라인에있는 경우

if (line.contains(name)) 

를 사용하여 당신은이 소년의 이름 또는 여자의 이름이 있는지에 대해 확인하고 있다는 점이다. 당신이 할 수있는 일은 그것들을 개별적으로 읽은 다음 점검 할 가치를 결정하는 것입니다.

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 
    } 

} 

스캐너 클래스가 줄을 구문 분석하는 데 사용되며,이 토큰에 의해 토큰, 이름은 소년 또는 소녀입니다 있는지 알 수 읽기 : 당신은 같은 것을 할 수 있습니다. 그런 다음 필요한 이름 만 확인하십시오.

+0

두 개의 if가 아니라 {if else if {}를 사용하는 것이 더 합리적입니다. – ndlu

+0

아니요, {}을 (를) 만족하지 않는 모든 조건이 else 문을 실행할 것이기 때문입니다. 따라서 소년 이름과 일치하지 않는 이름을 가진 경우 else 문에서 해당 조건을 확인하지 않기 때문에 소녀 이름과 일치하지 않더라도 else 블록을 직접 실행합니다. –

+0

해시 맵을 사용하여 나를 잡을 수있는 것처럼 보입니다. 하지만, 원래 가지고 있던 것과 런타임 오류가있었습니다. 그것은 컴파일되었지만 실행 중에 추락했습니다. int의 값을 double 값으로 변경해야했습니다. – Justiciar

0

- 현재 당신이 '소년을 사용하고 있는지 이름을 키와 소녀 이름을 값으로 사용합니다. 이는 원하는 것이 아닙니다. 대신, 두 개의 Map<String, IntTuple> 데이터 구조를 사용하십시오. 여기서 String은 이름이고 IntTuple은 행 번호 (계급) 및이 이름을 가진 사람들의 수입니다.

class IntTuple { 
    final int rank; 
    final int count; 

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

그건 의미가 있습니다. 나는 "열쇠"에 조금 혼란스러워했다. 그 코드와 함께 놀아 보겠습니다. – Justiciar

+0

프론트 엔드 사용자가 이미 섹스를 선택했기 때문에 그의 코드에 따라 두 개의 해시 맵을 만들 필요가 없으므로 하나의 해시 맵만 필요합니다. – ndlu

+0

@Justiciar 예를 들어, 해시 맵에 "1, 24,797"IntTuple 값에 매핑 된 "Jacob"키가 포함되어 있고 "map.get ("Jacob ")"이 반환하면 키를 사용하여 값을 조회 할 수 있습니다 "1, 24,797"값 –

관련 문제