ArrayList indexOf() returns wrong index?
I have a problem with ArrayList. I'm using ArrayList like this:
private ArrayList<Playlist> mPlaylists;
where Playlist is a class inherited from another ArrayList. I do the following:
p = new Playlist(...some parameters...);
mPlaylists.add(p);
Later, when I use 'p' to get the index in the list:
int index = mPlaylists.indexOf(p);
a开发者_JS百科n index of '1' is returned, even though inspection of the list clearly shows that it's index '4'.
Does anybody know why this fails? Thanks.
B.R. Morten
Edit: Same problem without indexOf(), using equals():
private int GetIndex(Playlist playlist) {
for (int i = 0; i < mPlaylists.size(); i++) {
if (mPlaylists.get(i).equals(playlist)) {
return i;
}
}
return -1;
}
New edit: This WORKS!:
private int getIndex(Playlist playlist) {
for (int i = 0; i < mPlaylists.size(); i++) {
if (mPlaylists.get(i) == playlist) {
return i;
}
}
return -1;
}
Solution: As suggested, I changed the Playlist class to not enherit from ArrayList, but rather keeping an instance privately. It turned out that I only had to implement 4 ArrayList methods.
This does the trick; Now indexOf() returns the correct object!
Thanks to all contributors!
Most likely your PlayList
messed up with the default ArrayList equals
implementation, because the way indexOf
is calculated to something like:
indexOf(Object o)
if( o == null ) then iterate until null is found and return that index
if( o != null ) iterate until o.equals( array[i] ) is found and return taht index
else return -1
end
So, you are doing something funny with your .equals method or your are accidentally inserting another element in the list when you think it is at the end.
EDIT
As per your edit... see? Your .equals()
method is broken.
Consider doing a good review and make sure it adheres to the description defined in Object.equals
From the API:
int indexOf(Object o)
: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.
So the answer is that you need to override .equals()
in Playlist
.
There may be many reasons for this behavior:
1) If multiple elements in an ArrayList are equal (according to equals method), then the first one is returned. Maybe you simply have multiple identical objects.
2) Your PlayList class extends ArrayList (I am not sure it's a good idea). Therefore, if you didn't override the equals method, the comparison is based on the sequence of elements only. For example, any two empty PlayList instances will be considered equal.
3) If you DID override equals, check your implementation. It must return true for a comparison with the same reference, and in your case it doesn't.
I'm not sure why you are having this problem, but I think if I were you I would choose to use the newer Generic List to create your list like this:
List<Playlist> mPlaylists = new List<Playlist>();
p = new Playlist(<some parameters>);
mPlaylists.Add(p);
精彩评论