Mike
Mike

Reputation: 7914

remove duplicate object in Java

I've User object a shown below:

User.java:

    public class User {
        public String firstName;
        public String lastName;

        public String getFirstName() {
            return firstName;
        }   
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
        public String getLastName() {
            return lastName;
        }
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        @Override
        public int hashCode() {
            return (this.firstName.hashCode() + this.lastName.hashCode());
        }

        @Override
        public boolean equals(Object obj) {
            if(obj instanceof User) {
                User temp = (User) obj;
                if(this.firstName.equals(temp.firstName) && this.lastName.equals(temp.lastName)) {
                    return true;
                }
            }
            return false;
        }
    }

And main program is shown below:

    import java.util.*; 

    class pp {
        public static void main(String[] args) {
            List<User[]> a = new ArrayList<User[]>();
            User[] u = new User[3];

            u[0] = new User();
            u[0].setFirstName("Mike"); u[0].setLastName("Jordon");      

            u[1] = new User();
            u[1].setFirstName("Jack"); u[1].setLastName("Nicolson");

            u[2] = new User();
            u[2].setFirstName("Jack"); u[2].setLastName("Nicolson");

            a.add(u);

            Set<User[]> s = new HashSet<User[]>(a);

            for (User[] ss : s) {
                for (int i=0; i<ss.length; i++) {           
                    System.out.println(ss[i].getFirstName() + " " + ss[i].getLastName());
                }
            }
        }
    }

I'm expecting output to be

Mike Jordon
Jack Nicolson

But somehow, its retaining duplicate object & printing as:

Mike Jordon
Jack Nicolson
Jack Nicolson

Can any one tell me what I'm missing??

Thanks!

Upvotes: 0

Views: 8000

Answers (9)

Jason
Jason

Reputation: 1241

Your equals method should be like :

  @Override
    public boolean equals(Object obj) {
        if(obj instanceof User) {
            User temp = (User) obj;
            if(this.firstName.equals(temp.firstName) && this.lastName.equals(temp.lastName)) {
                return true;
            }
        }
        return false;
    }

Upvotes: 6

TechieTaught
TechieTaught

Reputation: 1

I have gone through your questions and understood the requirement. Please find the similar kind of code I have implemented and also successfully removed objects from a collection those having duplicate values.

@Snipet...

Employee.java
==============

package com.hcl;

public class Employee {

    public String empid;
    public String empname;
    public double sal;
    public int age;

    public Employee(){

    }

    public Employee(String empid,String empname,double sal,int age){

        this.empid = empid;
        this.empname = empname;
        this.sal = sal;
        this.age = age;
    }

    public String getEmpid() {
        return empid;
    }
    public void setEmpid(String empid) {
        this.empid = empid;
    }
    public String getEmpname() {
        return empname;
    }
    public void setEmpname(String empname) {
        this.empname = empname;
    }
    public double getSal() {
        return sal;
    }
    public void setSal(double sal) {
        this.sal = sal;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * This override method playes a major role to remove duplicate values
     */
    @Override
    public int hashCode() {
        return (this.empid.hashCode() + this.empname.hashCode()+String.valueOf(this.sal).hashCode()+String.valueOf(this.age).hashCode());
    }

    /**
     * This override method plays a major role to remove duplicate values
     */
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Employee) {
            Employee temp = (Employee) obj;

            if(this.empid.equals(temp.empid) && this.empname.equals(temp.empname) && String.valueOf(this.sal).equals(String.valueOf(temp.sal)) && String.valueOf(this.age).equals(String.valueOf(temp.age))) {
                return true;
            }
        }
        return false;
    }

}

@Snipet..........
RemoveDuplicateObjects.java
=============================
package com.hcl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class RemoveDuplicateObjects {


    public static void main(String[] args) {

        Employee emp1 = new Employee("1","bapi",1000,31);
        Employee emp2 = new Employee("2","mano",2000,29);
        Employee emp3 = new Employee("1","bapi",1000,31); // emp3 == emp1 duplicate object
        Employee emp4 = new Employee("3","Rohan",3000,27);
        Employee emp5 = new Employee("1","bapi",1000,31); // emp5 == emp3 == emp1 duplicate object

        RemoveDuplicateObjects obj = new RemoveDuplicateObjects();

        // empList contains objects having duplicate values. How to remove duplicate? 
        List<Employee> empList = new ArrayList<Employee>();
        empList.add(emp1);
        empList.add(emp2);
        empList.add(emp3);
        empList.add(emp4);
        empList.add(emp5);

        if(emp1.equals(emp2)){

            System.out.println("emp1 and emp2 are equal");
        }

        if(emp1.equals(emp3)){
            System.out.println("emp1 and emp3 are equal");
        }
        obj.removeDuplicate(empList);

    }

    // method is used for removing objects having duplicate values
    private void removeDuplicate(List<Employee> empList) {


        Set<Employee> empSet = new HashSet<Employee>();
        empSet.addAll(empList);

        for(Employee e: empSet){

            System.out.println("id = "+e.getEmpid());
            System.out.println("name = "+e.getEmpname());
            System.out.println("sal = "+e.getSal());
            System.out.println("age = "+e.getAge());
        }

    }

}

