38

I have some object

class A {
  private Long id; 
  private String name; 
  public boolean equals(Long v) {
     return this.id.equals(v);
  }
}

and ArrayList of these objects. What I want is to be able to check if that list contains some object by object's field. For example:

ArrayList<A> list = new ArrayList<A>(); if (list.contains(0L)) {...}

but overrided Equals method is not helps me. What I am doing wrong? Thank you

UPDATE And should I override a hashcode() method too?

nKognito
  • 6,297
  • 17
  • 77
  • 138
  • have you overridden equals() in your A class? if so, can you post it here? – c05mic Nov 30 '11 at 06:49
  • Judging by the answers below, I guess there is no convenient solution to this. I feel like this could be solved with an anonymous class implementation, like the kind you use when calling Collections.sort() with your own Comparator. – kodu Apr 14 '17 at 12:22
  • After searching a bit more, I found some useful answers here: http://stackoverflow.com/questions/587404/finding-all-objects-that-have-a-given-property-inside-a-collection – kodu Apr 14 '17 at 12:30

3 Answers3

62

here's some code that might demonstrate how it works out:

import java.util.ArrayList;

class A {
  private Long id; 
  private String name; 

  A(Long id){
      this.id = id;
  }

    @Override
  public boolean equals(Object v) {
        boolean retVal = false;

        if (v instanceof A){
            A ptr = (A) v;
            retVal = ptr.id.longValue() == this.id;
        }

     return retVal;
  }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }
}

public class ArrayList_recap {
    public static void main(String[] args) {
        ArrayList<A> list = new ArrayList<A>(); 

        list.add(new A(0L));
        list.add(new A(1L));

        if (list.contains(new A(0L)))
        {
            System.out.println("Equal");
        }
        else
        {
            System.out.println("Nah.");
        }    
    }

}

First, there is an override of the equals(Object o) method. Then there is the override of the hashCode() as well. Also note that the instanceof A check in the equals will ensure that you're not trying to compare different objects.

That should do the trick! Hope it helped! Cheers :)

Vern
  • 2,393
  • 1
  • 15
  • 18
  • nice example Thanks! – Sameer Kazi Aug 17 '16 at 09:18
  • @Vern Hi, I was trying to implement same thing as you did, for my case i have one POJO class and i am trying to compare one attribute using contains method and its not working as expected. Could you please tell me in your case if you have setter and getter for id and name what value u will pass into contains method. – sashikanta Mar 20 '17 at 14:41
  • I have two properties I want to use. How would I impement the `hashCode()` method? – Marvin Oct 19 '19 at 01:22
12

What I am doing wrong?

You are not overriding. You are overloading.

The contains method calls the equals method with signature equals(Object), so this (new) method that you've added won't be called.

The other problem is that your equals method has the wrong semantics for contains. The contains method needs to compare this against an object that could be a member of the list. Your list does not contain Long objects. It contains objects of type A.

Now you might get away with this ... if you use raw list types ... but what you are trying to do is a violation of the API contract, and bad practice. A better solution is to iterate and test the elements of the list explicitly.


And should I override a hashcode() method too?

If you override equals(Object) then you should also override hashcode().

It won't make any difference here, but it is essential if you ever put your A objects into hashed data structures. And since you don't know what the next guy is going to do with your code, it is good practice to make sure that equals(Object) and hashCode() have compatible semantics.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
9

You have not overridden the method in your class. In order to override, method parameters must also be of same type.

it should be

public boolean equals(Object o) {

}

where as in your case it is

public boolean equals(Long o) {

 }

you probably need to do this

public boolean equals(Object o)
    {
        if (o == null) return false;
        if (o == this) return true; //if both pointing towards same object on heap

            A a = (A) o;
        return this.id.equals(a.id);
    }
Zohaib
  • 7,026
  • 3
  • 26
  • 35