[Java]Does indexOf use equals?
Asked Answered
A

2

6

I was wondering how the method indexOf of an ArrayList is implemented. In fact I have override the equals method like this:

public class CustomObject {
@Override 
    public boolean equals(Object o) {

        if(o instanceof CityLoader)
            return ((CityLoader)o).getName() == this.name;
        else if (o instanceof String)
            return this.name.equals((String)o);         
        return false;
    }
}

I though this will avoid me to override also the indexOf method but it seems I am totally wrong. When I try

ArrayList<CustomObject> customObjects = new ArrayList<CustomObject>
... insert customobject into the arraylist ...
customObjects.indexOf(new String("name")) 

indexOf return false but it should return true. (I checked the element I am looking for exists)

Am I totally wrong?

Autocratic answered 24/5, 2016 at 13:37 Comment(1)
"I was wondering how the method indexOf of an ArrayList is implemented" You don't need to know how it's implemented, you need to know what the contract is. There's a tool for that: The JavaDoc, which says: "Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. More formally, returns the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))), or -1 if there is no such index."Desilva
B
6

equals should never return true when the compared objects are not of the same type (in your case CustomObject's equals should always return false when o is not an instance of CustomObject).

The implementation of indexOf happens to use String's equals instead of your CustomObject's equals when you pass a String to it, and String's equals returns false when you pass to it a object that is not a String.

In addition, don't use == in comparison of Strings.

You should pass an instance of CustomObject to indexOf :

customObjects.indexOf(new CustomObject("name")) 

(or whatever the constructor of CustomObject looks like)

Your equals method should look like this :

public boolean equals(Object o) {
    if(!(o instanceof CityLoader))
        return false;
    CityLoader other = (CityLoader)o;
    return other.name.equals(this.name);
}
Bernoulli answered 24/5, 2016 at 13:40 Comment(9)
You are right! Should I override the String equals?Autocratic
@Autocratic No, you can't. String is a final class.Bernoulli
Thanks. So it seems to be a terrible practise. I will avoid it. Thanks!Autocratic
Just another question. If I want to override the indexOf method, will I have to do it in the CustomObject class or in a new class which extends ArrayList<CustomObject> ?Autocratic
@Autocratic Probably doing it in CustomObject would do.Guan
@Autocratic indexOf is a method of the List interface. You'll have to override it in a sub-class of the List implementation you are using (i.e. a sub-class of ArrayList in your case). It doesn't seem like a good idea though.Bernoulli
@Autocratic If you implement it in CustomObject, it won't be used when you call customObjects.indexOf, since customObjects is an ArrayList.Bernoulli
@Autocratic the solution here is not to use indexOf. Just write your own loop. Don't try to use indexOf(someTypeNotTheElementType), don't try to hack that into working, just stop.Prenotion
Downvote. other.name may be null and throw a NPE.Bedfordshire
G
0
customObjects.indexOf(new String("name")) 

This is what you are doing wrong. You are looking for an index of a String inside a CustomObject object list.

From the java docs :

 /**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the lowest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     *
     * @param o element to search for
     * @return the index of the first occurrence of the specified element in
     *         this list, or -1 if this list does not contain the element
     * @throws ClassCastException if the type of the specified element
     *         is incompatible with this list
     *         (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified element is null and this
     *         list does not permit null elements
     *         (<a href="Collection.html#optional-restrictions">optional</a>)
     */
    int indexOf(Object o);
Guan answered 24/5, 2016 at 13:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.