我在完成编程任务时遇到了一些问题。我想从文件中读取一些行(到目前为止没问题)并将其标记化。每一行都有大约4个令牌,每个令牌应该在列表中找到一个位置。最后,每一行也应该在列表中。
澄清这一点的一个小例子:
文件内容:
foo boo bar
bii buu baa
输出:
[[foo,boo,bar],[bii,buu,baa]]
继承我正在处理的代码
String fileContent = fileloader(file.toString());
List<String> linesList = new ArrayList<String>();
String[] lines = fileContent.split("\n");
for(String line:lines){
String[] splittedLine = line.split("\t");
for(String words:splittedLine){
linesList.add(words);
}
lexiconContent.add(linesList);
linesList.removeAll(linesList);
}
我猜参考文献存在问题,因为第一次迭代效果很好!但在第二次迭代中,它将实际第二内容也复制到第一个(0)
列表位置,依此类推。
最后我得到了类似[[], [], [], []]
答案 0 :(得分:3)
问题在于,您只创建了一个列表,并通过在每次迭代时修改该列表,将该列表的引用添加到外部列表中。因此,对该列表进行的最终修改将反映在所有参考文献中。
您可以通过在循环中每次创建一个新linesList
来解决此问题: -
List<String> linesList = null; // Don't initialize here
String[] lines = fileContent.split("\n");
for(String line:lines){
String[] splittedLine = line.split("\t");
linesList = new ArrayList<String>(); // Initialize a new list everytime.
for(String words:splittedLine){
linesList.add(words);
}
lexiconContent.add(linesList);
}
是的,您还可以将for循环简化为: -
for(String line:lines){
String[] splittedLine = line.split("\t");
lexiconContent.add(new ArrayList<String>(Arrays.asList(splittedLine)));
}
这样,您不必遍历数组,并将单个元素添加到List中。实际上,您根本不需要中间列表。
答案 1 :(得分:0)
在你的代码中......而不是为循环中的每次迭代创建新的ArrayList:for(String line:lines)
你只是在你使用过的ArrayList
的旧对象中添加单词(在嵌套循环中)从外部循环的第一次迭代开始,并在lexiconContent
ArrayList的所有后续索引处存储相同的参考值。在外部循环的每次迭代结束时,您正在清除linesList
。所以最后您将保留在lexiconContent
中有N个条目......其中lexiconContent的每个索引处的元素只是ArrayList(lineList)的单个对象的参考值,它是空的!
You should use following code instead:
String fileContent = fileloader(file.toString());
List<String> linesList = null;
String[] lines = fileContent.split("\n");
for(String line:lines){
List<String> linesList = new ArrayList<String>();
String[] splittedLine = line.split("\t");
for(String words:splittedLine){
linesList.add(words);
}
lexiconContent.add(linesList);
}