我正在寻找如何完成这项任务的想法。所以我将从我的程序如何工作开始。
我的程序读取CSV文件。它们是由逗号分隔的键值对。
L1234456,ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie
L6789101,zgna-3mcb-iiiv-pppp-a8yr-c3d2-ct7v-gggg-zz33-33ie
等
Function接受一个文件并将其解析为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;
}
这是代码,我在这里调用parse文件并传入CSV文件。
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");
}
}
问题在于我需要对两个keyvalue对进行清理,创建一个无法清理的keyValue对的单独列表,以及清理它们的列表,以便将它们插入到数据库中。那些不能打印出来的用户。
我考虑过循环思考记录并使用“CouldNotBeParsed”文本删除记录,以便只留下可以解析的记录。我还尝试从for循环期间删除记录Records.remove((i));然而,这会弄乱For循环,因为如果第一个记录无法清理,那么它被删除,在循环的下一次迭代中它被跳过,因为记录2现在是记录1.这就是为什么我去添加文本。
目前我需要两个列表,一个用于已经过消毒的记录,另一个用于未经过消毒的记录。
所以我认为必须有更好的方法来做到这一点。或者是同时消毒keyValue对的更好方法,或者是那种性质的东西。建议?
答案 0 :(得分: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);
}
现在你有一个单一的函数产生一个结果,你的所有记录都干净地分成三个桶 - 即清理过的记录,带坏键的记录,以及带有好键但是值不好的记录。