Arraylist with List<interfaceI>
and List<? extends InterfaceI>
both will have objects of classes implementing interfaceI. Then when what should be used?
There is no difference whatsoever. extends Object is redundant and assumed otherwise, just like writing class F extends Object .
List and Set interfaces are one of them that are used to group the object. Both interfaces extend the Collection interface. The main difference between List and Set is that Set is unordered and contains different elements, whereas the list is ordered and can contain the same elements in it.
The List interface extends Collection and declares the behavior of a collection that stores a sequence of elements. Elements can be inserted or accessed by their position in the list, using a zero-based index. A list may contain duplicate elements.
List is a Java interface that describes a sequential collection of objects. ArrayList is a class that describes an array-based implementation of the List Java interface.
The difference is that if you declare your list as List<? extends S> myList
, the myList
variable can by list of any type that extends S
so associations like shown below will work:
public class Clazz implements S{}
List<? extends S> myList = new List<Clazz>(); // its fine as Clazz extends S
List<? extends S> myList = new List<S>(); // its fine as well
List<? extends S> myList = new List<Object>(); // ooooops it wil not work
But in such case you will not be abe to PUT
anything to such list as you cannot guarantee the exact type of object that is held by list implementation assigned to myList
If you declare List<S> myList
than you will be able to PUT
and GET
objects from list, as you are sure what is in it, however assignments from above will not work!
public class Clazz implements S{}
List<S> myList = new List<Clazz>(); // no way!
List<S> myList = new List<S>(); //thats perfectly fine! - You can PUT new S in it;
List<S> myList = new List<Object>(); //known result;
Suppose Foo
and Bar
are two classes implementing InterfaceI
.
The second one (List<? extends InterfaceI>
) doesn't allow adding anything to the list (except null), since the type that the list contains is unknown: it could be a List<Foo>
or a List<Bar>
: you just don't know.
So you usually use this notation for a method argument, when you want the method to read the elements of the list passed as argument, and want the caller to be able to call your method with a List<InterfaceI>
, a List<Foo>
or a List<Bar>
. Using List<InterfaceI>
as argument would only accept lists of type List<InterfaceI>
.
Let's take a concrete example: you want to compute the maximum double value of a list of numbers. Such a method doesn't need to add or set anything to the list. All it does is iterating on the elements, get each number and compute their maximum. The signature could be
public double max(List<Number> list);
But then, you won't be able to do
List<Integer> ints = new ArrayList<>();
max(ints);
The only way to call this method is to do
List<Number> ints = new ArrayList<>();
max(ints);
Whereas if you declare the method as
public double max(List<? extends Number> list);
then you can do
List<Integer> ints = new ArrayList<>();
List<Long> longs = new ArrayList<>();
max(ints);
max(longs)
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