Find Duplicate Objects in a List using Java

In this post, I will show you how to find duplicate objects in a List using Java’s Comparator interface implementation based on multiple fields in a POJO.

Prerequisites
The following configurations are required in order to run the application
Eclipse
JDK 1.8
Have maven installed and configured
Junit, Mockito, PowerMockito dependency in pom.xml

Now we will see the below steps how to create a maven based Java project in Eclipse
Step 1. Create a standalone maven project in Eclipse

Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.

maven-arctype-quickstart
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : junit
Step 2. Modify the pom.xml file as shown below.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.roytuts</groupId>
    <artifactId>java</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>java</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.version>1.8</jdk.version>
        <junit.version>4.11</junit.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 3. If you see JRE System Library[J2SE-1.5] then change the version by below process

Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.5], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.

Step 4. Create a Model class called Car. So we will determine duplicate car is found based on make, model and year fields.

package com.roytuts.model;
public class Car {
    private String make;
    private String model;
    private int year;
    private boolean turnSignal;
    public Car() {
    }
    public Car(String make, String model, int year, boolean turnSignal) {
        this.make = make;
        this.model = model;
        this.year = year;
        this.turnSignal = turnSignal;
    }
    public String getMake() {
        return make;
    }
    public void setMake(String make) {
        this.make = make;
    }
    public String getModel() {
        return model;
    }
    public void setModel(String model) {
        this.model = model;
    }
    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
    public boolean isTurnSignal() {
        return turnSignal;
    }
    public void setTurnSignal(boolean turnSignal) {
        this.turnSignal = turnSignal;
    }
    public String toString() {
        return "Car [make=" + make + ", model=" + model + ", year=" + year
                + ", turnSignal=" + turnSignal + "]";
    }
}

Step 5. Create CarComparator class to compare each fields of the Car model class

package com.roytuts.comparator;
import java.util.Comparator;
import com.roytuts.model.Car;
public class CarComparator implements Comparator<Car> {
    @Override
    public int compare(Car c1, Car c2) {
        int m = c1.getMake().compareToIgnoreCase(c2.getMake());
        if (m != 0) {
            return m;
        }
        int md = c1.getModel().compareToIgnoreCase(c2.getModel());
        if (md != 0) {
            return md;
        }
        return Integer.compare(c1.getYear(),c2.getYear());
    }
}

Step 6. Create CarUtils class to create utility method for finding duplicates

package com.roytuts.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import com.roytuts.comparator.CarComparator;
import com.roytuts.model.Car;
public class CarUtils {
    public List<Car> getDuplicateCars(final List<Car> cars) {
        List<Car> duplicates = new ArrayList<Car>();
        Set<Car> carSet = new TreeSet<Car>(new CarComparator());
        for (Car car : cars) {
            if (!carSet.add(car)) {
                duplicates.add(car);
            }
        }
        return duplicates;
    }
}

Step 7. Create Junit class called CarTest which will test for duplicate Cars in a List of Cars

package com.roytuts.test;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.roytuts.model.Car;
import com.roytuts.utils.CarUtils;
public class CarTest {
    private CarUtils utils;
    private List<Car> cars;
    @Before
    public void setUp() throws Exception {
        utils = new CarUtils();
        populateCars();
    }
    @After
    public void tearDown() throws Exception {
        cars.clear();
    }
    @Test
    public void testGetDuplicateCars() {
        List<Car> duplicateCars = utils.getDuplicateCars(cars);
        System.out.println("Duplicate cars");
        for (Car car : duplicateCars) {
            System.out.println(car);
        }
    }
    private void populateCars() {
        if (cars != null && !cars.isEmpty()) {
            return;
        }
        cars = new ArrayList<Car>();
        Car car1 = new Car("Tata Motors", "Indica", 1990, true);
        Car car2 = new Car("Tata Motors", "Sumo", 1992, true);
        Car car3 = new Car("Maruti Suzuki", "WagonR", 1990, true);
        Car car4 = new Car("Tata Motors", "Sumo", 1994, true);
        Car car5 = new Car("Tata Motors", "Indica", 1990, true);
        Car car6 = new Car("Maruti Suzuki", "Swift", 2006, true);
        Car car7 = new Car("Hundai", "SX4", 1990, true);
        Car car8 = new Car("Tata Motors", "Zica", 2015, true);
        Car car9 = new Car("Maruti Suzuki", "Dzire", 2008, true);
        Car car10 = new Car("Maruti Suzuki", "Swift", 2006, true);
        cars.add(car1);
        cars.add(car2);
        cars.add(car3);
        cars.add(car4);
        cars.add(car5);
        cars.add(car6);
        cars.add(car7);
        cars.add(car8);
        cars.add(car9);
        cars.add(car10);
    }
}

Step 8. Now run the above Junit test class, you will see the below output

Duplicate cars
Car [make=Tata Motors, model=Indica, year=1990, turnSignal=true]
Car [make=Maruti Suzuki, model=Swift, year=2006, turnSignal=true]

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *