Univocity - 将每个 TSV 文件行解析为不同类型的 class 对象
Univocity - parse each TSV file row to different Type of class object
我有一个 tsv
文件,它有固定的行,但每一行都映射到不同的 Java Class。
例如
recordType recordValue1
recordType recordValue1 recordValue2
第一行我有以下内容 class:
public class FirstRow implements ItsvRecord {
@Parsed(index = 0)
private String recordType;
@Parsed(index = 1)
private String recordValue1;
public FirstRow() {
}
}
第二行我有:
public class SecondRow implements ItsvRecord {
@Parsed(index = 0)
private String recordType;
@Parsed(index = 1)
private String recordValue1;
public SecondRow() {
}
}
我想将 TSV 文件直接解析为相应的对象,但我缺乏想法。
使用 InputValueSwitch
。这将匹配每行特定列中的值以确定要使用的 RowProcessor
。示例:
为您需要处理的每种类型的记录创建两个(或更多)处理器:
final BeanListProcessor<FirstRow> firstProcessor = new BeanListProcessor<FirstRow>(FirstRow.class);
final BeanListProcessor<SecondRow> secondProcessor = new BeanListProcessor<SecondRow>(SecondRow.class);
创建 InputValueSwitch
:
//0 means that the first column of each row has a value that
//identifies what is the type of record you are dealing with
InputValueSwitch valueSwitch = new InputValueSwitch(0);
//assigns the first processor to rows whose first column contain the 'firstRowType' value
valueSwitch.addSwitchForValue("firstRowType", firstProcessor);
//assigns the second processor to rows whose first column contain the 'secondRowType' value
valueSwitch.addSwitchForValue("secondRowType", secondProcessor);
照常解析:
TsvParserSettings settings = new TsvParserSettings(); //configure...
// your row processor is the switch
settings.setProcessor(valueSwitch);
TsvParser parser = new TsvParser(settings);
Reader input = new StringReader(""+
"firstRowType\trecordValue1\n" +
"secondRowType\trecordValue1\trecordValue2");
parser.parse(input);
从您的处理器中获取已解析的对象:
List<FirstRow> firstTypeObjects = firstProcessor.getBeans();
List<SecondRow> secondTypeObjects = secondProcessor.getBeans();
输出将是*:
[FirstRow{recordType='firstRowType', recordValue1='recordValue1'}]
[SecondRow{recordType='secondRowType', recordValue1='recordValue1', recordValue2='recordValue2'}]
- 假设您在 classes
中实现了一个合理的 toString()
如果您想管理已解析对象之间的关联:
如果您的 FirstRow
应该包含为 SecondRow
类型的记录解析的元素,只需覆盖 rowProcessorSwitched
方法:
InputValueSwitch valueSwitch = new InputValueSwitch(0) {
@Override
public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
if (from == secondProcessor) {
List<FirstRow> firstRows = firstProcessor.getBeans();
FirstRow mostRecentRow = firstRows.get(firstRows.size() - 1);
mostRecentRow.addRowsOfOtherType(secondProcessor.getBeans());
secondProcessor.getBeans().clear();
}
}
};
- 以上假设您的
FirstRow
class 有一个 addRowsOfOtherType
方法,该方法将 SecondRow
列表作为参数。
就是这样!
您甚至可以混合搭配其他类型的RowProcessor
。还有另一个例子 here 证明了这一点。
希望这对您有所帮助。
我有一个 tsv
文件,它有固定的行,但每一行都映射到不同的 Java Class。
例如
recordType recordValue1
recordType recordValue1 recordValue2
第一行我有以下内容 class:
public class FirstRow implements ItsvRecord {
@Parsed(index = 0)
private String recordType;
@Parsed(index = 1)
private String recordValue1;
public FirstRow() {
}
}
第二行我有:
public class SecondRow implements ItsvRecord {
@Parsed(index = 0)
private String recordType;
@Parsed(index = 1)
private String recordValue1;
public SecondRow() {
}
}
我想将 TSV 文件直接解析为相应的对象,但我缺乏想法。
使用 InputValueSwitch
。这将匹配每行特定列中的值以确定要使用的 RowProcessor
。示例:
为您需要处理的每种类型的记录创建两个(或更多)处理器:
final BeanListProcessor<FirstRow> firstProcessor = new BeanListProcessor<FirstRow>(FirstRow.class);
final BeanListProcessor<SecondRow> secondProcessor = new BeanListProcessor<SecondRow>(SecondRow.class);
创建 InputValueSwitch
:
//0 means that the first column of each row has a value that
//identifies what is the type of record you are dealing with
InputValueSwitch valueSwitch = new InputValueSwitch(0);
//assigns the first processor to rows whose first column contain the 'firstRowType' value
valueSwitch.addSwitchForValue("firstRowType", firstProcessor);
//assigns the second processor to rows whose first column contain the 'secondRowType' value
valueSwitch.addSwitchForValue("secondRowType", secondProcessor);
照常解析:
TsvParserSettings settings = new TsvParserSettings(); //configure...
// your row processor is the switch
settings.setProcessor(valueSwitch);
TsvParser parser = new TsvParser(settings);
Reader input = new StringReader(""+
"firstRowType\trecordValue1\n" +
"secondRowType\trecordValue1\trecordValue2");
parser.parse(input);
从您的处理器中获取已解析的对象:
List<FirstRow> firstTypeObjects = firstProcessor.getBeans();
List<SecondRow> secondTypeObjects = secondProcessor.getBeans();
输出将是*:
[FirstRow{recordType='firstRowType', recordValue1='recordValue1'}]
[SecondRow{recordType='secondRowType', recordValue1='recordValue1', recordValue2='recordValue2'}]
- 假设您在 classes 中实现了一个合理的 toString()
如果您想管理已解析对象之间的关联:
如果您的 FirstRow
应该包含为 SecondRow
类型的记录解析的元素,只需覆盖 rowProcessorSwitched
方法:
InputValueSwitch valueSwitch = new InputValueSwitch(0) {
@Override
public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
if (from == secondProcessor) {
List<FirstRow> firstRows = firstProcessor.getBeans();
FirstRow mostRecentRow = firstRows.get(firstRows.size() - 1);
mostRecentRow.addRowsOfOtherType(secondProcessor.getBeans());
secondProcessor.getBeans().clear();
}
}
};
- 以上假设您的
FirstRow
class 有一个addRowsOfOtherType
方法,该方法将SecondRow
列表作为参数。
就是这样!
您甚至可以混合搭配其他类型的RowProcessor
。还有另一个例子 here 证明了这一点。
希望这对您有所帮助。