"Instantiating" a List in Java? [duplicate] - java

This question already has answers here:
How to initialize List<String> object in Java?
(13 answers)
Closed 8 years ago.
Trying to use the following code:
List<Integer> list = new List<Integer>();
I get the following error message:
java.util.List is abstract; cannot be instantiated
What does this mean and why can't I initialize a List the same way I would an ArrayList?

In Java, List is an interface. That is, it cannot be instantiated directly.
Instead you can use ArrayList which is an implementation of that interface that uses an array as its backing store (hence the name).
Since ArrayList is a kind of List, you can easily upcast it:
List<T> mylist = new ArrayList<T>();
This is in contrast with .NET, where, since version 2.0, List<T> is the default implementation of the IList<T> interface.

List is an interface, not a concrete class.
An interface is just a set of functions that a class can implement; it doesn't make any sense to instantiate an interface.
ArrayList is a concrete class that happens to implement this interface and all of the methods in it.

Use List<Integer> list = new ArrayList<Integer>();

List is the interface, not a class so it can't be instantiated. ArrayList is most likely what you're after:
ArrayList<Integer> list = new ArrayList<Integer>();
An interface in Java essentially defines a blueprint for the class - a class implementing an interface has to provide implementations of the methods the list defines. But the actual implementation is completely up to the implementing class, ArrayList in this case.
The JDK also provides LinkedList - an alternative implementation that again conforms to the list interface. It works very differently to the ArrayList underneath and as such it tends to be more efficient at adding / removing items half way through the list, but for the vast majority of use cases it's less efficient. And of course if you wanted to define your own implementation it's perfectly possible!
In short, you can't create a list because it's an interface containing no concrete code - that's the job of the classes that implement that list, of which ArrayList is the most used by far (and with good reason!)
It's also worth noting that in C# a List is a class, not an interface - that's IList. The same principle applies though, just with different names.

A List isn't a real thing in Java. It's an interface, a way of defining how an object is allowed to interact with other objects. As such, it can't ever be instantiated. An ArrayList is an implementation of the List interface, as is a linked list, and so on. Use those instead.

A List in java is an interface that defines certain qualities a "list" must have. Specific list implementations, such as ArrayList implement this interface and flesh out how the various methods are to work. What are you trying to accomplish with this list? Most likely, one of the built-in lists will work for you.

Related

Instantiating an interface with a concrete class

Suppose for a program that I needed a List of some kind. Any kind of List will do, so I create one.
List<Integer> example = new LinkedList<Integer>();
I've heard that it's good practice, when instantiating your objects, to define them as interfaces, if you are doing something that requires the use of that interface, but not necessarily that specific concrete class. For example, I could have made that "example" list an ArrayList instead.
However, defining my LinkedList to be a List interface in this way limits me. I can't use any of the LinkedList-specific methods, for example. I can only use methods that are in the List interface itself. The only way I've found to use my LinkedList-specific methods are to cast example to a LinkedList, like so:
((LinkedList)example).addLast(1);
...which seems to defeat the purpose, since by casting "example" to be a LinkedList, I may as well have created it and defined it to be a LinkedList in the first place, instead of a List.
So why is it good practice to create concrete classes and define them via interface? Is there something that I am missing?
LinkedList implements several interfaces.
The method addLast() comes from the Deque interface. It could be that's the interface you want to use.
Alternatively you might just need a List, in which case the add() method will append to the list.

Why we should use Interface, instead of concrete types?

