Is there historical reasons to the two ambiguous List.remove
?
List.remove(int)
List.remove(Object)
It seems like terrible design to me.
For a List<Integer>
it just seems really confusing.
EDIT:
Everybody seems pretty fine with this. Let me precise things a bit.
Let's say I have a List<Boolean>
.
Integer idx = Integer.valueOf(2);
list.remove(idx)
Though idx
is an object, Java compiles and will remove the item at index 2.
Now if it had been a List<Integer>
, the very same code would have called a different method with a totally different behavior.
Let's not talk about what would happen with Generics.
I feel like different behavior implies different names is a precious rule, especially within the same class.
The process of compiler trying to resolve the method call from given overloaded method definitions is called overload resolution. If the compiler can not find the exact match it looks for the closest match by using upcasts only (downcasts are never done). As expected the output is 10.
First of all:
List.remove(int)
removes an element at the specified index andList.remove(Object)
(or Collection.remove(Object)
) removes the specified element.I'm not sure if this was already known, but for completeness sake, I thought I'd mention it.
An important part to notice is that the API predates generics (and more importantly) auto-boxing by quite a bit (the collections API was introduced in Java 1.2 and auto-boxing was introduced in Java 5).
So when they first designed the API, there was absolutely no way to confuse the two. Even if your List
contained Integer
objects, it's simple: if you call the method with a primitive argument type (int
), then it's the index, if you pass in an Object
(even if it's Integer
), then you pass in the object to remove.
Granted, it's still not the greatest idea (but quite a few Java APIs are ... less than perfect), but the chance for confusion was much lower back then.
The increased chance of confusion only exists since the int
/Integer
barrier became less visible thanks to auto-boxing and auto-unboxing.
Sidenote: an important "feature" of the collections API is "short names for commonly used methods". The previous "solution" of Vector
/Enumeration
had notoriously long names for pretty common operations:
Vector.elementAt()
vs. List.get()
Vector.addElement()
vs. Collection.add()
Enumeration.hasMoreElements()
/nextElement()
vs. Iterator.hasNext()
/next()
Vector.removeElement()
vs. Collection.remove()
Vector.removeElementAt()
vs. List.remove(int)
And the last one are where they probably went a bit too far.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With