List vs Array vs ArrayList
What's the different between ArrayList and List?
Can someone please explain the difference between List and ArrayList like I'm five?
Type List vs type ArrayList in Java - Stack Overflow
Videos
Coming from Python, this whole Java thing is incredibly confusing. The thing is, they don't seem to mix and uses different methods such as .size() vs .length(). All of them also seem to be doing the same thing: having a group of something.
I really need a comparison of the three, and how to declare, manipulate, and access, etc them.
What exactly is the difference between
List<String> inputs = new ArrayList<>()
and
ArrayList<String> inputs = new ArrayList<>()
I've read some stuff about it but I'm a bit confused and I don't feel like I understood completely. Can someone explain the difference with some examples? Thank you!
Almost always List is preferred over ArrayList because, for instance, List can be translated into a LinkedList without affecting the rest of the codebase.
If one used ArrayList instead of List, it's hard to change the ArrayList implementation into a LinkedList one because ArrayList specific methods have been used in the codebase that would also require restructuring.
You can read about the List implementations here.
You may start with an ArrayList, but soon after discover that another implementation is the more appropriate choice.
I am wondering if anyone uses (2)?
Yes. But rarely for a sound reason (IMO).
And people get burned because they used ArrayList when they should have used List:
Utility methods like
Collections.singletonList(...)orArrays.asList(...)don't return anArrayList.Methods in the
ListAPI don't guarantee to return a list of the same type.
For example of someone getting burned, in https://stackoverflow.com/a/1481123/139985 the poster had problems with "slicing" because ArrayList.sublist(...) doesn't return an ArrayList ... and he had designed his code to use ArrayList as the type of all of his list variables. He ended up "solving" the problem by copying the sublist into a new ArrayList.
The argument that you need to know how the List behaves is largely addressed by using the RandomAccess marker interface. Yes, it is a bit clunky, but the alternative is worse.
Also, how often does the situation actually require using (1) over (2) (i.e. where (2) wouldn't suffice..aside 'coding to interfaces' and best practices etc.)
The "how often" part of the question is objectively unanswerable.
(and can I please get an example)
Occasionally, the application may require that you use methods in the ArrayList API that are not in the List API. For example, ensureCapacity(int), trimToSize() or removeRange(int, int). (And the last one will only arise if you have created a subtype of ArrayList that declares the method to be public.)
That is the only sound reason for coding to the class rather than the interface, IMO.
(It is theoretically possible that you will get a slight improvement in performance ... under certain circumstances ... on some platforms ... but unless you really need that last 0.05%, it is not worth doing this. This is not a sound reason, IMO.)
You canโt write efficient code if you donโt know whether random access is efficient or not.
That is a valid point. However, Java provides better ways to deal with that; e.g.
public <T extends List & RandomAccess> void test(T list) {
// do stuff
}
If you call that with a list that does not implement RandomAccess you will get a compilation error.
You could also test dynamically ... using instanceof ... if static typing is too awkward. And you could even write your code to use different algorithms (dynamically) depending on whether or not a list supported random access.
Note that ArrayList is not the only list class that implements RandomAccess. Others include CopyOnWriteList, Stack and Vector.
I've seen people make the same argument about Serializable (because List doesn't implement it) ... but the approach above solves this problem too. (To the extent that it is solvable at all using runtime types. An ArrayList will fail serialization if any element is not serializable.)
Finally, I'm not going to say "because its is good style". That "reason" is both a circular argument ("Why is it 'good style'?") and an appeal to an unstated (and probably non-existent!) higher authority ("Who says it is 'good style'?").
(I do think it is good style to program to the interface, but I'm not going to give that as a reason. It is better for you to understand the real reasons and come to the (IMO) correct conclusions for yourself. The correct conclusion may not always be the same ... depending on the context.)
List is in interface while ArrayList is a class.
See ArrayList, and List.
E.g, you can't use this setup:
List<String> list = new List<String>();... Because it's an interface.
However, this works:
ArrayList<String> arrayList = new ArrayList<String>();
Also... You can do as duffymo says below, which is more or less the same as implementing the List interface (making your own list implementation).
Consider a line like the following:
List<String> names = new ArrayList<String>();
If you're new to object-oriented architectures, you might have expected instead to see something like ArrayList<String> names = new ArrayList<String>();. After all, you've just said that it's a new ArrayList, so shouldn't you store it in a variable of type ArrayList?
Well, you certainly can do that. However, List is an interface--like a template of sorts--that ArrayList is said to inherit. It is a contract that says "anytime you use a List implementation, you can expect these methods to be available". In the case of List, the methods are things like add, get, etc.
But ArrayList is only one implementation of List. There are others, such as LinkedList. The two have the same interface, and can be used the same way, but work very differently behind the scenes. Where ArrayList is "random" access, meaning that it directly finds a specific element of the array without iterating through the whole list, LinkedList does have to start from the first element and go one-by-one until it gets to the element you need.
The thing is, while you do need to specify which you want when you create the object, you generally only need to communicate no more than the fact that it is a List, so you simply say that's what it is. List communicates that you have a collection that is intended to be in the order that it is given. If you don't need to communicate that much, you might consider passing it around as a Collection, which is another interface (a super-interface of List). Or, if all you need to communicate is that you can iterate over it, you might even call it an Iterable.