When using collections in Java, we are advised to use Interface instead of concrete types.
Like: List<Object> list = new ArrayList<Object>();
But, using ArrayList<Object> list = new ArrayList<Object>(); will also does the same job, right?
Yes, but if you later change your mind and use a LinkedList You have to change much more in your code.
That is the Polymorphism which is the core concept of OOP.
It means ‘a state of having many shapes’ or ‘the capacity to take on different forms’. When applied to OOP , it describes a language’s ability to process objects of various types and classes through a single, uniform interface.
List is a Uniform interface and its Different implementations are like ArrayList ,LinkedList.....etc
Prefer to read :What does it mean to program to a interface?
When you define your list as:
List myList = new ArrayList();
you can only call methods and reference members that belong to List class. If you define it as:
ArrayList myList = new ArrayList();
you'll be able to invoke ArrayList specific methods and use ArrayList specific members in addition to those inherited from List.
Nevertheless, when you call a method of a List class in the first example, which was overridden in ArrayList, then method from ArrayList will be called not the one in the List.
Also the first has the advantage that the implementation of the List can change (to a LinkedList for example), without affecting the rest of the code. This is will be difficult to do with an ArrayList, not only because you will need to change ArrayList to LinkedList everywhere, but also because you may have used ArrayList specific methods.
There's a useful principle: for declared types, use the loosest (vaguest) interface possible (and List is 'looser' than ArrayList).
In practice, this means if you only need to access methods declared in List<Object> on your list instance (which is actually an ArrayList), then declare it as List<Object>. This means you can change your mind on the exact type of list later and you only need to change the line that actually instantiates the ArrayList (or LinkedList or whatever you choose).
This has implications for method signature too: if you were passing around an ArrayList instead of a List, and then changed your mind about it being an ArrayList, you have to go and edit lots of method signatures.
Please read up on Polymorphism if you'd like to know more.
Tangentially related is the Liskov Substitution Principle:
What is the Liskov Substitution Principle?
Interfaces or should I say base calsses are used to generalize things and problems at hand. So when you implement an interface you can always get the specific objects.
For example:
From Animal interface or super class you can always derive specific interfaces or calsses like Lion, but not the other way, becaus its true that a Lion is an animal but several other animals cannot be derived from Lion. Thats why it is advised to make things general and hence use interfaces.
Same applies in your case. You can always get ArrayList and other implementations from a List.
Say you have a class with the following method
public ArrayList<T> foo (ArrayList<T> someInput) {
//Do some operations on someInput here...
return someOutput;
}
Now, what happens if you change the program so that it uses LinkedList objects instead of ArrayList objects? You will get a compiler error wherever this method is called, and you would have to go through and refactor your code so that it accepts LinkedList objects.
If you had programmed to an interface and used a List instead:
public List<T> foo (List<T> someInput) {
//Do some operations on someInput here....
return someOutput;
}
If this was the case, no refactoring would be necessary as both the LinkedList and ArrayList classes implement List so there would be no compiler errors. This makes it incredibly flexible. It does not matter to the method what it takes in and what it returns, as long as the objects implement the List interface. This allows you to define behaviour without exposing any of the underlying implementation.

Reason for - List list = new ArrayList(); [duplicate]

