例子如下:
SEG1|asdasd|20111212|asdsad
SEG2|asdasd|asdasd
SEG3|sdfsdf|sdfsdf|sdfsdf|sdfsfsdf
SEG4|sdfsfs|
基本上,每个 SEG*
行都需要解析为相应的对象,定义每个字段的内容。一些,例如 SEG1
中的第三个字段将被解析为 Date
。
每个对象通常会保持不变,但在某些情况下可能会添加额外的字段,如下所示:
SEG1|asdasd|20111212|asdsad|12334455
目前,我正在考虑使用以下类型的算法:
List<String> segments = Arrays.asList(string.split("\r"); // Will always be a CR.
List<String> fields;
String fieldName;
for (String segment : segments) {
fields = Arrays.asList(segment.split("\\|");
fieldName = fields.get(0);
SEG1 seg1;
if (fieldName.compareTo("SEG1") == 0) {
seg1 = new Seg1();
seg1.setField1(fields.get(1));
seg1.setField2(fields.get(2));
seg1.setField3(fields.get(3));
} else if (fieldName.compareTo("SEG2") == 0) {
...
} else if (fieldName.compareTo("SEG3") == 0) {
...
} else {
// Erroneous/failure case.
}
}
某些字段也可能是可选的,具体取决于要填充的对象。我担心的是,如果我向类中添加新字段,则还需要更新任何使用期望字段计数的检查。我该如何着手解析行,同时允许在类对象中填充新的或修改的字段类型?
最佳答案
如果您可以为所有要解析的类定义一个通用接口(interface),我建议如下:
interface Segment {}
class SEG1 implements Segment
{
void setField1(final String field){};
void setField2(final String field){};
void setField3(final String field){};
}
enum Parser {
SEGMENT1("SEG1") {
@Override
protected Segment parse(final String[] fields)
{
final SEG1 segment = new SEG1();
segment.setField1(fields[0]);
segment.setField1(fields[1]);
segment.setField1(fields[2]);
return segment;
}
},
...
;
private final String name;
private Parser(final String name)
{
this.name = name;
}
protected abstract Segment parse(String[] fields);
public static Segment parse(final String segment)
{
final int firstSeparator = segment.indexOf('|');
final String name = segment.substring(0, firstSeparator);
final String[] fields = segment.substring(firstSeparator + 1).split("\\|");
for (final Parser parser : values())
if (parser.name.equals(name))
return parser.parse(fields);
return null;
}
}
对于每种类型的段,将一个元素添加到枚举中,并在 parse(String[])
方法中处理不同类型的字段。
关于java - 如何将具有不同字段计数的分隔文本行解析为对象,同时允许扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8395641/