我有这段代码,可以读取XML文件。它获取5个字符串(groupId、groupType、filePath、author和lineNo),并首先将它们保存在字符串数组中。然后,字符串数组保存在ArrayList中。最后,最后一个"for“显示ArrayList的内容。
问题是,当我想要显示内容时,我只得到最后添加的字符串数组。以下是代码和输出。有人能想出问题出在哪里吗?
ArrayList<String[]> developerTypes = new ArrayList<String[]>();
String[] developerInfo = {null, null, null, null, null};
String[] developerInfoR = {null, null, null, null, null};
String groupId;
String groupType;
String filePath;
String author;
String lineNo;
SAXBuilder builder = new SAXBuilder();
Document doc = (Document) builder.build("A.xml");
Element clones = doc.getRootElement();
// Loop of clones' children (clone_group)
List<Element> parentElements = clones.getChildren();
for(Element parentElement:parentElements){
// Loop of clone_group's children (clone_fragment)
List<Element> elements = parentElement.getChildren();
for(Element element:elements){
// Loop of clone_fragment's children (blameInfo)
List<Element> childelements = element.getChildren();
for(Element childElement:childelements){
groupId = parentElement.getAttributeValue("groupid");
groupType = parentElement.getAttributeValue("type");
filePath = element.getAttributeValue("file");
author = childElement.getAttributeValue("author");
lineNo = childElement.getAttributeValue("lineNo");
//System.out.print(groupId + " - ");
//System.out.print(groupType + " - ");
//System.out.print(file + " - ");
//System.out.println(author);
developerInfo[0] = groupId;
developerInfo[1] = groupType;
developerInfo[2] = filePath.substring(1, filePath.lastIndexOf("."));;
developerInfo[3] = author;
developerInfo[4] = lineNo;
developerTypes.add(developerInfo);
}// for (blameInfo)
}// for (clone_fragment)
}// for (clone_group)
// Display the content of the Arraylist
for(int i = 0; i< developerTypes.size(); ++i){
developerInfoR = developerTypes.get(i);
for(int j = 0; j< developerInfoR.length; ++j){
System.out.print(developerInfoR[j] + " ");
}
System.out.print("\n");
}输出:
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
309 Type-3 builtin/update-index.c Jonathan Nieder 704
...发布于 2012-06-28 04:09:50
的问题是,当我想要显示内容时,我只得到最后添加的字符串数组。
不,您会发现您有许多对同一字符串数组的引用...因为这是你添加的。您只有一个字符串数组对象;developerInfo只是对该数组的引用。当你调用developerTypes.add(developerInfo)的时候,它会把引用复制到ArrayList中,所以你会得到很多次相同的引用。
您应该将developerInfo的声明和实例化放入循环中:
String[] developerInfo = {
groupId,
groupType,
filePath.substring(1, filePath.lastIndexOf(".")),
author,
lineNo
};
developerTypes.add(developerInfo);同样,如果在使用之前不声明developerInfoR,代码也会更整洁:
for(int i = 0; i< developerTypes.size(); ++i){
String[] developerInfoR = developerTypes.get(i);
for(int j = 0; j< developerInfoR.length; ++j){
System.out.print(developerInfoR[j] + " ");
}
System.out.print("\n");
}或者更好的是,使用增强的for循环:
for (String[] developerInfoR : developerTypes) {
for (String info : developerInfoR) {
System.out.print(info + " ");
}
System.out.print("\n");
}通常,您应该使用尽可能小的作用域声明局部变量,最好是在声明时赋值。在方法的顶部声明所有变量确实会损害可读性。
发布于 2012-06-28 04:09:40
您只有一个在循环中不断添加的developerInfo数组实例。您需要在每个循环步骤中创建一个新数组。
你似乎对你正在使用的结构的语义有一些误解。我是从你预先初始化developerInfoR的方式中推断出来的,但是从来没有使用过这个值。数组变量只包含对数组的引用,所以每次赋值给它时,之前引用的数组都会被遗忘和丢弃。所以,不要预先初始化developerInfo。事实上,你甚至不需要在你使用它的地方声明它。
打印数组内容还有一种更简单的方法:只需调用System.out.println(Arrays.toString(developerInfoR))。这样,您甚至不需要打印代码中的内部循环。
您不需要任何变量groupId、groupType、filePath、author、lineNo。例如,只需编写developerInfo[0] = parentElement.getAttributeValue("groupid");和类似的代码。这使得代码更加明显。但是使用完整的对象而不是String[]可能更有意义。有许多字段,每个字段的含义都隐藏在整数索引后面。
总而言之,考虑到这些建议和一些额外的建议,您的代码可以重写为:
final String path = filePath.substring(1, filePath.lastIndexOf("."));
final Document doc = (Document) new SAXBuilder().build("A.xml");
final List<DeveloperInfo> developers = new ArrayList<String[]>();
for (Element parentElement : doc.getRootElement().getChildren())
for (Element element : parentElement.getChildren())
for (Element childElement : element.getChildren())
developers.add(new DeveloperInfo(
parentElement.getAttributeValue("groupid"),
parentElement.getAttributeValue("type"),
element.getAttributeValue("file"),
path,
childElement.getAttributeValue("author"),
childElement.getAttributeValue("lineNo"),
));
for (DeveloperInfo d : developerTypes) System.out.println(d);DeveloperInfo类:
class DeveloperInfo {
public final String groupId, groupType, filePath, author, lineNo;
public DeveloperInfo(
String groupId, String groupType, String filePath,
String author, String lineNo)
{
this.groupId = groupId; this.groupType = groupType; this.filePath = filePath;
this.author = author; this.lineNo = lineNo;
}
public String toString() {
return "DeveloperInfo [groupId=" + groupId + ", groupType=" + groupType +
", filePath=" + filePath + ", author=" + author + ", lineNo=" + lineNo + "]";
}发布于 2012-06-28 04:10:22
每次将数组添加到ArrayList时,都会引用相同的数组。
而不是声明此String[] developerInfo = {null, null, null, null, null};
在开始的时候。每次循环时创建一个新数组。
String[] developerInfo = new String[5];
https://stackoverflow.com/questions/11234082
复制相似问题