Jedi Schmedi
Jedi Schmedi

Reputation: 818

Always index 0 when iterating over list

I keep getting the first object in the list when I try iterate.

code:

@Override
        protected void onPostExecute(List<Location> locations) {
            // TODO Auto-generated method stub
            super.onPostExecute(locations);

            Log.d("Debug" , "List: " + locations.size() +  " markers");
            for (Location location : locations) {
                Log.d("Debug", "index of: " + locations.indexOf(location));
            }
        }

Print out says, 200 markers in list and printout of index gives "0" 200 times. How come it won't iterate to next object?

Upvotes: 1

Views: 434

Answers (4)

user177800
user177800

Reputation:

It is iterating to the next object correctly:

.indexOf() just considers every object at every index to be .equals(location) == true to the first one at index 0.

Proof:

If you added the same Location 200 times and the .equals() isn't overridden correctly; for example where every instance is equal to every other instance; you are get back the first match.

The List.indexOf(Object o) Javadoc clearly states:

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.

If .equals() thinks it is then you will get the first match.

In your case index 0.

   public static void main(final String[] args)
    {
        final List<String> al = new ArrayList<String>(100);
        for (int i=0; i<100; i++) { al.add("Hello World!"); }
        for (final String s : al)
        {
            System.out.println(al.indexOf(s));
        }
    }

Prints out 0 100 times.

One simple change

    for (int i=0; i<100; i++) { al.add(Integer.toString(i)); }

And you see that the code works as intended with unique objects as considered by a correctly implemented .equals()

Upvotes: 2

Rudi Kershaw
Rudi Kershaw

Reputation: 12972

Probably because indexOf() returns the first index of an instance of an object that equals() the object you are checking for and you must have many multiple Locations that are considered meaningfully equal. This could be because you have incorrectly overridden your equals method for Location or just not considered the implications of your specific override.

Take a look at the following example which demonstrates your issue except with String objects;

        ArrayList<String> als = new ArrayList<String>();
        als.add("a");
        als.add("b");
        als.add("c");
        als.add("d");
        als.add("e");

        for(String s : als) System.out.print(als.indexOf(s));

        als = new ArrayList<String>();
        als.add(new String("a"));
        als.add(new String("a"));
        als.add(new String("a"));
        als.add(new String("a"));
        als.add(new String("a"));
        System.out.println();
        for(String s : als) System.out.print(als.indexOf(s));

This outputs;

01234
00000

In the last 5 outputted 0s, the s String you check the array for may be the 2nd or greater String in the array but it is found to be meaningfully equal (as defined by the String classes equals() override) to the String in the first index and so it will always return 0. Try the above example with an array of objects instead, and they are never considered equal unless they are referring to the same object in memory.

Upvotes: 1

Juan Rada
Juan Rada

Reputation: 3766

Validate equals method or validate the instance is not null. This is the implementation for the method on ArrayList in order to understand why.

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

Upvotes: 0

Mifmif
Mifmif

Reputation: 3190

Normally for (Location location : locations) iterate over the objects in locations list.When indexOf() is called it use equals and hashCode to find the specific object, but i think that you don't implement equals and hashCode methods of the class Location .Try to implement them and check.

Upvotes: 0

Related Questions