1

我正在寻找如何完成这项任务的想法。所以我将从我的程序如何工作开始。

我的程序读取一个 CSV 文件。它们是用逗号分隔的键值对。

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

ETC

函数获取一个文件并将其解析为 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

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)); 中删除记录。但是,这会弄乱 For 循环,因为如果无法清理第一条记录,则将其删除,在循环的下一次迭代中,它会被跳过,因为记录 2 现在是记录 1。这就是我添加文本的原因。

Atually 我需要两个列表,一个用于已清理的记录,另一个用于未清理的记录。

所以我在想一定有更好的方法来做到这一点。或者同时清理两个 keyValue 对或类似性质的更好方法。建议?

4

1 回答 1

1

从更改数据结构开始:不要使用二元素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; }
}

请注意,该类是不可变的。

现在创建一个包含三个对象列表的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; }
}

最后,在从文件读取的单个循环中填充这三个列表:

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

现在你有一个函数,它产生一个结果,你的所有记录被干净地分成三个桶 - 即清理记录,带有坏键的记录,以及带有好键但坏值的记录。

于 2014-11-14T16:25:17.590 回答