3

I have a main class that creates an arraylist of type Element:

public static void main(String[] args) throws IOException {
String input = "";
String id = ""; //combination of letters and numbers
String name = "";

ArrayList<Element> element = new ArrayList<> ();

BufferedReader in = new BufferedReader( new InputStreamReader(System.in));

while(!(input.equalsIgnoreCase("quit"))) {
    System.out.println("Please enter 'e' to enter an element, or 'quit' to quit");
    input = in.readLine();

if(input.equalsIgnoreCase("e")) {

    System.out.println("Please enter a name for the element");
    name = in.readLine();

    System.out.println("Please enter an id for the element");
    id = in.readLine(); 

    element.add(new Element(name,id));
    //only add if id and name don't exist already
}

}

}

Then I have a element clas:

public class Element {

private String name;
private String id;

public Element(String name, String id) {

this.name = name;
this.id = id;

}


}

I want to check before adding an element to a list (it's id and name), to check if another element already in the list already has those exact values (id and name). I know I can use the toString method to do this, but I'm not sure how I can override it to pass on an id and name, before adding the elements to the list. Is their a way to do this? Ideally I'd only want to add an element, if it doesn't already exist.

3 Answers 3

2

Below overridden equals method will work.

public class Element {
    private String name;
    private String id;

    public Element(String name, String id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Element){
            Element element = (Element) obj;
            if(element != null && this.name.equals(element.name) && this.id.equals(element.id)){
                return true;
            }
        }
        return false;
    }
  }

And then try doing check before adding to your list, as below:

        ArrayList<Element> element = new ArrayList<Element> ();
        Element element1 = new Element("a", "1");
        Element element2 = new Element("b", "2");
        Element element3 = new Element("b", "2");
        element.add(element1);
        element.add(element2);
        if(element.contains(element3)){
            System.out.println("Yes");
        } else{
            System.out.println("No");
        }


Time for some concept:

Below is the contains implementation from Java:

Part which should concern you is this - o.equals(elementData[i]. Internally equals method of the object will be used to do equals check, if you have not overridden the equals method then the memory location of 2 objects will be compared, and since it would be different ArrayList.contains will return false, so by overriding the equals method we are establishing a logical condition on when to treat 2 Element object as same.

public boolean contains(Object o) {
    return indexOf(o) >= 0;
}

  public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}
Sign up to request clarification or add additional context in comments.

13 Comments

Your equals method does not follow the contract of equals method. It throws NPE for null parameter: For any non-null reference value x, x.equals(null) should return false
Just one question, how would I call the equals method in the main class? Something like this: element.equals(element)?
If you don't needed duplication in your collection, you should use Set instead of List.
@A.Panzer I didn't get you, clearly, if you mean if(element.contains(null)){ will throw NPE then it will not because of this if (o == null) { condition in indexOf and there is a NULL in the list then contains will return true.
@hagrawal Take a look at Javadoc of Object.equals method. There are rules for equals() method. This is no matter whether your code pass null or not. Element class might be reused. docs.oracle.com/javase/7/docs/api/java/lang/…
|
2

You should use a Set. It is a data structure that does exactly what you want it to - it can't contain duplicates. In order for the set to work, you should have a correct implementation of the equals() and hashCode() methods of your class.

4 Comments

I'm not allowed to use anything other than an arraylist.
You should still override the equals() method and rely on the contains method of the ArrayList... But it will be grossly inefficient
@DanailAlexiev Please specify which implementation of Set you are recommending. Why contains will be inefficient?
@hagrawal The Set implementation depend on what you needed. You can use a simple HashCode or if you what keep the order you can use LinkedHashSet.
0

Override equals method of Element class. Use contains method of List to check whether element is already in the list.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.