Why isn't List.indexOf using generic types? I can have a List<Integer> but the indexOf method still takes an object which seems nutty to me, shouldn't it be int IndexOf(E o)?
« DataGrid and NUMA/Bluegene | Main | The future of frameworks and multi-core, a return to fibers »
The comments to this entry are closed.
Great question. I poked around a little and I can't come up with a compelling answer. Seems like switching to E here would not affect the compile-time safety of the class (like it does for add or for other methods that return a value), so it isn't required.
Depending how you look at it, you could consider it valid to search for a wider type in the collection, even if you won't ever find it due to the compile-time checks. That kind of thinking could mean that making this Object protected legacy non-generic code from breaking? Just a guess.
Posted by: Alex Miller | January 17, 2007 at 01:09 PM
I suspect because the obvious (if not best) solution would be to search down the list from the start to the end calling equals on each object. This does not require the type, or a cast, so in this implementation it doesn't really matter.
Yes this is odd, and they probably should have used E, but if they didn't have a cast in Java implementations of List it was probably never an issue, and it doesn't affect the contents of the list. You'll notice that the following methods have the same oddness:
contains
lastIndexOf
remove
also the methods:
containsAll
removeAll
retainAll
take a Collection rather than Collection.
Oh and why does toArray() return Object[] and not E[] (that one really annoys me).
Alasdair
Posted by: Alasdair | January 17, 2007 at 01:19 PM
You're late to the party.
If indexOf took an E, then you wouldn't be able to find out whether any kind of element was in a List[?], nor in a List[? extends Number].
Also, it wouldn't be possible to have a List[String], do Object o="hello" and then find out whether 'o' is in the List[String].
Don't be fooled by anyone who comes here and comments about backward compatibility - that's already ensured by allowing raw types.
Posted by: Ricky Clarkson | January 17, 2007 at 01:30 PM
Just Object.equals(o) dont need concrete type infomation, it seems.
Posted by: | January 18, 2007 at 12:48 AM
In response Alasdair's complaint: "Oh and why does toArray() return Object[] and not E[] (that one really annoys me)."
The issue here is that E is not a reifiable type. What this means is that due to erasure, it is NOT possible to do this: new E[10]. So toArray() has to return Object[]. You should use toArray(E[]) instead and pass in an array of the correct type.
Posted by: Simon Archer | January 22, 2007 at 02:13 PM