How to declare an ArrayList? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why should the interface for a Java class be prefered?
I m relatively new to java and i have just started on collections framework.
While on ArrayList I encountered on two ways people declare it. For example to declare an ArrayList of Strings :
List<String> l = new ArrayList<String>();
or
ArrayList<String> al = new ArrayList<String>();
Which one of these two should I use and what is the difference between them?
I know that the actual methods called are decided at runtime and hence the methods called will all be of ArrayList class only but still the first declaration restricts the methods that can be called.
The first way is, I have heard, called "coding to an interface". Any method will be invoked using the variable l and hence only methods provided by List interface can be called, whereas, in the second example we can call all the methods provided not only by List but by the Object class also (like finalize(), wait() etc). So why even in the first place people even use the first declaration??

You should always use least specific interface possible. This makes it easier to substitute alternate implementations if a more appropriate one exists. For example, methods that take List don't care if the list is a linked list or an array list. You can choose whichever one is more appropriate.

I personally recommend using List<String> l = new ArrayList<String>();
The reason is you typically don't need to know you're working with an ArrayList. You just need something that operates like a list. There's a lot of behaviors on ArrayList that people don't need access to. Consider "EnsureCapacity". They don't need that - they just need the List operations. As a general rule, you want to limit the exposure of data and functionality on a "need to know" basis, and users of your list do not need to know (by default) what implementation you used.
Obviously, if they do need to know that you're using an ArrayList instead of a LinkedList, for instance, then you would want to use an ArrayList reference instead of a List reference. For most purposes though, that's not necessary.

Related

Interface with concrete classes [duplicate]

This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
If we consider two implementations below, what's the actual use of the first one?
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
From what I have read in the posts, the first implementation helps in avoiding breaking change like we can change the implementation again as
a=new TreeList<String>();
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
Different implementations of interface List have different performance characteristics for different operations. Which implementation of List you should choose is not arbitrary - different implementations are more efficient for different purposes.
For example, inserting an element somewhere in the middle is expensive on an ArrayList, but cheap on a LinkedList, because of the way the implementations work. Likewise, accessing an element by index is cheap on an ArrayList, but expensive on a LinkedList.
It may happen that when you started writing your program, you used an ArrayList without thinking about it too much, but later you discover that a LinkedList would be more efficient.
When you've programmed against the interface List instead of a specific implementation, it's very easy to change from ArrayList to LinkedList - to the rest of the program, it still looks like a List, so you'd only have to change one line.
Lets say that you have decided to develop a more efficient List implementation of your own. Perhaps one that has better memory management internally, or may be a faster set method (insertion) implementation. You can just implement the List interface and rest of your code will continue to work without any change, except this one line. You can also extend ArrayList and write your own code.
//Old code
List<String> a = new ArrayList<String>();
a.set(0, "Test");
//New code
List<String> a = new MyCustomisedList<String>();
//Same code, but your optimized set logic. May be faster...
a.set(0, "Test");
A TreeList doesn't exist, so lets use a PersistentList as an example.
Lets say you have an #Entity that you want to save to a database:
public class MyMagicEntity {
#OneToMany
List<MyChildEntity> children;
public void setChildren(final List<MyChildEntity> children) {
this.children = children;
}
}
Now, when you create MyMagicEntity then you would do something like
final MyMagicEntity mme = new MyMagicEntity();
final List<MyChildEntity> children = new ArrayList<>();
children.add(new MyChildEntity("one"));
children.add(new MyChildEntity("two"));
children.add(new MyChildEntity("three"));
mme.setChildren(children);
//save to DB
So you created an ArrayList that you passed into your MyMagicEntity, which assigns it to the List - it doesn't care that the underlying implementation is as long as it's a List.
Now, later you do:
final MyMagicEntity mme = //load from DB
final List<Children> children = mme.getChildren();
So, what is children? Well, if we are using JPA and Hibernate it is actually a PersistentList, not an ArrayList.
As we access the members of children, Hibernate will go and pull them from the database. This List is still a List - your program doesn't have to know any of this.
Could you do this without using the List interface? No! Because:
you cannot create a PersistentList
Hibernate cannot create an ArrayList
Whilst this is an extreme example, where the underlying behaviour of the List is completely different, this applies in all sorts of other situations.
For example:
ArrayList and LinkedList have different performance characteristics, you may want to switch
Guava has an ImmutableList which you may want to use
Collections.unmodifyableList also implements List, which you may want to use
You could conceivably have a List backed by a file
The basic idea is that List defines what any list must be able to do, but not how it is done.
Here List is an Interface which contains all common operation method can perform with an List.
List Interface is parent for ArrayList , LinkedList and many more class. So, It can hold all these type of Object reference.
All these List method have different (or own type) Implementation with different class. So, whatever method you use will automatically apply according to override method definition of Object belong to the class.
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
Now , In Your case you can declare both ways is alright. but suppose a Scenario like this.
You are calling some services and you know that return any List Type (not specific) of Object. It may be a LinkedList or ArrayList or any other type of List.
at that time whatever response you get You can easily hold those responses in a List Type of Reference Variable.
and after gathering the result you can differentiate further of Object Type.

