我正在尝试将纯文本文件解析为ArrayList
Objects
。问题是它有某种嵌套结构。数据如下所示:
S 183166621 75783-29-8 0 -1 0 0 0 0
SS 183166621 0 DE Siloxane und Silikone, di-Me, polymers mit bor oxid (B2O3)
SS 183166621 0 EN Siloxanes and Silicones, di-Me, polymers with boron oxide (B2O3)
S 183166624 3087-36-3 221-410-8 0 -1 0 0 0 0
SS 183166624 0 DE Titan(4+)ethanolat
SS 183166624 0 EN Ethanol, titanium(4+) salt
所以有一行以“S”开头,代表某种物质。每个“S”行后面跟着多个“SS”行,其中包含不同语言中相应物质的同义词。同义词的数量不固定。有些只有2个,有些有3个,4个或更多。
我的想法是创建一个Substance Object
,其中包含一个包含所有可能的同义词的列表。
我创建了一个BufferedReader
并尝试逐行解析文件
String line;
while((line = br.readLine()) != null) {
if (line.startsWith("S\t")) {
Substance substance = new Substance();
String[] columns = line.split("\t");
// Parse columns and store them in substance Object
}
}
要读取同义词,我想启动第二个内部循环,解析以“SS”开头的所有行。当到达另一个“S”时,内循环停止。
String line;
while((line = br.readLine()) != null) {
if (line.startsWith("S\t")) {
Substance substance = new Substance();
String[] columns = line.split("\t");
// Parse columns and store them in substance Object
while((line = br.readLine()) != null) {
if (line.startsWith("SS\t")) {
Synonym synonym = new Synonym();
// Parse columns and store them in synonym Object
// Add synonym to List of Synonyms of Substance
substance.addSynonym(synonym);
}
else {
break;
}
}
}
}
这个问题是,在离开内循环后,外循环执行另一个readline()
,因此实际的“S” - 失去了。
有人能指出我正确的方向吗?
答案 0 :(得分:3)
您已经认识到的问题是您从阅读器中读过两次。我只读一次并立即拆分,检查主要物质的第一个标记是S
还是先前读过的主要物质的同义词SS
。为此,您需要在循环之外使用Substance substance;
变量。
String line;
Substance actualSubstance = null;
while((line = br.readLine()) != null) {
String[] columns = line.split("\t");
if (columns[0].equals("S")) {
actualSubstance = new Substance();
// parse main substance
} else if (columns[0].equals("SS")) {
if(actualSubstance != null) {
Synonym synonym = new Synonym();
// parse synonim substance and add to actual main substance
actualSubstance.addSynonym(synonym);
} else {
// bad format of the input file -> handle accordingly
}
} else {
// junk
}
}
答案 1 :(得分:1)
解决此问题的常用方法之一是保持引用变量引用您创建的最后一个Substance对象。您可以在循环外定义变量。
然后你开始解析这些行。
如果该行以单个S
开头,则检查substance
的先前值是否不是null
。如果是这样,您将其添加到物质列表中。然后,您创建一个新的Substance
并将其分配给substance
。
这样,每次点击Substance
行时都会开始新的S
,并在看到新的S
行后立即将其放入列表中。< / p>
在同一循环中,如果该行以SS
开头,则解析同义词,并使用substance.addSynonym
。您知道在此阶段您已经创建了Substance
对象,并且它正在substance
中等待。如果您不确定文件始终以S
开头,建议您检查null
。
最后,在循环结束后,Substance
中的substance
对象尚未提交到列表中,因为没有新的S
行。您只需将其添加到列表中即可。
ArrayList<Substance> list = new ArrayList<>();
String line;
Substance substance = null ;
while((line = br.readLine()) != null) {
if (line.startsWith("S\t")) {
if ( substance != null ) {
list.add( substance );
}
substance = new Substance();
String[] columns = line.split("\t");
// Parse columns and store them in substance Object
else if (line.startsWith("SS\t")) {
Synonym synonym = new Synonym();
// Parse columns and store them in synonym Object
// Add synonym to List of Synonyms of Substance
if ( substance != null ) {
substance.addSynonym(synonym);
}
}
}
list.add( substance );