user3871678
user3871678

Reputation: 23

remove Objects from a List base on another list

I want to remove a List of elements Objects from list base on whatever is inside list2. I used removeAll(). Why does the list not remove those elements that are found in list2?

Element.java

public class Element {

    private String element;

    public Element() {

    }

    public Element(String element) {
        setE(element);
    }


    public String getElement() {
        return element; 
    }

    public void setElement(String element) {
        this.element = element;
    }
}

RemoveAllTest.java

import java.util.ArrayList;
import java.util.List;
public class RemoveAllTest {
    public RemoveAllTest() {
        List<Element> list = new ArrayList<Element>();
        List<Element> list2 = new ArrayList<Element>();

        list.add(new Element("a"));
        list.add(new Element("b"));
        list.add(new Element("c"));

        list2.add(new Element("a"));
        list2.add(new Element("b"));
        list.removeAll(list2);

        for(int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i).getElement());
        }
    }
    public static void main(String[] args) {
        new RemoveAllTest();
    }
}

Upvotes: 0

Views: 111

Answers (5)

You could, as an alternative to the other answers, simply reuse the same objects in both lists:

Element a = new Element("a");
Element b = new Element("b");
Element c = new Element("c");

list.add(a);
list.add(b);
list.add(c);

list2.add(a);
list2.add(b);
list.removeAll(list2);

for(int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i).getElement());
}

output:

c

Upvotes: 0

Nir Alfasi
Nir Alfasi

Reputation: 53525

Because these are not the same elements! every time you're using new operator you're creating a new element!

In order to make two elements that have the same element string equals - you have to override (implement) equals() for example:

@Override
public boolean equals(Object other){
    if (!( other instanceof Element)) {
        return false;
    }
    Element o = (Element)other;
    if (this.element == null) {
        return o.getElement() == null;
    }
    return this.element.equals(o.getElement());
}

Upvotes: 2

Nick Palmer
Nick Palmer

Reputation: 2753

Your Element class does not implement equals. Because of they use the Object.equals() method which only tests if it is the exact same object. (i.e. that it is == ).

If you implement equals it is good practice to also implement hashCode so that equal objects will hash into the same bucket in hash data structures like Map.

Here is your Element which will not have this problem:

public class Element {

    private String element;

    public Element() {

    }

    public Element(String element) {
        setE(element);
    }


    public String getElement() {
        return element; 
    }

    public void setElement(String element) {
        this.element = element;
    }

    public boolean equals(Object other) {
        if (other instanceof Element) {
            Element otherElement = (Element) other;
            if (null == element) {
                return otherElement.element == null;
            }
            return element.equals(otherElement.element);
        }
        return false;
    }

    public int hashCode() {
        if (null == element) {
            return -7;
        }
        return element.hashCode();
    }
}

Note that we have to be careful about cases where element is null because you are not ensuring that element has a sane value. A "better" element class could avoid this if appropriate by only providing a constructor which takes a String and throwing an IllegalArgumentException if the string passed into the constructor is null, or if the setElement call takes a null value. Like so:

public class Element {

    private String element;

    public Element(String element) {
        setElement(element);
    }

    public String getElement() {
        return element; 
    }

    public void setElement(String element) {
        if (null == element) {
            throw new IllegalArgumentException("Element must not be null.");
        }
        this.element = element;
    }

    public boolean equals(Object other) {
        if (other instanceof Element) {
            Element otherElement = (Element) other;
            return element.equals(otherElement.element);
        }
        return false;
    }

    public int hashCode() {
        return element.hashCode();
    }
}

Finally, note that null == element is better to write than element == null since you can easily forget an equal sign and end up assigning null to element. If you write null = element the compiler will complain and alert you of the dropped character.

Upvotes: 2

Darshan Lila
Darshan Lila

Reputation: 5868

Use following Element class it should help you.

class Element {

private String element;

public Element() {

}

public Element(String element) {
    setElement(element);
}


public String getElement() {
    return element; 
}

public void setElement(String element) {
    this.element = element;
}

public boolean equals(Object object)
{
    Element now=(Element)object;
    if (object == null || object.getClass() != getClass()) 
    {
        result = false;
    }
    else if(this.getElement().equals(now.getElement()))
    {
        return true;
    }
    else
    {
        return false;
    }
}
public int hashCode() 
 {
    if(element!=null)
      return element.hashCode();
    else
      return 0;
 }
}

Upvotes: 0

Ruchira Gayan Ranaweera
Ruchira Gayan Ranaweera

Reputation: 35557

You need to override equals() and hashCode() methods in Element class.

In this case you must override equals() method. But as a good practice override hashCode() too.

Now let's try to solve your issue. You can use following as equals() and hashCode()

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

    Element element1 = (Element) o;

    if (element != null ? !element.equals(element1.element) 
                                     : element1.element != null) return false;

    return true;
}

@Override
public int hashCode() {
    return element != null ? element.hashCode() : 0;
}

For more information Why do We need to override the equals and hashCode methods in Java?

Upvotes: 4

Related Questions