Why to keep interface as reference? [duplicate]

This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 9 years ago.
I have observed in Java programming language, we code like following:
List mylist = new ArrayList();
Why we should not use following instead of above one?
ArrayList mylist = new ArrayList();
While the second option is viable, the first is preferable in most cases. Typically you want to code to interfaces to make your code less coupled and more cohesive. This is a type of data abstraction, where the user of mylist (I would suggest myList), does not care of the actual implementation of it, only that it is a list.
We may want to change the underlying data structure at some point, and by keeping references, we only need to change the declaration.
The separation of Abstract Data Type and specific implementation is one the key aspects of object oriented programming.
See Interface Instansiation
Just to avoid tight coupling. You should in theory never tie yourself to implementation details, because they might change, opposite to interface contract, which is supposed to be stable. Also, it really simplifies testing.
You could view interface as an overall contract all implementing classes must obey. Instead, implementation-specific details may vary, like how data is represented internally, accessed, etc. - the information that you'd never want to rely on.
If you use ArrayList, you are saying it has to be an ArrayList, not any other kind of List, and to replace it you would have to change every reference to the type. If you use List you are making it clear there is nothing special about the List and it is used as a plain list. It can be changed to another List by changing just one line.

Assigning ArrayList to List [duplicate]

This question already has an answer here:
What is the difference between List and ArrayList? [duplicate]
(1 answer)
Closed 10 years ago.
Is there any Difference between two lines in the following
ArrayList<String> arrName = new ArrayList<String>();
List<String> arrName = new ArrayList<String>();
Thanks for Reply
Almost always the second one is preferred over the first one. The second 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.
Try to hide specific implementation behind an Interface whenever possible. see this
The second approach is usually the preferred one as it hides the implementation behind an interface.
This means that later on, if the requirements will change and will require another implementation of the List interface, you can change just one line of code and everything else will still work because you were coding to an interface not to a class.
There is not much difference per se, but List shall be used whenever possible as it is an interface and you may see in standard libraries' methods parameters are generally List<K>, so that any specific implementation can be passed, like ArrayList or LinkedList.
Second is example of Program to Interface and its the preferred way.
For details What does it mean to "program to an interface"?
The latter is usually recommended as long as you only need a List interface later on. That's called "programming to interface, not implementation".
As for the detailed difference between them, I have answered in another question on stackoverflow: The difference between "C c = new C()" and "A c = new C()" when C is a subclass of A in Java

