-3

I have a ArrayList<CustomObject> as ArrayList<Names> in my project. The Names pojo contains name and image fields as follows:

Names.java

public class Names {


    private String name;

    private String image;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public Names(String name, String image) {
        this.name = name;
        this.image = image;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return name;
    }

}

I am adding values for the fields as follows:

         ArrayList<Names> menu = new ArrayList<Names>();

         menu.add(new Names("chandru","image1"));
         menu.add(new Names("vikki","image2"));
         menu.add(new Names("karthick","image3"));
         menu.add(new Names("chandru","image4"));
         menu.add(new Names("karthick","image5"));
         menu.add(new Names("chandru","image6"));
         menu.add(new Names("karthick","image7"));
         menu.add(new Names("vikki","image8"));
         menu.add(new Names("karthick","image9"));
         menu.add(new Names("harish","image10"));
         menu.add(new Names("vivek","image11"));
         menu.add(new Names("harish","image12"));

My requirement:

Now all my requirement is to remove the repeated names contains in the ArrayList. I tried several methods like to remove duplicates as follows:

Method I: Using HashSet

Adding values into the HashSet and assigning back those values into new ArrayList<Names> named al.

          ArrayList<Names> al = new ArrayList<Names>();

          Set<Names> hs = new HashSet<Names>();
          hs.addAll(menu);

          al.clear();
          al.addAll(hs);

          System.out.println(al);

Output of Method I:

[karthick, vikki, karthick, karthick, chandru, vivek, vikki, chandru, harish, harish, karthick, chandru]

Expected Output to be:

Values after removing duplicates:

[karthick, vikki,chandru, vivek, harish]

I am also posting my entire class for your reference

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;


public class Sample {

     public static void main(String[] args) {

         ArrayList<Names> menu = new ArrayList<Names>();
         menu.add(new Names("chandru","image"));
         menu.add(new Names("vikki","image"));
         menu.add(new Names("karthick","image"));
         menu.add(new Names("chandru","image"));
         menu.add(new Names("karthick","image"));
         menu.add(new Names("chandru","image"));
         menu.add(new Names("karthick","image"));
         menu.add(new Names("vikki","image"));
         menu.add(new Names("karthick","image"));
         menu.add(new Names("harish","image"));
         menu.add(new Names("vivek","image"));
         menu.add(new Names("harish","image"));

         ArrayList<Names> al = new ArrayList<Names>();

          Set<Names> hs = new HashSet<Names>();
          hs.addAll(menu);

          al.clear();
          al.addAll(hs);

          System.out.println(al);

     }
 }

Please help me to resolve by issue which I am facing to remove duplicates from the list. Any kind of suggestions and solutions would be much helpful for me. Thanks in advance.

