ArrayList of objects, compare objects and find duplicates, add object to new ArrayList only once for each duplicate
I've figured out how to compare two ArrayLists and add duplicates to a new 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);
}
}
}
Anyway, I do this, I add each duplicate one time at a time there. Since Rodaba exists 7 times, since it has 7 different priorities, it is added to the list 7 * 6 times. This is how I print:
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());
}
}
Is there a sane way to avoid this and only add Rodaba once for each priority that she applied for? Heres my way out, is there a way to get only the selected section?
I lingered on this for a long time. I would be very grateful for both suggestions to help make ArrayLists better and also how to figure this out.
source to share
As I noted in the comments, you can simply check for one student before adding it:
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);
Note that this will only work if you override the method equals
and hashCode
your class Student
, since objects do not have the same references.
Basically, you will check if Student
the list is on before adding it. If you followed your method correctly equals
, student A will not equal A with a different priority .
source to share
You can use a different approach with streams. For example:
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());
(Improvements are welcome.)
source to share