1

I have my Class MyModel which contains:

private int value;

public int getValue() {
    return value;
}

public void setValue(int value) {
    this.value = value;
}

Now I have populated MyModel class:

private final List<MyModel> listModel = new ArrayList<>();
private Mymodel myModel;

 myModel= new MyModel ();
 myModel.setValue(1);
 myModel.setValue(2);
 myModel.setValue(3);
 listModel.add(myModel);

I want to find out if listModel contains myModel

listModel.contains(myModel)

I have made some search and I know contains makes use of the equals but I am finding the right way to find the solution. Thanks in advance

Erald Haka
  • 182
  • 2
  • 10
  • 6
    There's really no other way to do this besides implementing `equals`. You should implement `equals`. – Makoto Mar 02 '19 at 07:13
  • And a modern IDE will help you with implementing it properly – Joakim Danielson Mar 02 '19 at 07:19
  • If you have one primitive field that can identify the MyModel uniquely that is an int id for example then you can get the list of the fields from List and search for myModel.id in it. – muasif80 Mar 02 '19 at 07:25
  • "contains makes use of the equals but I am finding the right way to find the solution" - implementing equals() for MyModel IS the right way to use contains() later. – amseager Mar 02 '19 at 07:31
  • Possible duplicate of [How does a ArrayList's contains() method evaluate objects?](https://stackoverflow.com/questions/2642589/how-does-a-arraylists-contains-method-evaluate-objects) – Julien Lopez Mar 02 '19 at 07:46
  • The object always equals itself. You need only make own equals() if you make another instance (with new operator) with the same value. – rockfarkas Mar 02 '19 at 08:30

3 Answers3

2

If you look at the implementation of contains in ArrayList class, you'd see that internally it is using the equals method to find the object:

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

public int indexOf(Object o) {
    return indexOfRange(o, 0, size);
}

int indexOfRange(Object o, int start, int end) {
    Object[] es = elementData;
    if (o == null) {
       ...
    } else {
        for (int i = start; i < end; i++) {
            if (o.equals(es[i])) { //calling overridden equals of the object instance, else it will revert to the Object's equals which simply compares the reference 
                return i;
            }
        }
    }
    return -1;
}

So you'd be needing to create both equals and hashCode for your MyModel class. You can take the help of the IDE you are using to generate it for you:

As an example:

class MyModel{
    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof MyModel)) return false;
        MyModel myModel = (MyModel) o;
        return value == myModel.value;
    }

    @Override
    public int hashCode() {
        return Objects.hash(value);
    }
}
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44
  • The object (should) always equals itself! The original implementation `Object.equals(..)` is `this == another`. The OP do not change the original `myModel` object's reference, so `contains(myModel)` must work without make own `equals(...)`. – rockfarkas Mar 02 '19 at 08:21
1

The only way to check for contains is to override equals() method. If you check how contains method is implemented in ArrayList you can easily find it out. contains() method will call indexOf() method which will return the index of a element in the list. If the index is greater than 0, then it contains() method will return true.

Lets look how indexOf() method is implemented.

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;
}

This means indexOf() method is just traversing through elements in the list and calling equals() method in your MyModel class.

So there is no other way to check for contains without overriding equals() method from Object class

Binu
  • 754
  • 6
  • 15
  • The object (should) always equals itself! The original implementation `Object.equals(..)` is `this == another`. The OP do not change the original myModel object's reference, so `contains(myModel)` must be true without write own `equals(...)`. – rockfarkas Mar 02 '19 at 08:28
0

Try to run the following code, I have modified it and added Logs, now u can check output printed on the console: I would suggest you check for the object by using equals().

class MyModel {
private int value;

public int getValue() {
    return value;
}

public void setValue(int value) {
    this.value = value;
}

@Override
public String toString() {
    return "MyModel{" +
            "value=" + value +
            '}';
}

}

final List<MyModel> listModel = new ArrayList<>();
    MyModel myModel;

    myModel= new MyModel();
    myModel.setValue(1);
    myModel.setValue(2);
    myModel.setValue(3);
    listModel.add(myModel);
    //here your myModel object has '3' value and list has [3], So this will return `true`
    System.out.println("myModel=>"+myModel.toString()+"-->List = "+listModel.toString()+",, CONTAINS. =>"+listModel.contains(myModel));

    myModel= new MyModel();
    myModel.setValue(8);
    listModel.add(myModel);
    //here your myModel object has '8' value and list has [3,8], So this will return `true`
    System.out.println("myModel=>"+myModel.toString()+"-->List = "+listModel.toString()+",, CONTAINS. =>"+listModel.contains(myModel));

    myModel= new MyModel();
    myModel.setValue(100);
    //here your myModel object has '100' value and list has [3,8], So this will return `false`
    System.out.println("myModel=>"+myModel.toString()+"-->List = "+listModel.toString()+",, CONTAINS. =>"+listModel.contains(myModel));
Kavita Patil
  • 1,784
  • 1
  • 17
  • 30