2012-10-11 2 views
2

제가이 문제로 고민하고 있습니다. txt 파일을 읽고 내용을 ArrayList에 넣고 싶습니다. 형식은 다음과 같습니다. :텍스트 파일에서 읽기 및 레코드가 빈 줄로 구분됩니다. (자바)

name    Yoshida Shuhei 
birthday   8-04-1961 
phone   
email    [email protected] 
medicalHistory  None 
address    12 X Street, Suburb, 
        NSW, Australia 


address    13 Y Street, Suburb, VIC, Australia 
name    Kazuo Hirai 
medicalHistory  None 
email    [email protected] 
phone    0987654321 
birthday   26-11-1972 

파일이 여러 환자 기록을 포함하고, 각 환자의 기록에서 레코드가 임의의 순서로 발생할 수있는 블록 (예를 들어 첫 번째 환자의 이름이 먼저지만, 두 번째 환자의 주소이 먼저) 모든 레코드는 공백 행으로 구분됩니다. 내 코드 수,

public static ArrayList<Patient> getData(String fileName) { 
     try { 
       File file = new File(fileName); 
       Scanner reader = new Scanner(file); 
       ArrayList<Patient> recordList = new ArrayList<Patient>(); 
       ArrayList<MedicalHistory> mhList = new ArrayList<MedicalHistory>(); 
       int index = -1; 
       int mh_index = -1; 
       String s; 
       Patient p = null; 
       MedicalHistory mh = null; 
       boolean addressActive = false; 
       boolean mhActive = false; 

       while (reader.hasNext()) { 
        s = reader.nextLine(); 
        Scanner line = new Scanner(s); 
        String cmd; 

        if (!s.trim().isEmpty()) { 
         cmd = line.next(); 

         if (cmd.equalsIgnoreCase("name")) { 
          index++; 
          p = new Patient(); 
          p.setName(line.nextLine()); 
          recordList.add(index, p); 
          addressActive = false; 
          mhActive = false; 

         } else if (cmd.equalsIgnoreCase("address")) { 
          if (line.hasNext()) { 
           p.setAddress(line.nextLine().trim()); 
           recordList.set(index, p); 
          } 
          addressActive = true; 
          mhActive = false; 

         } else if (cmd.equalsIgnoreCase("birthday")) { 
          p.setBirthday(line.nextLine()); 
          recordList.set(index, p); 
          addressActive = false; 
          mhActive = false; 

         } else if (cmd.equalsIgnoreCase("email")) { 
          if (line.hasNext()) { 
           p.setEmail(line.nextLine()); 
           recordList.set(index, p); 
          } 
          addressActive = false; 
          mhActive = false; 

         } else if (cmd.equalsIgnoreCase("phone")) { 
          if (line.hasNextInt()) { 
           p.setPhone(line.nextInt()); 
           recordList.set(index, p); 
          } 
          addressActive = false; 
          mhActive = false; 

         } else if (cmd.equalsIgnoreCase("medicalHistory")) { 
          mh = new MedicalHistory(); 
          //...parse the medicalHistory 
          addressActive = false; 
          mhActive = true; 

         } else if (addressActive) { 
          String address = p.getAddress() + " " + s.trim(); 
          p.setAddress(address); 
          recordList.set(index, p); 

         } else if (mhActive) { 
          //to deal with multiple medical histories 
         } else 
          System.out.println("Error: no command:" + s); 
        } 
       } 
       reader.close(); 
       return recordList; 
      } catch (Exception e) { 
       System.out.println("Error:- " + e.getMessage()); 
       return null; 
      } 
    } 

문제는 다음과 같습니다

, 여기 내 코드는 현재 라인은 빈 줄이 아닌 경우 내 생각은, 환자의 기록을 읽고 환자 객체로 추가하기 시작한다

이름이 일 때만 처리됩니다. 첫 번째 비어 있지 않은 라인은 다른 명령으로 시작하는 경우 (예를 들어 주소로 시작),

