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.
Related
PMD would report a violation for:
ArrayList<Object> list = new ArrayList<Object>();
The violation was "Avoid using implementation types like 'ArrayList'; use the interface instead".
The following line would correct the violation:
List<Object> list = new ArrayList<Object>();
Why should the latter with List be used instead of ArrayList?
Using interfaces over concrete types is the key for good encapsulation and for loose coupling your code.
It's even a good idea to follow this practice when writing your own APIs. If you do, you'll find later that it's easier to add unit tests to your code (using Mocking techniques), and to change the underlying implementation if needed in the future.
Here's a good article on the subject.
Hope it helps!
This is preferred because you decouple your code from the implementation of the list. Using the interface lets you easily change the implementation, ArrayList in this case, to another list implementation without changing any of the rest of the code as long as it only uses methods defined in List.
In general I agree that decoupling interface from implementation is a good thing and will make your code easier to maintain.
There are, however, exceptions that you must consider. Accessing objects through interfaces adds an additional layer of indirection that will make your code slower.
For interest I ran an experiment that generated ten billion sequential accesses to a 1 million length ArrayList. On my 2.4Ghz MacBook, accessing the ArrayList through a List interface took 2.10 seconds on average, when declaring it of type ArrayList it took on average 1.67 seconds.
If you are working with large lists, deep inside an inner loop or frequently called function, then this is something to consider.
ArrayList and LinkedList are two implementations of a List, which is an ordered collection of items. Logic-wise it doesn't matter if you use an ArrayList or a LinkedList, so you shouldn't constrain the type to be that.
This contrasts with say, Collection and List, which are different things (List implies sorting, Collection does not).
Why should the latter with List be used instead of ArrayList?
It's a good practice : Program to interface rather than implementation
By replacing ArrayList with List, you can change List implementation in future as below depending on your business use case.
List<Object> list = new LinkedList<Object>();
/* Doubly-linked list implementation of the List and Deque interfaces.
Implements all optional list operations, and permits all elements (including null).*/
OR
List<Object> list = new CopyOnWriteArrayList<Object>();
/* A thread-safe variant of ArrayList in which all mutative operations
(add, set, and so on) are implemented by making a fresh copy of the underlying array.*/
OR
List<Object> list = new Stack<Object>();
/* The Stack class represents a last-in-first-out (LIFO) stack of objects.*/
OR
some other List specific implementation.
List interface defines contract and specific implementation of List can be changed. In this way, interface and implementation are loosely coupled.
Related SE question:
What does it mean to "program to an interface"?
Even for local variables, using the interface over the concrete class helps. You may end up calling a method that is outside the interface and then it is difficult to change the implementation of the List if necessary.
Also, it is best to use the least specific class or interface in a declaration. If element order does not matter, use a Collection instead of a List. That gives your code the maximum flexibility.
Properties of your classes/interfaces should be exposed through interfaces because it gives your classes a contract of behavior to use, regardless of the implementation.
However...
In local variable declarations, it makes little sense to do this:
public void someMethod() {
List theList = new ArrayList();
//do stuff with the list
}
If its a local variable, just use the type. It is still implicitly upcastable to its appropriate interface, and your methods should hopefully accept the interface types for its arguments, but for local variables, it makes total sense to use the implementation type as a container, just in case you do need the implementation-specific functionality.
In general for your line of code it does not make sense to bother with interfaces. But, if we are talking about APIs there is a really good reason. I got small class
class Counter {
static int sizeOf(List<?> items) {
return items.size();
}
}
In this case is usage of interface required. Because I want to count size of every possible implementation including my own custom. class MyList extends AbstractList<String>....
Interface is exposed to the end user. One class can implement multiple interface. User who have expose to specific interface have access to some specific behavior which are defined in that particular interface.
One interface also have multiple implementation. Based on the scenario system will work with different scenario (Implementation of the interface).
let me know if you need more explanation.
The interface often has better representation in the debugger view than the concrete class.
This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 7 years ago.
I am using a method that returns type List<>, and I am then able to call methods on that List :
List<Artist> artists = artistsPager.artists.items;
artists.add(new Artist());
To be clear artistsPager.artists.items is returning type List<Artist>.
Since List is only an interface, how is the compiler letting me use this artists object, doesn't a List<> always need an implementation, like ArrayList?
For example, the compiler won't let me do the following, because "List is abstract; cannot be instantiated":
List<Integer> list = new List<Integer>();
How is artistsPager.artists.items any different than new List<Integer>()?
For those curious, this come from the Java Web API wrapper for Android. All help is greatly appreciated.
I do not believe this is a duplicate of this question because even though the answers are the same, the question that begets them is different. The other question is asking the difference between type List and ArrayList, whereas my question was wondering why the compiler was not complaining when the implementation of List was hidden.
I am fine with having this marked as a duplicate to direct future users to that question, but I do not think it should be closed as the answers here I think would be immensely helpful to other users.
How is artistsPager.artists.items any different than new List<Integer>()?
artistsPager.artists.items is a field of type List<>. Somewhere in the code, it must have been instantiated with a concrete implementation like ArrayList.
new List<Integer>() is a constructor call, which is invalid because List is an interface.
doesn't a List<> always need an implementation, like ArrayList<>?
Yes, you need an implementation in order to create an instance. However, the compiler knows two things:
It knows that you have already created some instance, and assigned it to items, and
It knows that whatever you have assigned to items, implements List<> interface
Knowing these two things is enough for the compiler to let you call add on a variable declared as an interface type. In this way your code does not need to care what implementation you get - an ArrayList<>, a LinkedList<>, or some custom implementation you developed: your code will work with all of them.
Note that the practice of referring to objects through their interface type is desirable. It is called programming to interface. It lets you hide implementation details, and swap objects for different implementations later on.
This means that a concrete list was created somewhere (for example, an ArrayList).
You only know that the list that is created is implementing methods from the List interface, allowing you to use these methods.
Take this example hiding the concrete LinkedList from the user:
public static List<Integer> makeListOfInts(){
return new LinkedList<Integer>(){
{
add(1);
add(2);
}
}
}
I can be easily replaced with an ArrayList:
public static List<Integer> makeListOfInts(){
return new ArrayList<Integer>(){
{
add(1);
add(2);
}
}
}
And all the function's user knows is that a List is returned, but it does not know the concrete type of the list. It may only use functions from the List interface, and not from the specific implementation that was selected.
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.
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.
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.