This question already has answers here:
Why do some people use the List base class to instantiate a new ArrayList?
(4 answers)
What does it mean to "program to an interface"?
(33 answers)
Closed 9 years ago.
I have seen code like this many times:
List<String> list = new ArrayList<String>();
Why do people take the parent of ArrayList (and other classes) instead of the type of the generated object?
Does that take less performance? Or why should someone do this?
When someone writes code like this, he/she is trying to follow a basic OO design principle which says -
Program to an interface, not to a concrete implementation
I have explained this principle in one of my blog posts. Look in the Class Inheritance VS Interface Inheritance section.
To summarize the post, when you use a reference of a parent type to refer to an instance of a sub-type, you get a lot of flexibility. For example, if you ever need to change your sub-type implementation in the future, you will be able to do that easily, without changing much of your code.
Consider the following method -
public void DoSomeStuff(Super s) {
s.someMethod();
}
and a call to this method -
DoSomeStuff(new Sub());
now, if you ever need to change the logic inside someMethod, you can easily do it by declaring a new subtype of Super, say NewSubType, and changing the logic inside that implementation. In this way, you will never have to touch other existing code which utilizes that method. You will still be able to use your DoSomeStuff method in the following way -
DoSomeStuff(new NewSubType());
Had you declared the parameter of DoSomeStuff to be of Sub, you would then have to change its implementation too -
DoSomeStuff(NewSubType s) {
s.someMethod();
}
and it may also chain/bubble to several other places.
In terms of your collection example, this lets you change the list implementation that a variable is pointing to without much hassle. You can easily use a LinkedList in place of an ArrayList.
When you write:
List<String> list = new ArrayList<String>();
Then you are sure you'll use only the functionality of the interface List. (ArrayList implements List, so List is more flexibl).
Using this, allows you to change the ArrayList to other types in the future (like LinkedList..).
It means you can swap out the type of list at any point with anything that implements the List interface, as opposed to creating a rigid model that can only use ArrayList. For example:
private List<String> list;
public SomeConstructor()
{
// At this point, you can make it any type of object you want.
list = new ArrayList<String>();
list = new LinkedList<String>();
list = new AttributeList<String>();
}
This will abstract your code that uses the list object, away from the details like what exact object type list is. All it needs to know is that it has the add method etc. This is called Loose Coupling.
To sort things out:
For more flexibility you initiate interface List:
So if you don't need all ArrayList use List only.
You can write something like: List<String> = Arrays.asList("aa", "bb","cc").
For sure, less functionality can help to performance. As you know If you want to use multithreaded application, use Vector instead but it will down your performance.
Took from here
Because a method doesn't have to know what list-implementation you use.
A Method just needs to know that is is a list.
The Method can still be used.
Always program to an interface, not to a concrete implementation. (In this case List)
Generally it is preferred to work with the Interface class (List in this case) so that any List implementation could later be substituted with minimal fuss if requirements change.
Although ArrayList possibly supports some methods that are not on the List interface, this declaration makes it clear that those extra methods are not relevant in that case.
List<String> list = new ArrayList<String>();
In collection framework List is an interface while ArrayList is implementation. Main reason you'd do this is to decouple your code from a specific implementation of the interface also this will be helpful in case if you wish to move to some other implementation of List in the future.

List<Object> listObject = new ArrayList<Object>()?

So many time I have seen that instantiation of Arraylist is done in the manner "
List<Object> listObject = new ArrayList<Object>();
So I am wondered that what is the significance of instantiation of Arraylist in this way? What happens if we instantiate ArrayList() like
ArrayList<Object> listObject = new ArrayList<Object>();
List is an interface , ArrayList class is a specific implementation of that interface.
List<Object> listObject = new ArrayList<Object>();
With this you can change the List implementation in future. List listObject can invoke all the methods declared in the List interface. In future , if you don't want the ArrayList implementation of the List, and change it with say a LinkedList , you can do that :
List<Object> listObject = new LinkedList<Object>();
You will not have to alter the code which uses listObject , if you had declared the listObject as List interface type, and not worry about it breaking the rest of the code because you might have used something specific to ArrayListwith this declaration:
ArrayList<Object> listObject = new ArrayList<Object>();
This is called Programming to an interface, not to an implementation.
This is because of the fact that its always a good practice to write code to interface and not implementation. So when you do List<Object> listObject = new ArrayList<Object>(); you always have the liberty to change ArrayList to LinkedList and elsewhere in the code will need no change. So programming to interface (List) here gives you the liberty/power to change the underlying implementation without affecting other places in code. I will suggest you to read this small note to have more clarity.
Most of answers refer to the mantra of "coding to the interface". Although, it is a sound advice, it might lead to some problems. Specifically, in case of List the user of object listObject would not know anything about the efficiency of the underlying data structure. For example, if this is an instance of ArrayList then getting the last element is only O(1), while if it is a LinkedList then it is O(listObject.size).
Therefore, often it is very important to know the exact underlying data structure, which can be achieved by using the implementation type for variable declaration. For instance, Scala's List is a class that make its data structure explicit.
Thus, I would say that as always, the decision should be an informed one and cater toward the design of your application. If the data structure should be "a list" and no requirements for specific implementation is known then use List for declaration. However, if a set of algorithms that should work on that data structure is well known then use a concrete implementation class (i.e. ArraysList, LinkedList) that would ensure optimal performance of those algorithms.
There's no difference between list implementations in both of your examples. There's however a difference in a way you can further use variable myList in your code.
When you define your list as:
List myList = new ArrayList();
you can only call methods and reference members that belong to List class. If you define it as:
ArrayList myList = new ArrayList();
you'll be able to invoke ArrayList specific methods and use ArrayList specific members in addition to those inherited from List.
Nevertheless, when you call a method of a List class in the first example, which was overridden in ArrayList, then method from ArrayList will be called not the one in the List.
That's called polymorphism.
This will ,"Program to an interface and not to an Implementation"
Please have a look at this and this
List is an interface, and ArrayList is a class. Best practices say: Program against interfaces, not concrete classes.
Actually, there may be no difference between those two definitions (defining the variable type as interface vs class), but using List makes your code dependent on the interface, not the class. Then you can later change the actual type of the variable, without affecting the code that is using the variable.
Because you can use different implementations of the same interface(in this case you may want to change your List implementation to a linkedList instead of an ArrayList ) without changing code.
Why should the interface for a Java class be preferred?
As of Java 7 these are the known implementations of List
All Known Implementing Classes:
AbstractList, AbstractSequentialList,
ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList,
RoleUnresolvedList, Stack, Vector
Leaving aside the Abstract classes what this means is that in the future if you want to plug in a different List implementation other than ArrayList you have a variety of options.
Also called Coding to Interfaces this is a widely used programming paradigm.
When you use List you use Abstraction. Imaging a case wherein there is function call expects List<Object>
List<Object> myList = myFunction();
now in function myFunction(),
its better to use
List<Object> myList = new ArrayList<Object>();
return myList;
than
ArrayList<Object> myList = new ArrayList<Object>();
because you will avoid unnecessary casting. The calling function only expects a List irrespective of its implementation.
Moreover, List interface offers a lot of generic functions which are applicable for all the implementations. So you can write some generic code manipulating a list irrespective of whether its LinkedList or ArrayList. This is the advantage of using Abstraction.
List is an Interface. when ever you define interface as reference we have to instantiate using it's implementation.