Chandru
  • 5,954
  • 11
  • 45
  • 85
  • 4
    You didn't override `hashCode()` and `equals()` in your `Names` class. – Eran Sep 27 '15 at 08:10
  • If you want the HashSet to eliminate duplicates based on the `name` of `Names`, then two `Names` instance with the same `name` should be equal. But they're not, because you haven't overridden `equals()` and `hashCode()` to make that happen. – JB Nizet Sep 27 '15 at 08:11
  • @JBNizet I really dont know how to do that. Can u post some piece of code?? – Chandru Sep 27 '15 at 08:13
  • have a look [here](http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java) – Blackbelt Sep 27 '15 at 08:14
  • 4
    @Chandru read the javadoc of the methods to understand their contract. Use Google. Do some research. This is important stuff. You shouldn't just take my code and copy and paste it. You need to understand how that works. – JB Nizet Sep 27 '15 at 08:15
  • 1
    possible duplicate of [How to remove duplicates from a list?](http://stackoverflow.com/questions/2849450/how-to-remove-duplicates-from-a-list) – Tom Sep 27 '15 at 08:15
  • Point is you are already putting unique object into hashset, http://stackoverflow.com/questions/203984/how-do-i-remove-repeated-elements-from-arraylist use name as key value here. – dex Sep 27 '15 at 08:21

3 Answers3

2

You just need to override hashCode and equals and your code works well:

   public class Names {


    private String name;

    private String image;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public Names(String name, String image) {
        this.name = name;
        this.image = image;
    }

    @Override
    public String toString() {
        return name;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.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;
        Names other = (Names) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }


}

Test Class

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

public class Test {


    public static void main(String[] args) {

        ArrayList<Names> menu = new ArrayList<Names>();
        menu.add(new Names("chandru","image"));
        menu.add(new Names("vikki","image"));
        menu.add(new Names("karthick","image"));
        menu.add(new Names("chandru","image"));
        menu.add(new Names("karthick","image"));
        menu.add(new Names("chandru","image2"));
        menu.add(new Names("karthick","image"));
        menu.add(new Names("vikki","image"));
        menu.add(new Names("karthick","image"));
        menu.add(new Names("harish","image"));
        menu.add(new Names("vivek","image"));
        menu.add(new Names("harish","image"));

        ArrayList<Names> al = new ArrayList<Names>();

         Set<Names> hs = new HashSet<Names>();
         hs.addAll(menu);

         al.clear();
         al.addAll(hs);

         System.out.println(al);

    }
}

Hope this help!

Kenny Tai Huynh
  • 1,464
  • 2
  • 11
  • 23
  • 1
    Now set the image of the second chandru to "image2". Does it still do what the OP want? – JB Nizet Sep 27 '15 at 08:18
  • yes the above code is not working if i change the second image field as image2. – Chandru Sep 27 '15 at 08:21
  • @Nizet: depends on what you want to compare. In case you just need to check the name is duplicated only, just remove the image condition checking in equals and hashCode. – Kenny Tai Huynh Sep 27 '15 at 08:21
  • @Chandru: as I shared above, depends on your requirements. If you just need to check the name, then just remove the image. Let's me edit the code for you! – Kenny Tai Huynh Sep 27 '15 at 08:22
  • yes @KennyTaiHuynh please. Anyways each image field will be different in the ArrayList. I will also edit the question. – Chandru Sep 27 '15 at 08:23
  • But that should be specified in the answer. You should also tell the OP that the methods have been autogenerated by your IDE, because generating that by hand is awful, and the code is horrible to read. To generate the equivalent by hand, you would use `return Objects.hash(name, image);` and you would use `Objects.equals(this.name, other.name) && Objects.equals(this.image, other.image)`. – JB Nizet Sep 27 '15 at 08:25
  • @Nizet: thanks for the comment. Yes, the easiest way is generated the two method from IDE. But we also can change it from that code as the way we want. :). – Kenny Tai Huynh Sep 27 '15 at 08:28
  • @KennyTaiHuynh Thanks it is working great. I accepty your answer. – Chandru Sep 27 '15 at 08:51
  • Chandru: Hope this help. :) @Nizet: thanks for your comment too :) – Kenny Tai Huynh Sep 27 '15 at 08:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/90722/discussion-between-chandru-and-kenny-tai-huynh). – Chandru Sep 27 '15 at 09:23
2

You need to override equals and hashcode method for Names class.

The hashcode method is use to calculate the bucket in HashSet and equals is used to identify the duplicate and will not add if any found already in the set.

@Override
public boolean equals(Object o) {
  if (this == o) return true;
  if (!(o instanceof Names)) return false;

  Names names = (Names) o;

  if (image != null ? !image.equals(names.image) : names.image != null) return false;
  if (name != null ? !name.equals(names.name) : names.name != null) return false;

  return true;
}

@Override
public int hashCode() {
  int result = name != null ? name.hashCode() : 0;
  result = 31 * result + (image != null ? image.hashCode() : 0);
  return result;
}
YoungHobbit
  • 13,254
  • 9
  • 50
  • 73
0

Why don't use use a Set for everything, instead of using the ArrayList. In order for the Set to work properly you will have to overwrite the the equals(E object), and hashcode() methods in your Names.class accordingly. Please see Java Generics for more hints:

Java Overriding equals and hashCode with Generics

Community
  • 1
  • 1