Reputation: 11486
I have been reading Effective Java and I have come across the unbounded Collection type <?>
. However, the reading has led me to believe that you can't put any elements, other than null
, into an instance of Collection<?>
.
So, my question is this: what is the purpose of instantiating a Collection<?>
when we can only insert null
elements as it seems pointless. I've been trying to figure out this concept, but it just doesn't seems to make much sense. Any help would be much appreciated.
Upvotes: 13
Views: 869
Reputation: 4222
Collection
is a lowest abstraction of all Lists
and Sets
. It is good to use as lowest abstraction you can use, cuz it gives you more flexibility in future and your code is more robust, cuz it can handle all Lists
or Sets
or other implementations, which do not even have to be implemented yet.
Well, Collection is some way equivalent to Collection<Object>
. It just mean the generic type of the objects stored in Collection
is unknown or you can use lowest abstraction of any object which is Object
itself. In this case you can put into Collection
any object even mix it with different types. But you have to be aware to cast it into proper type at runtime because you did not provide what type of Object your Collection is storing. So, the Collection cannot cast the Object to proper type for you, you have to do it by yourself. To recognize proper type you should use Object instanceof SomeOtherClass
or Class.isAssignableFrom(Class)
at runtime.
Also Collection
does not implement get()
method but you can get Iterator
and obtain object from the collection this way.
Upvotes: 1
Reputation: 8161
Collection<?>
allows you to create, among other things, methods that accept any type of Collection
as an argument. For instance, if you want a method that returns true
if any element in a Collection
equals some value, you could do something like this:
public boolean collectionContains(Collection<?> collection, Object toCompareTo) {
for (Object o : collection) {
if (toCompareTo.equals(o)) return true;
}
return false;
}
This method can be called by any type of Collection
:
Set<String> strings = loadStrings();
collectionContains(strings, "pizza");
Collection<Integer> ints = Arrays.toList(1, 2, 3, 4, 5);
collectionContains(ints, 1337);
List<Collection<?>> collections = new ArrayList<>();
collectionContains(collections, ILLEGAL_COLLECTION);
Upvotes: 24
Reputation: 2520
When you are declaring a collection with wildcards you specify that the collection is a supertype of all kind of collections.
This is really useful when you have a method on which you would want to pass all types of collection let's say for example:
void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e);
}
}
Have a look at Oracle's documentation about wild cards as it's very exhaustive.
Upvotes: 1
Reputation: 121998
Consider the following Util method from docs
The following method shows you how to use an Iterator to filter an arbitrary Collection — that is, traverse the collection removing specific elements.
static void filter(Collection<?> c) {
for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next()))
it.remove();
}
This simple piece of code is polymorphic, which means that it works for any Collection
regardless of implementation.
Upvotes: 5