This question already has answers here:
Use interface or type for variable definition in java?
(8 answers)
Closed 8 years ago.
I want to ask a question about using List in Collections API of java :
List <Integer> list = new ArrayList<>();
ArrayList<Integer> aList = new ArrayList<>();
We can use either for making an object of ArrayList, so which is the better way to create an ArrayList, and why?
The first option makes the rest of your code more modular, since you can replace the List implementation used by your code by changing a single line of code.
You'd just have to change
List <Integer> list = new ArrayList<>();
to
List <Integer> list = new SomeOtherListImplementation<>();
Declaring the variable to be ArrayList ties your code to the ArrayList implementation of the List interface.
If, however, your code requires usage of methods of ArrayList that are not part of the List interface, you might have to use an ArrayList variable.
The first case called as programming to interfaces.
If you stick to interface programming and implement your programm later you may change it to some other implementation.
For ex
List <Integer> list = new LinkedList<>();
If you code in first way, when ever you need to change just change the Right Hand Side of the initialization part and you are done without any code breakage and without any compiler error.
ArrayList<Integer> aList = new ArrayList<>();
Above line of code is ok if the variable aList is not modified later.
List <Integer> list = new ArrayList<>();
But if you want to add more flexibility to your code I would suggest this way because you can later declare the list variable to a different List implementation.
List <Integer> list = new LinkedList<>();
It will not break the code because it ensures that you only call the methods that are defined by the List interface.
First approach is modular. Which is taking advantage of fact that "Base class pointer can point to Derived class Object".
This is particularly helpful while we are passing argument. say,
public void display(List<String> names);
LinkedList<String> names = new LinkedList<String>();
display(names);
Related
This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 2 years ago.
I am learning about interfaces in Java and one example they give is being able to create a linked list using the List interface List<String> strings = new LinkedList<>(); but they don't go into any detail. Why would I want to do this as oppose to LinkedList<String> strings = new LinkedList<>();?
List<T> is an interface, meaning there are a certain number of methods that you must implement when you extend List. LinkedList happens to extend List. When you do List<String> strings = new LinkedList<>();, java only sees List's methods. However, when you do LinkedList<String> strings = new LinkedList<>(); java sees it as a LinkedList and it will work when you call methods LinkedList has like getLast. People do List<String> strings = new LinkedList<>(); mainly for readability but it should be about the same.
For local variables, it doesn't matter all that much, at least not in this case.
The main benefit of List<String> strings = new LinkedList<>(); is that you could simply swap the LinkedList for an ArrayList or any other List implementation if needed.
This is most important at the "edges" of your class (parameters, return types, fields) because it makes your API more flexible for two reasons:
Other classes are not bound by your choice of List implementation, because your class will take any List
Other classes that interface with your class are forcibly unaware of your class' internal choice of which List implementation to use, which means you can switch from an ArrayList to a LinkedList or vice versa at any time, without breaking code outside of your class
From Effective Java, 3rd Edition, Item 64:
REFER TO OBJECTS BY THEIR INTERFACES
If you get into the habit of using interfaces as types, your program
will be much more flexible. If you decide that you want to switch
implementations, all you have to do is change the class name in the
constructor (or use a different static factory).
So, with List<String> strings = new LinkedList<>();, you just have to change the implementation name and the rest of the client code remains same.
With LinkedList<String> strings = new LinkedList<>();, you may have to modify your client code.
Note that it's entirely appropriate to go ahead with implementation class as types. But, if you can use an interface as type, it's the best choice.
This question already has answers here:
Incompatible types List of List and ArrayList of ArrayList
(7 answers)
Initialize List<List<Integer>> in Java
(4 answers)
Closed 5 years ago.
I want to understand the difference between the two definitions and why the correct one is correct and the wrong is wrong.
The one showing me the compile-error
List<List<Integer>> arr2 = new ArrayList<ArrayList<Integer>>();
The error it gave me :
try2.java:8: error: incompatible types: ArrayList<ArrayList<Integer>> cannot be
converted to List<List<Integer>>
List<List<Integer>> arr2 = new ArrayList<ArrayList<Integer>>();
The one which is working:
List<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
NOTE:
I understand why the below one works:
List<Integer> arr = new ArrayList<Integer>();
Edit-1:
Now i just want to understand what is wrong with List<List<Integer>> arr2 = new ArrayList<ArrayList<Integer>>();
You don't need any of that:
List<List<Whatever>> items = new ArrayList<>();
Done.
The important thing to understand: you can not create those "inner" lists. You just create a List (that has type "list of lists"). Later on, you would do:
List<Whatever> innerItems = new ArrayList<>();
items.add(innerItems);
for example. The reason is: collections are not arrays. Java allows you to write down expressions that create a full blown 2-dim array. But collections don't have that concept of multiple dimensions (implementation-wise)!
One part of that is the fact that generics are actually implemented using type erasure. This means: the actual list implementation doesn't know anything about the generic type you used in your source code. It is only dealing with instances of Object. In that sense, it is not possible that the implementation "knows" that the new List is supposed to contain List<Whatever>.
You could use the diamond operator, as GhostCat suggested, and let the compiler worry about the correct type.
But if you want to understand what the correct type should be, use:
List<List<Integer>> arr2 = new ArrayList<List<Integer>>();
You are instantiating a List of something (let's forget for a second that something happens to be a List<Integer>), so you need to create an instance of a class that implements the List interface - ArrayList in this case. So you create an instance of ArrayList of something.
The element type (my so called "something") - List<Integer> in your example - remains unchanged.
Now, when you want to add an element to your List, you need to create an instance of a class that implements List<Integer>:
List<Integer> inner = new ArrayList<Integer>();
arr2.add(inner);
This question already has answers here:
How can Arrays.asList return an instantiated List?
(3 answers)
Closed 7 years ago.
I know that an object cannot be created from an interface like this :
List list2 = new List(); // error.
When i work with Arrays.asList(),i'm confused, because this function returns List and the following code works perfectly:
List list1 = Arrays.asList("a","b","c"); // works perfectly
Right side of this equation returns List. Then the code becomes List list1=new List(); How can this be possible and how this code works although the right side returns an interface, i didn't understand. Can you explain it please?
Thanks in advance
Arrays.asList(...) returns a new ArrayList.
Due to polymorphism it can state that it returns a List, and then return anything that implements the List interface. An ArrayList is a list, so it can be returned.
Extra Note: The ArrayList that asList is using is actually created in the Arrays class as an anonymous class that extends the functionality of the ArrayList class to create a constructor that accepts a native array.
List is an "Interface". You cannot create a new instance ( via new ...) from an Interface, you need a "real" class for that. Arrays.asList is a method that returns an object.
For your first code, you must do something like...
List list2 = new ArrayList();
ArrayList is a Class that implements the List interface. But sorry, I fear that you need to consult some basic Java and OOP tutorials to understand what classes, interfaces, objects, etc. really are, as this is not the place for something like this.
The thing is that List is an interface, not a class. You can only instantiate classes, not interfaces under Java. So you either need to create a new type that implements List (e.g. ArrayList or LinkedList, i.e. List list2 = new ArrayList();) or you can obtain a list like you did by calling a method that creates a list.
This question already has answers here:
How to initialize List<String> object in Java?
(13 answers)
Closed 7 years ago.
I have the following code:
List<Product> product = new List<Product>();
The error:
Cannot instantiate the type List<Product>
Product is an Entity in my EJB project. Why I'm getting this error?
List is an interface. Interfaces cannot be instantiated. Only concrete types can be instantiated. You probably want to use an ArrayList, which is an implementation of the List interface.
List<Product> products = new ArrayList<Product>();
Use a concrete list type, e.g. ArrayList instead of just List.
List is an interface. You need a specific class in the end so
either try
List l = new ArrayList();
or
List l = new LinkedList();
Whichever suit your needs.
List can be instantiated by any class implementing the interface.By this way,Java provides us polymorphic behaviour.See the example below:
List<String> list = new ArrayList<String>();
Instead of instantiating an ArrayList directly,I am using a List to refer to ArrayList object so that we are using only the List interface methods and do not care about its actual implementation.
Examples of classes implementing List are ArrayList,LinkedList,Vector.You probably want to create a List depending upon your requirements.
Example:- a LinkedList is more useful when you hve to do a number of inertion or deletions .Arraylist is more performance intensive as it is backed by a fixed size array and array contents have to be changed by moving or regrowing the array.
Again,using a List we can simply change our object instantiation without changing any code further in your programs.
Suppose we are using ArrayList<String> value = new ArrayList<String>();
we may use a specific method of ArrrayList and out code will not be robust
By using List<String> value = new ArrayList<String>();
we are making sure we are using only List interface methods..and if we want to change it to a LinkedList we simply have to change the code :
List<String> value = new ArrayList<String>();
------ your code uses List interface methods.....
value = new LinkedList<String>();
-----your code still uses List interface methods and we do not have to change anything----
and we dont have to change anything in our code further
By the way a LinkedList also works a Deque which obviously also you cannot instantiate as it is also an interface
Interfaces can not be directly instantiated, you should instantiate classes that implements such Interfaces.
Try this:
NameValuePair[] params = new BasicNameValuePair[] {
new BasicNameValuePair("param1", param1),
new BasicNameValuePair("param2", param2),
};
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Type List vs type ArrayList in Java
Why is it recommended to do this:
List<String> myArrayList = new ArrayList<String>
or same with Map interface and HashMap class
rather than:
ArrayList<String> myArrayList = new ArrayList<String>
Because the consuming code of the myArrayList variable won't be tied to a particular implementation of this interface.
With the first (preferred) line you say, that your code needs a List, with the second line you say your code needs an ArrayList. Usually, you path variable instances around. If you now change the myArrayList instance for some reason you would have to change too much code.
You should not use:
List<String> myArrayList = new ArrayList<String>
Why you should use the type List instead of ArrayList (unless you really need feature of the ArrayList that is missing in the List interface) is already explained in the other answer.
But I think it is even more important to use proper names. So if you use List as type for the variable, the name should not tell that it is an ArrayList. It would be even better if the name indicated the use of the variable.
Yes, this is picky. But using good names will make it a lot easier to understand the code in a year from now and for colleagues.