Hi guys,
I am having an issue finding duplicates in an arrayList.
Here is some code

        studentRecords.add(new Student("Jo", "Pip", "JP000", LocalDate.of(1999,9,23), Sex.FEMALE));
        studentRecords.add(new Student("Tara", "Bot", "TB345", LocalDate.of(1991,9,1), Sex.FEMALE));
        studentRecords.add(new Student("Mara", "Lewart", "ML456", LocalDate.of(1988,5,23), Sex.FEMALE));
        studentRecords.add(new Student("Anna", "Clarke", "AC010", LocalDate.of(1999,1,1), Sex.FEMALE));
        studentRecords.add(new Student("Frank", "Boia", "FB300", LocalDate.of(2001,8,13), Sex.MALE));
        studentRecords.add(new Student("Anna", "Clarke", "AC010", LocalDate.of(1999,1,1), Sex.FEMALE));
        studentRecords.add(new Student("Jo", "Pip", "JP000", LocalDate.of(1999,9,23), Sex.FEMALE));

This is the list of student records stored in an ArrayList.
I have to make sure that I identify the duplicates and store the duplicates in another arrayList, duplicateRecords for the sake of argument.
Now, the first thing I tried was to do something like this

public void findDuplicates() {
        if(!studentRecords.isEmpty()) {
            duplicateRecords = new ArrayList<Student>();
            for(int i = 0; i < studentRecords.size(); i++) {
                for(int j = 1; j < studentRecords.size(); j++) {
                    if(studentRecords.get(i).equals(studentRecords.get(j)) && i != j) {
                        duplicateRecords.add(studentRecords.get(i));
                    }
                }
            }
        }
        printDetails(studentRecords);
        System.out.println("############");
        printDetails(duplicateRecords);

    }                   

Which is buggy because, of course, it adds the record for Anna twice. I guess the complexity comes in if there are multiple duplicates, for example what happens if there are 3 records for Anna Clarke? In theory I'd want that to be twice in the duplicateRecords because it is a double duplicate
I can't really think of another approach though, any ideas?

Recommended Answers

That could be much easier amd faster of you sorted the List (or create a sorted copy) first. Then just store every record that's equal to the previous record.

If not... have you tried changing line 5 to
for(int j = i+1; ...
... which should fix it for one …

Jump to Post

Yes, that worked perfectly.

Of course it did! ;)

Glad to have helped
JC

ps: Mark Question Solved?

Jump to Post

All 4 Replies

That could be much easier amd faster of you sorted the List (or create a sorted copy) first. Then just store every record that's equal to the previous record.

If not... have you tried changing line 5 to
for(int j = i+1; ...
... which should fix it for one duplicate, but stilll leaves a problem for multiple duplicates.

That could be much easier amd faster of you sorted the List (or create a sorted copy) first. Then just store every record that's equal to the previous record.

Yes, that worked perfectly.
Here is the code.
I slightly changed the collection, adding 2 duplicates and not only one (Anna is there 3 times):

studentRecords.add(new Student("Jo", "Pip", "JP000", LocalDate.of(1999,9,23), Sex.FEMALE));
        studentRecords.add(new Student("Sean", "Due", "SD230", LocalDate.of(1982,10,2), Sex.MALE));
        studentRecords.add(new Student("Bart", "Dowes", "BD333", LocalDate.of(2000,11,23), Sex.MALE));
        studentRecords.add(new Student("Tara", "Bot", "TB345", LocalDate.of(1991,9,1), Sex.FEMALE));
        studentRecords.add(new Student("Mara", "Lewart", "ML456", LocalDate.of(1988,5,23), Sex.FEMALE));
        studentRecords.add(new Student("Anna", "Clarke", "AC010", LocalDate.of(1999,1,1), Sex.FEMALE));
        studentRecords.add(new Student("Ahmed", "Mohammed", "AM222", LocalDate.of(1990,2,23), Sex.MALE));
        studentRecords.add(new Student("Dan", "Tissip", "DT599", LocalDate.of(1988,4,12), Sex.MALE));
        studentRecords.add(new Student("Frank", "Boia", "FB300", LocalDate.of(2001,8,13), Sex.MALE));
        studentRecords.add(new Student("Anna", "Clarke", "AC010", LocalDate.of(1999,1,1), Sex.FEMALE));
        studentRecords.add(new Student("Darla", "Roberts", "DR432", LocalDate.of(1979,10,10), Sex.FEMALE));
        studentRecords.add(new Student("Jo", "Pip", "JP000", LocalDate.of(1999,9,23), Sex.FEMALE));
        studentRecords.add(new Student("Anna", "Clarke", "AC010", LocalDate.of(1999,1,1), Sex.FEMALE));

then the class Student extends Comparable and overrides compareTo

public class Student implements Comparable<Student> {
....
@Override
    public int compareTo(Student o) {

        return this.name.compareTo(o.name);
    }   
}

and the main class calls the findDuplicates method which has all the logic, sorting the elements and comparing each record to the previous one as you suggested

...
public void findDuplicates() {
        duplicateRecords = new ArrayList<Student>();
        Collections.sort(studentRecords);//sorting the collection
        printDetails(studentRecords);
        System.out.println("############");
        for(int i = 1; i < studentRecords.size(); i++) {
            Student currentStudent = studentRecords.get(i);
            Student previousStudent = studentRecords.get(i - 1);
            if(currentStudent.equals(previousStudent)) {
                duplicateRecords.add(currentStudent);
            }
        }
        printDetails(duplicateRecords);

    }
    ...

This prints

Student [name=Anna, surname=Clarke, studentNumber=AC010, dob=1999-01-01, sex=FEMALE]
Student [name=Anna, surname=Clarke, studentNumber=AC010, dob=1999-01-01, sex=FEMALE]
Student [name=Jo, surname=Pip, studentNumber=JP000, dob=1999-09-23, sex=FEMALE]

Yes, that worked perfectly.

Of course it did! ;)

Glad to have helped
JC

ps: Mark Question Solved?