1

このタスクを達成する方法のアイデアを探しています。それでは、私のプログラムがどのように機能するかから始めましょう。

私のプログラムは CSV ファイルを読み取ります。コンマで区切られたキーと値のペアです。

  L1234456,ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie
  L6789101,zgna-3mcb-iiiv-pppp-a8yr-c3d2-ct7v-gggg-zz33-33ie

関数はファイルを受け取り、それを解析して String[] の arrayList にします。この関数は ArrayList を返します。

    public ArrayList<String[]> parseFile(File csvFile) {
    Scanner scan = null;
    try {
        scan = new Scanner(csvFile);
    } catch (FileNotFoundException e) {

    }

    ArrayList<String[]> records = new ArrayList<String[]>();
    String[] record = new String[2];
    while (scan.hasNext()) {
        record = scan.nextLine().trim().split(",");
        records.add(record);
    }
    return records;
 }

解析ファイルを呼び出して CSVFile を渡すコードは次のとおりです。

  ArrayList<String[]> Records = parseFile(csvFile);

次に、解析されないファイル用に別の ArrayList を作成しました。

  ArrayList<String> NotParsed = new ArrayList<String>();

そのため、プログラムはコンマで区切られたキーと値のペアのサニタイズを続けます。したがって、まずレコードの最初のキーから始めます。例: L1234456。レコードをサニタイズできなかった場合は、現在のキーを "CouldNOtBeParsed" テキストに置き換えます。

for (int i = 0; i < Records.size(); i++) {
        if(!validateRecord(Records.get(i)[0].toString())) {
            Logging.info("Records could not be parsed " + Records.get(i)[0]);
               NotParsed.add(srpRecords.get(i)[0].toString());
            Records.get(i)[0] = "CouldNotBeParsed";
        } else {
            Logging.info(Records.get(i)[0] + " has been sanitized");
        }
    }

次に、ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie など、キーと値のペアの 2 番目のキーを実行します。

for (int i = 0; i < Records.size(); i++) {
        if(!validateRecordKey(Records.get(i)[1].toString())) {
            Logging.info("Record Key could not be parsed " + Records.get(i)[0]);
               NotParsed.add(Records.get(i)[1].toString());
            Records.get(i)[1] = "CouldNotBeParsed";
        } else {
            Logging.info(Records.get(i)[1] + " has been sanitized");
        }
    }

問題は、両方のキーと値のペアをサニタイズする必要があることです。サニタイズできなかったキーと値のペアの別のリストと、サニタイズされたもののリストを作成して、データベースに挿入できるようにします。できないものは、ユーザーに出力されます。

レコードをループし、「CouldNotBeParsed」テキストを含むレコードを削除して、解析できるレコードだけを残すことを考えました。また、 for ループ Records.remove((i)); の間にレコードを削除しようとしました。ただし、最初のレコードをサニタイズできなかった場合は削除され、ループの次の反復ではレコード 2 がレコード 1 になるためスキップされるため、For ループが台無しになります。そのため、テキストを追加しました。

実際には、サニタイズされたレコードとサニタイズされていないレコードの 2 つのリストが必要です。

だから私はこれを行うためのより良い方法があるに違いないと考えていました。または、両方の keyValue ペアを同時にサニタイズするより良い方法、またはその性質の何か。提案?

4

1 に答える 1

1

データ構造を変更することから始めます。2 要素配列のリストを使用するのではなくString[]、キーと値のペアのクラスを定義します。

class KeyValuePair {
    private final String key;
    private final String value;
    public KeyValuePair(String k, String v) { key = k; value = v; }
    public String getKey() { return key; }
    public String getValue() { return value; }
}

クラスは不変であることに注意してください。

次に、オブジェクトの 3 つのリストを持つオブジェクトを作成しKeyValuePairます。

class ParseResult {
    private final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>();
    private final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>();
    private final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>();
    public ParseResult(List<KeyValuePair> s, List<KeyValuePair> bk, List<KeyValuePair> bv) {
        sanitized = s;
        badKey = bk;
        badValue = bv;
    }
    public List<KeyValuePair> getSanitized() { return sanitized; }
    public List<KeyValuePair> getBadKey() { return badKey; }
    public List<KeyValuePair> getBadValue() { return badValue; }
}

最後に、ファイルから読み取る単一のループでこれら 3 つのリストを作成します。

public static ParseResult parseFile(File csvFile) {
    Scanner scan = null;
    try {
        scan = new Scanner(csvFile);
    } catch (FileNotFoundException e) {
        ???
        // Do something about this exception.
        // Consider not catching it here, letting the caller deal with it.
    }
    final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>();
    final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>();
    final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>();
    while (scan.hasNext()) {
        String[] tokens = scan.nextLine().trim().split(",");
        if (tokens.length != 2) {
            ???
            // Do something about this - either throw an exception,
            // or log a message and continue.
        }
        KeyValuePair kvp = new KeyValuePair(tokens[0], tokens[1]);
        // Do the validation on the spot
        if (!validateRecordKey(kvp.getKey())) {
            badKey.add(kvp);
        } else if (!validateRecord(kvp.getValue())) {
            badValue.add(kvp);
        } else {
            sanitized.add(kvp);
        }
    }
    return new ParseResult(sanitized, badKey, badValue);
}

これで、すべてのレコードが 3 つのバケットに明確に分離された単一の結果を生成する単一の関数ができました。つまり、サニタイズされたレコード、キーが不適切なレコード、キーが適切で値が不適切なレコードです。

于 2014-11-14T16:25:17.590 に答える