2017-07-11 13 views
3

我想出瞭如何比較兩個ArrayList並將重複項添加到新的ArrayList。對象的ArrayList,比較對象並查找重複項,將對象添加到新的ArrayList中,每個副本只有一次

ArrayList<Student> allStudentsA = assignStudents(); 
    ArrayList<Student> allStudentsB = allStudentsA; 

    for (Student studentA : allStudentsA) { 
     for (Student studentB : allStudentsB) { 
      if (studentA.getId().equals(studentB.getId()) && studentA.getEduNumber() != studentB.getEduNumber()) { 
       duplicateStudents.add(studentB); 
      } 
     } 
    } 

然而,我做到了這一點,我添加每個副本一次,每次在那裏。由於「羅達巴」有7次,因爲她有7個不同的優先次序,所以她被列入名單7 * 6次。繼承人如何打印出:

for (Student student : duplicateStudents) { 
     if (student.getFornavn().equals("Rodaba")) { 
      System.out.println("Name: " + student.getFornavn() + "\t \t" + "EduNumber: " + student.getOptagelsesområde() + "\t" + "Prio: " + student.getPrio()); 
     } 
    } 

有一個聰明的辦法可以避免這種情況,只因爲她已經申請了每個優先增加「Rodaba」一次? 繼承人我的輸出,有沒有辦法只獲得標記的部分? Heres my output, is there a way to only get the marked section

我一直堅持這個很長一段時間。我真的很感激這兩個建議,更好的方式來製作ArrayLists,以及如何找出這個問題。

+0

我認爲使用'Map'可能是一個很好的解決方案。它也消除了嵌套的'for'循環。 –

+0

爲什麼不檢查學生是否已經在列表中?此外,它與此沒有任何關係,但是您可以重寫您的'Student#toString'方法以更加乾淨地打印它 – Nathan

+0

@Nathan問題在於學生將在_n_次列表中,其中_n_是他們優先級的數量有。 –

回答

3

正如我在評論中指出的,你可以簡單地添加它之前檢查一個學生的存在:

ArrayList<Student> allStudentsA = assignStudents(); 
ArrayList<Student> allStudentsB = allStudentsA; 

for (Student studentA : allStudentsA) 
    for (Student studentB : allStudentsB) 
     if (studentA.getId().equals(studentB.getId()) 
      && studentA.getEduNumber() != studentB.getEduNumber()) 
      if (!duplicateStudents.contains(studentB)) 
       duplicateStudents.add(studentB); 

注意如果你推翻的equalshashCode方法,這隻會工作您的Student類,因爲對象沒有相同的引用。

基本上,您將在添加之前檢查Student是否已經在列表中。如果您正確實施了equals方法,學生A將不會等於A,其優先級不同

+0

問題再次出現在它遇到第一個學生時停止添加。所以它只在第25個優先級中添加一次「Rodaba」,因爲我想要的是爲每個優先級添加一次。 –

+0

@LarsChristensen然後回到你的'Student#equals'實現上:即使優先級不同,看起來你的equals方法也會返回true。 – Nathan

+0

你是神的彌敦道,那是問題所在。我編輯了我的equals方法來正確檢查優先級,問題就解決了。 –

1

您可以對流使用不同的方法。例如:

List<Student> allStudentsA = assignStudents(); 
List<Student> duplicateStudents = allStudents.stream() 
    .collect(groupingBy(Student::getId)) 
//Now you've got Map<String, List<Student>> (assuming id is of type String). 
//Id of an user is a key. In value (list) you have all Students with the same id. 
//Now we want to take this lists which have size greater than two and merge them. 
    .values() 
    .stream() 
    .filter(list -> list.size() >= 2) 
    .flatMap(List::stream) 
    .collect(Collectors.toList()); 

(改進是值得歡迎的。)

+1

謝謝你的替代方法。 –