-1

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?

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
Zephyr
  • 1,521
  • 3
  • 22
  • 42
  • 3
    Think "sorting". ArrayList will not sort on `add`. Other implementations might do so. So if the requirement changes to have items sorted, you'll just exchange the implementations and you're done. You changed behavior of client code without changing its implementation (except that one line where you pick the implementation). Of course: If you need to use a method that is specific to a specific implementation, you are bound to that implementation. – Fildor Jun 24 '16 at 07:05

4 Answers4

2

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.

Jesper
  • 202,709
  • 46
  • 318
  • 350
1

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.

Jens
  • 67,715
  • 15
  • 98
  • 113
Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
1

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");
Shankar
  • 2,625
  • 3
  • 25
  • 49
0

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.

Vikrant Kashyap
  • 6,398
  • 3
  • 32
  • 52