4

I've a listView that has some content initially. If the same content it gets, i removed the duplication through linkedhashset. Now, i want copy the linkedhashset contents i.e without duplication contents to new ArrayList.

I tried to copy through

p.addAll(0,lhm);  // P is the instance of  ArrayList and lhm is linkedHashset instance

But, the ArrayList includes the duplication content too.

Example :

 ArrayList<Price> p = new ArrayList<Price>();

     p.add(new Price("Banana", 60));
     p.add(new Price("Apple", 80));

    LinkedHashSet<Price> lhm = new LinkedHashSet<Price>(p); 
    lhm.add(new Price("Banana", 20)); 
    lhm.add(new Price("Apple", 40));
    lhm.add(new Price("Orange", 30)); 
    for(Price pr:lhm)
    {
        System.out.println(pr);
    } 
    Price duplicate = new Price("Banana", 20);
    System.out.println("inserting duplicate object..."); 
    lhm.add(duplicate);
    lhm.add(new Price("Apple", 40));
    p.addAll(0,lhm);
    System.out.println("After insertion:"); 
    for(Price pr:lhm)
    {
        System.out.println(pr);
    }

    for (int i = 0; i < p.size(); i++) {

        System.out.println(p.get(i).getItem() +"-" +p.get(i).getPrice());           
    }

Price.class

class Price
{
    private String item; 
    private int price; 
    public Price(String itm, int pr)
    {
        this.item = itm; 
        this.price = pr; 
        }
    public int hashCode()
    { 
        System.out.println("In hashcode");
        int hashcode = 0; 
        hashcode = price;
        //System.out.println(hashcode);

        hashcode+= item.hashCode(); 
    //  System.out.println(hashcode);

        return hashcode;  
        }

    public boolean equals(Object obj)
    {
        System.out.println("In equals"); 
        if (obj instanceof Price) 
        {
            Price pp = (Price) obj; 
            return (pp.item.equals(this.item) && pp.price == this.price); 
            }
        else 
        { 
            return false;
            }
        }

    public String getItem()
    {
        return item; 
    }

    public void setItem(String item) 
    { 
        this.item = item; 
        }

    public int getPrice() 

    {
        return price;
        }
    public void setPrice(int price) 
    {
        this.price = price; 
        }
    public String toString()
    {
        return "item: "+item+" price: "+price; 
        }
    }

Output :

In hashcode
In hashcode
In hashcode
In hashcode
In hashcode
item: Banana price: 60
item: Apple price: 80
item: Banana price: 20
item: Apple price: 40
item: Orange price: 30
inserting duplicate object...
In hashcode
In equals
In hashcode
In equals
//iterating linkedhasset content

After insertion:
item: Banana price: 60
item: Apple price: 80
item: Banana price: 20
item: Apple price: 40
item: Orange price: 30

// iterating ArrayList p content

Banana-60
Apple-80
Banana-20
Apple-40
Orange-30
Banana-60
Apple-80 <-- duplicate
user3289108
  • 770
  • 5
  • 10
  • 29
  • This is not an issue if you think carefully. You created an arraylist and added two elements into it. And created another set with that arraylist, and did some insertion on set and then added to list. So what do you expect. How a list can prevent your duplicates (with your logic) if you added some elements already into it? – Pankaj Kumar Mar 09 '15 at 06:16
  • Since `LinkedHashset` has only unique items, i thought is there any way to copy the unique content to new ArrayList. – user3289108 Mar 09 '15 at 06:18
  • @user3289108 AKS's answer demonstrates exactly that. Your problem is that you're added copies of the same references to the original list. If you clear it first, all the new elements will be unique. – shmosel Mar 09 '15 at 06:20

2 Answers2

9

The following line just inserts all the elements into the arraylist starting from the 0th index

p.addAll(0,lhm);

And, the elements which were added using these lines were still present in the arraylist:

p.add(new Price("Banana", 60));
p.add(new Price("Apple", 80));

So, you should clear the array list before adding the items from the linkedhashset, in case you don't want the duplicates. i.e.

p.clear();
p.addAll(lhm); // and, at this point you don't need the index.
AKS
  • 18,983
  • 3
  • 43
  • 54
  • See if 1,2 are the items in p. If i add another 2,3,4...the final arraylist should show 1,2,3,4. (By preventing duplicate..here 2). I don't need to clear all the items. It should present and when adding new items which are duplicate should not inserted. – user3289108 Mar 09 '15 at 06:11
  • Arraylist doesn't guarantee unique items like a Set and that's why when you have items 1, 2 in p and you add 2, 3, 4 later, the items in p afterwards will be 1, 2, 2, 3, 4. – AKS Mar 09 '15 at 06:14
  • Yes, but since im copying the contents from `linkedhashset` which has unique contents only right? won't it discard the old content? – user3289108 Mar 09 '15 at 06:22
  • @user3289108 `List.addAll()` does not override existing values, it just *adds* additional ones, regardless of whether they are already contained or not. – shmosel Mar 09 '15 at 06:23
  • Right i got it now. Since p has 2 items are already, adding lhm which contains same items makes it duplicate for new arraylist. Clearing p before adding lhm to p helps. Thank you. – user3289108 Mar 09 '15 at 06:25
2

A Set will only ensure that its own elements are unique. You can't expect ArrayList to exclude duplicates unless the entire collection is filtered through a set. For example:

...
p.addAll(0,lhm);
p = new ArrayList<String>(new HashSet<String>(p));
shmosel
  • 49,289
  • 6
  • 73
  • 138
  • I know. I think you missed this line `LinkedHashSet lhm = new LinkedHashSet(p); `. – user3289108 Mar 09 '15 at 06:12
  • @user3289108 all that accomplishes is it ensures that `lhm` contains only unique elements. But no one's checking that the elements you're subsequently copying back from `lhm` to `p` are unique to `p`. – shmosel Mar 09 '15 at 06:15
  • Yes, lhm contains only unique elements. You can check example. In the After insertion, `Apple-80` is not included since it is `linkedhashset`. But, it shows when copying lhm content to new arraylist. – user3289108 Mar 09 '15 at 06:20
  • Yes, of course `lhm` contains unique elements, but you're copying those elements to the list that already contains the same elements. You need to stop and think for a minute. We're all saying the same thing, but you're not listening. – shmosel Mar 09 '15 at 06:22
  • And why do you only mention `Apple-80` as the duplicate while `Banana-60` is also a duplicate item. And, as everyone is iterating and re-iterating that these items are already present in the arraylist. And, when you add some more items they are just appended and they don't replace the existing items. – AKS Mar 09 '15 at 06:25