« DataGrid and NUMA/Bluegene | Main | The future of frameworks and multi-core, a return to fibers »

January 17, 2007

Java 5 generic List strangeness

Why isn't List.indexOf using generic types? I can have a List but the indexOf method still takes an object which seems nutty to me, shouldn't it be int IndexOf(E o)?

January 17, 2007 | Permalink

Comments

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 | Jan 17, 2007 12:09:21 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 | Jan 17, 2007 12:19:51 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 | Jan 17, 2007 12:30:23 PM

Just Object.equals(o) dont need concrete type infomation, it seems.

Posted by: | Jan 17, 2007 11:48:53 PM

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 | Jan 22, 2007 1:13:14 PM

Post a comment