Why assign a new ArrayList to a List variable?

I am new to java and when I go through the code of many examples on net I see people declaring the variable for an ArrayList as simply List in almost all the cases.
List<String> myList = new ArrayList<String>();
I don't understand if there is some specific advantage of doing this. Why can't it be an ArrayList itself, like so:
ArrayList<String> myList = new ArrayList<String>();
It's called programming to an interface. It allows you to substitute that ArrayList for a LinkedList if somewhere down the line you decide that a LinkedList would be more appropriate.
Because if you decide to change it later it's easier:
List<String> myList = new ArrayList<String>();
List<String> myList = new LinkedList<String>();
It's more important in method signatures, when changing what you return can force everyone using your function to change their code.
This isn't a cast but rather you are using the interface as the declared type of the variable. The reason for doing this is that you can switch which implementation of List you are using. If users of the list only depend on the List interface, they won't be affected if you using another list type, such as LinkedList.
List is an interface so it can store referance to all classes extending from List Interface.If you used following statment then after some programing steps you can also store other Objects(extending from List) referance.
List<String> myList = new ArrayList<String>();
...
myList =new LinkedList<String>();
The main advantage comes with this is code maintenance. For instance, if someone comes and wants to use a LinkedList instead of the ArrayList, you only need to change one line rather than zillions throughout the code. It makes your code a little more flexible.
The whole concept of polymorphism in java relies on java's ability to use interface/base class reference to reference to sub class objects.
Also, programming to an interface rather than to the actual implementation is always seen as a best practice. This would allow the developer to replace one implementation with other/better implementation easily when required.
Java is strongly typed object-oriented language. ....
Let's go through an example: Suppose that you are writing a sort function sort(ArrayList<> list). If the function declared in that way, java wont allow you to sort anything else with that function than ArrayList. Better approach would be to define an abstraction (as in your question is) List. In that abstraction you declare methods. that all implementations must implement-define (ie ArrayList). Now your sort function can be declared as sort(List<> list) and you can sort with it anything that implements List (and follows the contract of the List methods).
In this way you can reuse code that you wrote for all your implementations as long as they obey the contract of the abstraction. In Java you achieve this using interfaces as abstractions and classes as implementations. There are other advantages too, but you have read some book about Object-oriented programming if you want to understand them better.
1) List is an interface, the implementation class is ArrayList
2) List interface extends Collection.

Categories

Resources