Done! Now you can run the program and analyze the solution.

Upvotes: 5

Mahesh Gurav
Mahesh Gurav

Reputation: 145

Hi you can write a method in pp class in order to remove duplicate elements from the user array as follows :

private User[] getUserArrayWithoutDuplicates(User[] a) {
    int count = a.length;
    Set<User> tempset = new HashSet<User>();
    for (int i = 0; i < count; i++) {
        User[] user = a;
        int arraysize = user.length;
        for (int j = 0; j < arraysize; j++)
            tempset.add(user[j]);
    }
    User[] usr = new User[tempset.size()];
    Iterator<User> tempIterator = tempset.iterator();
    int p = 0;
    while (tempIterator.hasNext()) {
        User user = tempIterator.next();
        usr[p] = new User();
        usr[p].setFirstName(user.firstName);
        usr[p].setLastName(user.lastName);
        p++;
    }
    return usr;
}

This method will remove the duplicate entries from User array and return the User array without duplicate entries.

Upvotes: 0

Jon Newmuis
Jon Newmuis

Reputation: 26502

In general, you can add elements to a Set to remove duplicates. However, you don't want to add the entire array to the collection in general; you just want to add the individual elements, like so:

    public static void main(String[] args) {
        Set<User> a = new HashSet<User>();
        User[] u = new User[3];

        u[0] = new User();
        u[0].setFirstName("Mike"); u[0].setLastName("Jordon");      

        u[1] = new User();
        u[1].setFirstName("Jack"); u[1].setLastName("Nicolson");

        u[2] = new User();
        u[2].setFirstName("Jack"); u[2].setLastName("Nicolson");

        // Add each of the users to the Set.  Note that there are three.
        for (User user : u) {
            a.add(u);
        }

        // Get the results back as an array.  Note that this will have two.
        User[] duplicatesRemoved = new User[0];
        a.toArray(duplicatesRemoved);
    }

Upvotes: 0

Harmeet Singh
Harmeet Singh

Reputation: 2616

try this my friend :

        Iterator i = a.iterator();
        while (i.hasNext()) {
            User u = (User) i.next();
            boolean match = false;
            Iterator j = a.iterator();
            boolean once = true;
            while (j.hasNext()) {                    
                if(once){j.next();} // to skip own occurence only once
                once = false;                    
                User u2 = (User) j.next();
                if (u.getFirstName().equals(u2.getFirstName())
                        && u.getLastName().equals(u2.getLastName())) {
                    match = true;
                }
            }
            if (!match) {
                // print
            }
        }

Upvotes: 1

maneesh
maneesh

Reputation: 1112

First you should use a Set to store objects instead of a array if you dont want duplicates. (Arrays and List do allow duplicate objects to be stores)

Second your equals methods should use String.equal method for comparison and should check for null values too to be on the safe side. I would use the IDE's auto generate feature for hashcode and equals methods always (i.e. Eclipse Source -> Generate hashCode() and equals()...)

 @Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
    result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    User other = (User) obj;
    if (firstName == null) {
        if (other.firstName != null)
            return false;
    } else if (!firstName.equals(other.firstName))
        return false;
    if (lastName == null) {
        if (other.lastName != null)
            return false;
    } else if (!lastName.equals(other.lastName))
        return false;
    return true;
}

and main method

public static void main(String[] args) {
    List<Set<User>> a = new ArrayList<Set<User>>();
    Set<User> set = new HashSet<User>();

    User u = new User();
    u.setFirstName("Mike"); u.setLastName("Jordon");      
    set.add(u);

    u = new User();
    u.setFirstName("Jack"); u.setLastName("Nicolson");
    set.add(u);

    u = new User();
    u.setFirstName("Jack"); u.setLastName("Nicolson");
    set.add(u);

    a.add(set);

    for (Set<User> ss : a) {
        for (User user : ss) {           
            System.out.println(user.getFirstName() + " " + user.getLastName());
        }
    }
}

Upvotes: 0

Andrew Swan
Andrew Swan

Reputation: 13627

You're using a Set of arrays, where the set has one element, namely an array of three Users. Arrays don't enforce or check uniqueness, which is why you get the same User twice. If you removed the arrays altogether, and simply used a Set, you'd get the "unique" behaviour you want.

Upvotes: 0

Subir Kumar Sao
Subir Kumar Sao

Reputation: 8401

Override the equals method as suggested by Jason. Now for removing duplicates you need to use Set.

List allows duplicate values so you will always have duplicate values. Set doesnot allow duplicate value so it will solve your problem.

Upvotes: 0

PeterMmm
PeterMmm

Reputation: 24630

I suppose you want this:

 class pp {
        public static void main(String[] args) {
            Set<User> a = new HashSet<User>();

        User u = new User();
        u.setFirstName("Mike"); u.setLastName("Jordon");  
        a.add(u);

        u = new User();
        u.setFirstName("Jack"); u.setLastName("Nicolson");
        a.add(u);

        u = new User();
        u.setFirstName("Jack"); u.setLastName("Nicolson");

        a.add(u);

        for (User ss : a) {           
                System.out.println(ss.getFirstName() + " " + ss.getLastName());
        }
    }
}

Upvotes: 1

Related Questions