*
The moose likes Beginning Java and the fly likes Returning ArrayList Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Returning ArrayList "type incompatible" error" Watch "Returning ArrayList "type incompatible" error" New topic
Author

Returning ArrayList "type incompatible" error

Colm Dickson
Ranch Hand

Joined: Apr 04, 2009
Posts: 89
hi all,


I have the following method that is like the following:

public List<String> splitThis (String source)
{

ArrayList<String> al = new ArrayList<String>();

/*use scanner to read source and add to arraylist */
I loop through string source as add token below.

al.add(.....);

/* then I return out the list */
return al;

}

When I call this later on in the program I do so using the following method which will remove duplicate tokens:

private List<String> removeDuplicates(List<String> list)
I call this method as follows:

ArrayList<String> newList = new ArrayList<String>();
newList = 'class instance'.removeDuplicates(the passed list);

I get an incompatible type error. I know the return type is List<String> and I'm attempting to assign the value to an ArrayList<String>. I thought because an ArrayList implements List that it could be substituted for in place of the List<String>?

Of course it's fine when I assign the value to a List<String> reference instead or indeed change the return type of the method to be ArrayList<String> but why choose one over the other.....why have return List<> rather than ArrayList<>? Any comments on the nature of this error to aid my understanding will be very welcome.

Thanks,

Colm
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Colm Dickson wrote:I get an incompatible type error. I know the return type is List<String> and I'm attempting to assign the value to an ArrayList<String>. I thought because an ArrayList implements List that it could be substituted for in place of the List<String>?


Well, all ArrayList<String> objects are List<String>, so this is okay:
List<String> list = new ArrayList<String>();

However, not all List<String> Objects are ArrayList<String>s, so this can't safely assign a List<String> to an ArrayList<String> like you attempt to do. The List<String> could be a LinkedList<String>, or any of a number of other List<String> implementations. The compiler can't know what specific type the List<String> is going to be at runtime, so you get the error warning you that it isn't safe.

Remember, you can always safely assign up the inheritance tree (Class to ParentClass or Class to Inteface) but you can not safely assign down the inheritance tree (ParenClass to Class, or Interfase to Class) because the is a relationship is not guaranteed to be true.

Of course it's fine when I assign the value to a List<String> reference instead or indeed change the return type of the method to be ArrayList<String> but why choose one over the other.....why have return List<> rather than ArrayList<>?


Increased flexibility. If the interface gives you all the methods you need to call, then you should use it. That way, in the future you can change the splitThis method or the removeDuplicates method to use LinkedList<String>, or some other List<String> implementation, without affecting any other code. If you program to the List<String> interface then the actual type of List<String> the method uses becomes a non-important implementation detail of the method. The method can change which list is used all it wants in order to improve performance without affecting any other code. If you return an ArrayList<String>, then later find out that the application is more performant with a LinkedList<String> so you change it, then you break all the code that uses the List (and maybe all the code that uses that code... it can quickly become a huge change).


Steve
John de Michele
Rancher

Joined: Mar 09, 2009
Posts: 600
Colm:

The better choice would be to program against interfaces rather than implementations. For example, it may turn out that ArrayLists are horribly inefficient for what you are doing, and you want to use a LinkedList (or some other type of List) instead. If you program for an interface, you can change the implementation, and the rest of your program will work just fine (unless you use methods outside of the interface). If you program for implementations, and you have to make a change, then you are changing the class' API, which is a lot more work, especially if it is widely used.

To Illustrate (using pseudo code):

Programming against interfaces:


Programming against implementations:



Hope this helps.

John.
Colm Dickson
Ranch Hand

Joined: Apr 04, 2009
Posts: 89
Thanks to the both of you for your very helpful replies. That's much clearer now.

Colm.
 
Don't get me started about those stupid light bulbs.
 
subject: Returning ArrayList "type incompatible" error