Polymorphism: Why use "List list = new ArrayList" instead of "ArrayList list = new ArrayList"? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why should the interface for a Java class be prefered?
When should I use
List<Object> list = new ArrayList<Object>();
ArrayList inherits from List, so if some features in ArrayList aren't in List, then I will have lost some of the features of ArrayList, right? And the compiler will notice an error when trying to access these methods?
The main reason you'd do this is to decouple your code from a specific implementation of the interface. When you write your code like this:
List list = new ArrayList();
the rest of your code only knows that data is of type List, which is preferable because it allows you to switch between different implementations of the List interface with ease.
For instance, say you were writing a fairly large 3rd party library, and say that you decided to implement the core of your library with a LinkedList. If your library relies heavily on accessing elements in these lists, then eventually you'll find that you've made a poor design decision; you'll realize that you should have used an ArrayList (which gives O(1) access time) instead of a LinkedList (which gives O(n) access time). Assuming you have been programming to an interface, making such a change is easy. You would simply change the instance of List from,
List list = new LinkedList();
to
List list = new ArrayList();
and you know that this will work because you have written your code to follow the contract provided by the List interface.
On the other hand, if you had implemented the core of your library using LinkedList list = new LinkedList(), making such a change wouldn't be as easy, as there is no guarantee that the rest of your code doesn't make use of methods specific to the LinkedList class.
All in all, the choice is simply a matter of design... but this kind of design is very important (especially when working on large projects), as it will allow you to make implementation-specific changes later without breaking existing code.
This is called programming to interface. This will be helpful in case if you wish to move to some other implementation of List in the future. If you want some methods in ArrayList then you would need to program to the implementation that is ArrayList a = new ArrayList().
This is also helpful when exposing a public interface. If you have a method like this,
public ArrayList getList();
Then you decide to change it to,
public LinkedList getList();
Anyone who was doing ArrayList list = yourClass.getList() will need to change their code. On the other hand, if you do,
public List getList();
Changing the implementation doesn't change anything for the users of your API.
I think #tsatiz's answer is mostly right (programming to an interface rather than an implementation). However, by programming to the interface you won't lose any functionality. Let me explain.
If you declare your variable as a List<type> list = new ArrayList<type> you do not actually lose any functionality of the ArrayList. All you need to do is to cast your list down to an ArrayList. Here's an example:
List<String> list = new ArrayList<String>();
((ArrayList<String>) list).ensureCapacity(19);
Ultimately I think tsatiz is correct as once you cast to an ArrayList you're no longer coding to an interface. However, it's still a good practice to initially code to an interface and, if it later becomes necessary, code to an implementation if you must.
Hope that helps!
This enables you to write something like:
void doSomething() {
List<String>list = new ArrayList<String>();
//do something
}
Later on, you might want to change it to:
void doSomething() {
List<String>list = new LinkedList<String>();
//do something
}
without having to change the rest of the method.
However, if you want to use a CopyOnWriteArrayList for example, you would need to declare it as such, and not as a List if you wanted to use its extra methods (addIfAbsent for example):
void doSomething() {
CopyOnWriteArrayList<String>list = new CopyOnWriteArrayList<String>();
//do something, for example:
list.addIfAbsent("abc");
}
I guess the core of your question is why to program to an interface, not to an implementation
Simply because an interface gives you more abstraction, and makes the code
more flexible and resilient to changes, 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 its client.
I use that construction whenever I don't want to add complexity to the problem. It's just a list, no need to say what kind of List it is, as it doesn't matter to the problem. I often use Collection for most of my solutions, as, in the end, most of the times, for the rest of the software, what really matters is the content it holds, and I don't want to add new objects to the Collection.
Futhermore, you use that construction when you think that you may want to change the implemenation of list you are using. Let's say you were using the construction with an ArrayList, and your problem wasn't thread safe. Now, you want to make it thread safe, and for part of your solution, you change to use a Vector, for example. As for the other uses of that list won't matter if it's a AraryList or a Vector, just a List, no new modifications will be needed.
In general you want to program against an interface. This allows you to exchange the implementation at any time.
This is very useful especially when you get passed an implementation you don't know.
However, there are certain situations where you prefer to use the concrete implementation.
For example when serialize in GWT.

List versus ArrayList as reference type?

Ok so I know that Set, List and Map are interfaces but what makes the first line of code any better than the second line?
List myArr = new ArrayList();
ArrayList myArr = new ArrayList();
If you use the first form, you are saying all you are ever going to use is the functionality of the List interface - nothing else, especially nothing extra added by any implementation of it. This means you can easily change the implementation used (e.g. just substitute LinkedList for ArrayList in the instantiation), and not worry about it breaking the rest of the code because you might have used something specific to ArrayList.
A useful general principle about types in programming (sometime referred to as the robustness principle) is as follows:
Be liberal about what you accept
Be conservative about what you emit
List is more liberal than ArrayList, since List can be any kind of List implementation e.g. an ArrayList, a LinkedList or FrancosSpecialList. Hence it is a good idea to be liberal and accept any kind of list since you may want to change the implementation later.
The main reason to use ArrayList explicitly as a type (your second case) is if you need to use methods that are specific to ArrayList that are not available through the List interface. In this case a generic List won't work (unless you want to do lots of ugly and confusing casting), so you might as well be explicit and use an ArrayList directly. This has the added bonus of hinting to a reader that specific features of ArrayList are needed.
As you can see from the source of ArrayList here, most of the methods implemented are annotated as #override because all of them that are defined through List interface so, if you are gonna use just basic functionalities (that is what you are gonna do most of the time) the difference won't be any practical one.
The difference will come if someday you will think that the features of the ArrayList are not suitable anymore for your kind of problem and you will need something different (a LinkedList for example). If you declared everything as List but instantiated as ArrayList you will easily switch to new implementation by changing the instantiations to new LinkedList() while in other case you will have to change also all variable declarations.
Using List list = new ArrayList() is more OOP style since you declare that you don't care about the specific implementation of the list, and that you want to discard the static information about the type since you will rely on the interface provided by this kind of collection abstracting from its implementation.

Categories

Resources