Search code examples
javascjp

Use of a Comparable with indexOf


I tried the following simple test.

class ZiggyTest{
    public static void main(String[] args){

        List<Cities> cities3 = new ArrayList<Cities>();
        Cities city = new Cities("London");

        cities3.add(new Cities("Manchester"));
        cities3.add(new Cities("Glasgow"));
        cities3.add(new Cities("Leeds"));
        cities3.add(city);
        cities3.add(new Cities("Leicester"));
        cities3.add(new Cities("Croydon"));
        cities3.add(new Cities("Watford"));

        System.out.println("IndexOf(new Croydon) " 
                       + cities3.indexOf(new Cities("Croydon")));
        System.out.println("IndexOf(city) " 
                       + cities3.indexOf(city));
    }   
}

class Cities implements Comparable<Cities>{
    String title;

    Cities(String aTitle){
        this.title = aTitle;
    }

    public String getTitle(){
        return title;
    }

    public String toString(){
        return "Title : " + title;
    }

    public int compareTo(Cities c){
        return title.compareTo(c.getTitle());
    }
}

The output of the above test is

IndexOf(new Croydon) -1
IndexOf(city) 3

I understand why the second line is producing 3 but I don't understand why the first line is not finding the new one with title="Croydon".

The API describes the indexOf method as one that

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.

I think the API is saying that if the object is null then it will return the index of the first occurrence of a null object from the list. If it is not null it will return the index of the first occurrence where the passed in object equals method returns true.

Shouldn't the the object created as cities3.indexOf(new Cities("Croydon") be equal to the object added previously as cities3.add(new Cities("Croydon"));?


Solution

  • Redefine equals instead of compareTo if you want perform search operations.

    By default indexOf compares using equals operation, and in your case equals not redefined, that means you have comparison by references. When you create new City object with the same name you have another reference to object, so equals return false.

    P.S. If you are using object that describe city, preferable name for class City not Cities