어디 ...이 초기화, 프로그램이 오류가 발생합니다) (더 새로운 환자가 없을 것 정확히 p = new Patient()을 입력해야합니다. 명령 순서에 상관없이 환자 기록을 읽은 다음 Patient 객체에 데이터를 저장하는 프로그램입니까?

누구든지 내 코드를 개선하고이 조건을 충족시킬 수 있습니까? 고마워요!

답변

1

각 블록을 파일의 각 값에 매핑하는 HashMap<String,String>으로 읽는 것이 좋습니다. 블록이 끝나면 (즉, 빈 행 또는 파일의 끝이 보일 때) Patient 오브젝트를 올바르게 작성하기 위해 필요한 특정 속성 순서대로 블록을 처리 할 수 ​​있습니다.

. . . 
while (reader.hasNext()) { 
    s = reader.nextLine(); 
    Scanner line = new Scanner(s); 
    String cmd; 

    if (!s.trim().isEmpty()) { 
     if (p == null) { 
      // starting a new block -- create a new patient record 
      p = new Patient(); 
      recordList.add(p); 
     } 

     if (cmd.equalsIgnoreCase("name")) { 
      index++; 
      p.setName(line.nextLine()); 
      addressActive = false; 
      mhActive = false; 
     } else if (cmd.equalsIgnoreCase("address")) { 
      if (line.hasNext()) { 
       p.setAddress(line.nextLine().trim()); 
      } 
      addressActive = true; 
      mhActive = false; 

     } else if (cmd.equalsIgnoreCase("birthday")) { 
      p.setBirthday(line.nextLine()); 
      addressActive = mhActive = false; 
     } else if (cmd.equalsIgnoreCase("email")) { 
      if (line.hasNext()) { 
       p.setEmail(line.nextLine()); 
      } 
      addressActive = mhActive = false; 
     } else if (cmd.equalsIgnoreCase("phone")) { 
      if (line.hasNextInt()) { 
       p.setPhone(line.nextInt()); 
      } 
      addressActive = mhActive = false; 
     } else if (cmd.equalsIgnoreCase("medicalHistory")) { 
      mh = new MedicalHistory(); 
      //...parse the medicalHistory 
      addressActive = false; 
      mhActive = true; 
     } else if (addressActive) { 
      String address = p.getAddress() + " " + s.trim(); 
      p.setAddress(address); 
     } else if (mhActive) { 
      //to deal with multiple medical histories 
     } else 
      System.out.println("Error: no command:" + s); 
     } 
    } else { 
     // blank line indicates end of block 
     p = null; 
    } 
} 
. . . 

참고가 (p에 의해 참조) 현재의 환자 기록을 수정할 때, 당신은 돈 것을 '

또는 현재 논리와 함께, 당신은 당신이 원하는 일을 할을 약간 변경해야 다시 recordList의 요소를 설정해야합니다. 이미 배열 목록에있는 객체를 참조하기 때문에 자동으로 업데이트됩니다. 이것으로, 당신은 index을 전혀 필요로하지 않습니다; recordList 끝에 새 환자 레코드를 추가하고 입력이 여전히 동일한 블록에있는 한 계속 수정하십시오.

+0

OMG에서 실행할 때이 문제를 줄 수 있습니다 .. 스레드로부터 안전하지 않습니다, 그것은 작동! 너는 생명의 은인이야! 도와 줘서 고마워. 나는이 문제를 2 일 동안 붙들 았고, 나는이 논리를 해결할 수 없었다 ... – Carter

1

내 생각은 이름 값 쌍을 저장하기 위해, 해시 테이블을 환자 #을 저장하기 위해 .. 전체 데이터를 저장하는 해시 테이블을 유지하기 위해

Hashtable<Integer,Hashtable<String,String>> ht = new Hashtable<Integer,Hashtable<String,String>>(); 

정수 것이다.

("address","<addr>"), ("name","<name>")

의 HashMap 당신이 다중 스레드 환경 ..

+0

다른 사람의 솔루션을 사용했지만 도움을 주셔서 감사합니다! – Carter

관련 문제