3

この問題で立ち往生しています。助けてください: txt ファイルを読み込んでその内容を ArrayList に入れたいのですが、フォーマットは次のようになります:

name                Yoshida Shuhei
birthday            8-04-1961
phone               0123456789
email               abc@123.com
medicalHistory      None
address             12 X Street, Suburb, 
                    NSW, Australia


address             13 Y Street, Suburb, VIC, Australia
name                Kazuo Hirai
medicalHistory      None
email               xyz@123.com
phone               0987654321
birthday            26-11-1972

ファイルには複数の患者記録が含まれており、各患者記録ブロック内の記録は任意の順序で発生する可能性があり (たとえば、最初の患者の名前が最初に来るが、2 番目の患者の住所が最初に来る)、すべての記録は空白行で区切られます。

私の考えは、現在の行が空白行でない場合、患者の記録を読み始めて患者オブジェクトに追加することです。これが私のコードです:

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

問題は、私のコードは名前が最初に来る場合にしか処理できないことです。最初の空でない行が他のコマンドで始まる場合 (たとえば、addressで始まる)、それに対して初期化されたnew Patient()はなく、プログラムはエラーを取得します...

では、コマンドの順序に関係なく患者の記録を読み取り、そのデータを患者オブジェクトに格納するプログラムであるp = new Patient()を正確にどこに配置すればよいのでしょうか?

誰でも私のコードを改善してこの条件を満たすことができますか? どうもありがとう!

4

2 に答える 2

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、入力が同じブロック内にある限り変更を続けます。

于 2012-10-11T02:38:00.123 に答える
1

私の考えは、ハッシュテーブルを維持して完全なデータを保存することです..

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

患者番号を格納する整数、名前と値のペアを格納するハッシュテーブル。

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

HashMap はスレッド セーフではありません。マルチスレッド環境で実行すると問題が発生する可能性があります。

于 2012-10-11T03:13:25.153 に答える