2012-06-27 3 views
0

XML 파일에서이 코드를 읽습니다. 5 개의 문자열 (groupId, groupType, filePath, author 및 lineNo)을 가져오고 먼저 문자열 배열에 저장합니다. 그런 다음 String Array가 ArrayList에 저장됩니다. 마지막으로, 마지막 "for"는 ArrayList의 내용을 표시합니다.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 
... 
+0

하면, 오류가이 같은 코드를 "단계별"때 신속하게 명백해질 것이다 디버거와 좋은 IDE를 처리하는 방법을 알 필요가 날 것으로 보인다. –

답변

3

문제 때 I 내용을 표시하고 싶습니다. 마지막으로 추가 된 문자열 배열을 얻습니다.

아니, 당신은 당신이 추가 한 것 때문에 원하는 작업 ... 같은 문자열 배열에 많은 참조를 가지고 것을 찾을 수 있습니다. 문자열 배열이 하나뿐입니다 객체; developerInfo은 해당 배열에 대한 참조 일뿐입니다. developerTypes.add(developerInfo)으로 전화하면 참조 번호가 ArrayList으로 복사되므로 동일한 참조 정보가 많이 있습니다.

당신은 루프에 developerInfo의 선언 및 인스턴스화를 끌어해야

:

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"); 
} 

또는 : 당신이 그것을 사용하기 전까지는 developerInfoR을 선언하지 않은 경우

String[] developerInfo = { 
    groupId, 
    groupType, 
    filePath.substring(1, filePath.lastIndexOf(".")), 
    author, 
    lineNo 
}; 
developerTypes.add(developerInfo); 

는 마찬가지로 코드가 청소기 것 향상된 루프를 사용하는 것이 더 좋습니다.

for (String[] developerInfoR : developerTypes) { 
    for (String info : developerInfoR) { 
     System.out.print(info + " "); 
    } 
    System.out.print("\n"); 
} 

일반적으로에서 가능한 한 늦게 가져갈 수있는 가장 작은 범위의 로컬 변수를 선언하여 선언 시점에 값을 이상적으로 할당해야합니다. 메소드 상단의 모든 변수를 선언하면 가독성이 크게 떨어집니다.

+1

또한 C 프로그래머를 쉽게 식별 할 수 있습니다. – Charles

+0

@Charles C 프로그래머는 아니지만 K & R 스타일의 C 프로그래머는 마음이 있습니다. :) –

2

당신은 당신이 루프에서 반복해서 추가 지키는 developerInfo 배열의 하나의 인스턴스 만 있습니다. 각 루프 단계에서 새 배열을 만들어야합니다.

사용중인 contsructs의 의미에 대한 약간의 오해가있는 것 같습니다. 나는 당신이 앞에서 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 + "]"; 
    } 
0

ArrayList에 추가 할 때마다 동일한 배열을 참조하고 있습니다. 대신 처음에이 String[] developerInfo = {null, null, null, null, null};

을 선언

. 반복 할 때마다 새 배열을 만듭니다.

String[] developerInfo = new String[5];