When I see the Set.java file in JDK,
/**
*
* <p>This interface is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @param <E> the type of elements maintained by this set
*
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
* @see List
* @see SortedSet
* @see HashSet
* @see TreeSet
* @see AbstractSet
* @see Collections#singleton(java.lang.Object)
* @see Collections#EMPTY_SET
* @since 1.2
*/
public interface Set<E> extends Collection<E> {
/**
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
* @throws UnsupportedOperationException if the <tt>add</tt> operation
* is not supported by this set
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this set
* @throws NullPointerException if the specified element is null and this
* set does not permit null elements
* @throws IllegalArgumentException if some property of the specified element
* prevents it from being added to this set
*/
boolean add(E e);
/**
* @param o object to be removed from this set, if present
* @return <tt>true</tt> if this set contained the specified element
* @throws ClassCastException if the type of the specified element
* is incompatible with this set
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if the specified element is null and this
* set does not permit null elements
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
* is not supported by this set
*/
boolean remove(Object o);
//other methods
}
I am not getting, why add
method is taking E
parameter and remove
method is taking Object
parameter as a input argument?
Any help or reference link to understand this behavior would be appreciate.
In
public boolean add(E e)
E means the the type of elements maintained by this set. You can only permitted element of type in collection. Inernally its maps at workIn
public boolean remove(Object o)
Removes the specified element from this set if it is present. You dont need to check what type of element it is - just check if its there take it out.again maps at work internally
I agree, it's wierd, but it allows you to do the following:
Because your Set will always return E, but you may want to check if an object (not necessarily E) is in the Set.
The
add
method of collections is 'covariant', which means that you can add any element of typeE
or of a subtype ofE
. Theremove
method however is contravariant, you can remove any object that is a either of typeE
or of a supertype ofE
. Normally, the syntax would have to beBut since this syntax is not valid in Java (unfortunately), the type of the parameter is
Object
, which is always a super type ofE
, no matter whatE
is.This also allows you to remove an object from the collection whose runtime type is
E
while its compile-time type is a supertype ofE
. For example, take a look at this simple piece of codeThis code shows that you should be able to remove any object from the collection that has the same or a supertype of the collection. Due to the syntactic limitation of Java, the method would also accept any other object that could never be in the collection due to its type:
This example compiles perfectly fine, but it makes no sense: You could never have an Integer in your
List<String>
.Conclusion
The parameter type of
remove
isObject
because it represents the supertype of all types, and it lets you remove an element that has been upcasted toObject
while it could still be an element in the collection due to its runtime type. The signatureremove(? super E)
is neither possible nor necessary, but it would warn the programmer when an operation can never succeed, likeremove(1)
on aList<String>
.