Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List<interfaceI> vs List<? extends InterfaceI> in java

Arraylist with List<interfaceI> and List<? extends InterfaceI> both will have objects of classes implementing interfaceI. Then when what should be used?

like image 788
HimanshuR Avatar asked Aug 18 '14 10:08

HimanshuR


People also ask

Are List <?> And List <? Extends object the same?

There is no difference whatsoever. extends Object is redundant and assumed otherwise, just like writing class F extends Object .

What is the difference between List interface and set interface?

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.

Does List extend collections interface?

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.

Is a List An interface in Java?

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.


2 Answers

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;
like image 28
Antoniossss Avatar answered Sep 22 '22 22:09

Antoniossss


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)
like image 109
JB Nizet Avatar answered Sep 23 '22 22:09

JB Nizet