This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 10 years ago.
What are the fundamental differences between the two objects? Is one more efficient? Does one have more methods?
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.
List is an interface; ArrayList is a class that implements the List interface.
Interfaces define the method signatures that are required, but say nothing about how they are implemented.
Classes that implement an interface promise to provide public implementations of methods with the identical signatures declared by the interface.
A List defines the interface that ArrayList uses, that allows it to implement methods that will allow all other classes that implement List to be used together or in a similar way. An ArrayList is always also a List, but an List isn't necessarily an ArrayList.
That is, ArrayList implements List (among a few other interfaces).
How to use List and ArrayList, or other implementation of List, is Polymorphism and Inheritance, and also the reason why for using languages such as Java.
In simplicity, Polymorphism is many forms while Inheritance is reuse.
There can be many kinds of concrete and ready to us List that is available to you, such as ArrayList, Vector, LinkedList and Stack. The decision to use which comes from you, and if you look at the List API, you would notice that all of these List implementations extend in one way or another from List.
According to the java docs, List is just an interface, and ArrayList is one of the classes that implement it. There is no inherent efficiency advantage to using ArralyList specifically instead of List-typed references to an ArrayList object.
However, when it comes to "efficiency", there can be a difference between different implementations of the List interface. For instance there can be a small efficiency difference between a LinkedList and an ArrayList, depending on how you're using them.
To quote the java docs on the ArrayList page,
The add operation runs in amortized constant time, that is, adding n elements requires O(n) time. All of the other operations run in linear time (roughly speaking). The constant factor is low compared to that for the LinkedList implementation.
In other words, the performance difference will probably be negligible, but you may see some advantage from using an ArrayList (as opposed to a LinkedList).
In case you're interested, ArrayList is implemented with an array that is resized from time to time (most likely whenever your collection doubles in size), which is quite different from the implementation of a LinkedList (see wikipedia for details).
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.
I just started with lists in Java and I'm confused with all this.
So basically we have ArrayList and LinkedList which can be defined like
LinkedList<String> s = new LinkedList<String>();
ArrayList<String> s = new ArrayList<String>();
But then we also have LinkedIntList which can be defined like for example:
class LinkedIntList {
private ListNode first;
private int size;
LinkedIntList () {
first=null;
size=0;
}
LinkedIntList(LinkedIntList l) {
first = l.getFirst();
size=l.size();
}
ListNode getFirst() {return first;}
int size() {return size;}
}
But this is my problem, why define LinkedIntList using a class? What is the difference comparing to LinkedLists where we just define like I stated.
I can't understand why a class is being used. If this is a 'new type' of array why using a class instead of declaring it normally?
Sorry if this sounds weird, but I'm a beginner and really need help at this.
Thank you!
A List in java, is an ordered collection. I suppose you are a beginner and confused with syntax. If you have java decompiler, you can see that LinkedList and ArrayList are also classes. Which means somewhere some good person has done the coding for you and provided you a class which is similar to your "LinkedIntList" and provided you out of the box.
You don't need to create a new class if java provides sufficient functionality for you.
But sometimes, the out of the box classes are not sufficient for our requirements. In that case we have to write our own implementation of classes, such as your class "LinkedIntList".
In this case, it seems you need size and one element hence you are creating it on your own.
LinkedList is a class defined in the java.util package, and it's already provided to you. It exploits a feature called Generics that allows you to provide the type of objects that will populate the list. You basically take it as a black box: in most cases, you don't care about LinkedList actual implementation, but only about its interface (that is, the methods it exposes to you).
The class LinkedIntList that you provided does not feature genericity, but is simply an implementation of a linked list where each item is a ListNode. I guess a ListNode contains an integer, otherwise the name LinkedIntList wouldn't make much sense.
Anyway, you could discard this implementation (although is good for learning) and simply declare
LinkedList<Integer> myLinkedList = new LinkedList<Integer>();
If you want to know more about generics, take a look at the java tutorials.
In your first example,
LinkedList<String> s = new LinkedList<String>();
it is the implementation of LinkedList defined in the stardard library, specifically from package java.util. See here: http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
You can look for its source code (1000+ lines long so I won't be posting it here) and compare it to your custom implementation of LinkedIntList.
Basically, Java already provided a default implementation of LinkedList(your first example) but everyone can still write(a class) and use their own implementation (your second example).
You're question isn't clear, but I'll try to explain to you what Lists are essentially.
Lists are a type of data structure, not only in Java but in a lot of programming language. Arrays are also a type of data structure. Data structures hold and manage data in an organized manner.
In Java, the main difference between a List and an Array is that a List has dynamic size, while an Array is of fixed size set when the Array was declared.
All Lists in Java are implementation of the List interface. If you don't know what interfaces are, I suggest you learn about it, but basically it means that all Lists can do the same basic set of things for you, but do them differently internally.
For example, ArrayList uses Arrays internally in order to expand or diminish the List as necessary (implement the dynamic size). LinkedList implements things differently internally, using nodes that are connected to each other. But they both offer the same basic sets of operations to the programmer, defined in the List interface (although one may offer additional methods the other doesn't).
Because the differ in their inner implementation, they might differ in performance for different operations. They have different algorithms to do things (for example, access a value in an index), with different 'speeds' (complexities) of doing so.
Most of the time ArrayList will be the right, simpler choice. This answer talks about when to prefer one over the other.
Hope this helps.
A java List is an ordered collection of objects, this java.util.List is actually an interface (contract) that defined what a list should behave like.
There are multiple variations (implementations) of List in the java standard JDK, while each is different from the other, they honor the contract defined in List (the ordered aspect for example). These implementations are concrete classes and you choose from in your code.
LinkedList and ArrayList you mentioned are JDK implementations of List.
The class you shared (LinkedIntList) is a custom made structure of objects, that neither part of the JDK, nor implement the java List interface.
LinkedList is a part of Java platform class in java.util package and it is widely used in different tasks. And it supports Generics .
LinkedIntList is a custom implementation just to show you how single-linked list coudl be implemented.
You can find more about different algorithms and structures and also complexity here
This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 10 years ago.
I use this two statements to ArrayList definition:
ArrayList<String> my = new ArrayList<>();
List<String> my2 = new ArrayList<>();
Which one should i use?
With your second definition, you could later replace ArrayList constructor for another type of List, like a LinkedList or a high-performant list, or any other kind of list that may exist in the future. In your first definition, you are tied to the ArrayList implementation forever. You cannot change it, because the rest of your code is trusting in this reference being explicitly an ArrayList.
By using an interface, on the contrary, your code relies on a contract, that of the interface, and not in a particular implementation (like ArrayList). That gives you the power of changing implementations without affecting its users. And change is something that we must foster and plan ahead, simply because we cannot prevent things from changing.
The latter. Program to an interface, not to an implementation.
Depends on what you need. It's generally advised to use interfaces (hence List) if possible, otherwise you're sticked to implementation class. Say, you use ArrayList as input parameter of some method. For some reason (e.g. performance) you decide at some point to switch from ArrayList to LinkedList. So you must change also the type of the input parameter. If you use interface (List), you're more free to switch implementation without the need of refactoring code.
I'm creating a library to be used by people but why should my method return a List instead of an ArrayList?
Because if the user knows the real type is an ArrayList he will use the accessor [] in a loop instead of iterator but if he doesn't know he will use an iterator.
Same question for LinkedList, if the return type is a List he won't be able to use the correct accessor.
Am I right?
Returning List will make it possible for users of your library to use anything that implements a List interface, while using an ArrayList will force them to use an ArrayList.
If in the future, you as a library creator decide to change your internal implementation, that changes will be hidden from the end user by the generic interface to your library.
Because the users of your library should never know that you are using an ArrayList internally.
For example, say you return an ArrayList and lots of people have started using your library. Now if you suddenly realize a LinkedList better suits your purpose, then you break compatibility for all the folks who are presently using your code.
This is why it is always better to code to an interface, not an implementation, and even more so when you are writing code that is specifically meant to be re-used. The interface (List in this case) acts as a contract between your code and the client's code. It tells them what your code does (interface), without telling them how it does it (by not exposing the implementation).
Return an interface (or failing that a super class?) if possible. This way the method can have a broader application if overriden. This might prevent some class-specific methods from being available on the returned object but there's nothing stopping a programmer taking the List data and copying it to whatever Collection they prefer to use.
List myList = new MyLibrary().getList();
ArrayList myArrayList = new ArrayList(myList);
LinkedList myLinkedList = new LinkedList(myList);
They don't have to use an iterator - the List interface supports get(int index) as a method. If you want flexibility to change the underlying container to anything supporting the list interface, use List. If specific ArrayList methods are required on what you return, use ArrayList.
Because your user can make from your List either ArrayList or LinkedList, you will leave him a choice. It's called Programming to Interface. You should give users of your API as much freedom as you can and this technique is one of the ways how to achieve it.
1. Its the concept of Interface Polymorphism.
2. Its better to have List<My_Obj> arr = new ArrayList<My_Obj>;
3. Suppose you want to use LinkedList instead of ArrayList as somepoint, then you donot
need to worry abt how to do it..
If You are returning List then it is possible for users of your library to use anything that implements a List interface. It may be Array List or Linked List.
I typically choose the most general type possible. In this case, you could return a type that's even more general than a List, such as Collection or Iterable.
By returning Iterable, the compiler will prevent the calling code from attempting to add elements to your list. This is much stronger than relying on Collections.unmodifiableList() to fail at runtime.
Using more general types also gives you more room to manoeuvre in the future. Perhaps your method's going to load your data from a streaming source rather than an in-memory source: then Iterable becomes a much more suitable than List.
We are learning about the Collection Interface and I was wondering if you all have any good advice for it's general use? What can you do with an Collection that you cannot do with an array? What can you do with an array that you cannot do with a Collection(besides allowing duplicates)?
The easy way to think of it is: Collections beat object arrays in basically every single way. Consider:
A collection can be mutable or immutable. A nonempty array must always be mutable.
A collection can allow or disallow null elements. An array must always permit null elements.
A collection can be thread-safe; even concurrent. An array is never safe to publish to multiple threads.
A list or set's equals, hashCode and toString methods do what users expect; on an array they are a common source of bugs.
A collection is type-safe; an array is not. Because arrays "fake" covariance, ArrayStoreException can result at runtime.
A collection can hold a non-reifiable type (e.g. List<Class<? extends E>> or List<Optional<T>>). An array will generate a warning for this.
A collection can have views (unmodifiable, subList...). No such luck for an array.
A collection has a full-fledged API; an array has only set-at-index, get-at-index, length and clone.
Type-use annotations like #Nullable are very confusing with arrays. I promise you can't guess what #A String #B [] #C [] means.
Because of all the reasons above, third-party utility libraries should not bother adding much additional support for arrays, focusing only on collections, so you also have a network effect.
Object arrays will never be first-class citizens in Java APIs.
A couple of the reasons above are covered -- but in much greater detail -- in Effective Java, Third Edition, Item 28, from page 126.
So, why would you ever use object arrays?
You're very tightly optimizing something
You have to interact with an API that uses them and you can't fix it
so convert to/from a List as close to that API as you can
Because varargs (but varargs is overused)
so ... same as previous
Obviously some collection implementations must be using them
I can't think of any other reasons, they suck bad
It's basically a question of the desired level of abstraction.
Most collections can be implemented in terms of arrays, but they provide many more methods on top of it for your convenience. Most collection implementations I know of for instance, can grow and shrink according to demand, or perform other "high-level" operations which basic arrays can't.
Suppose for instance that you're loading strings from a file. You don't know how many new-line characters the file contains, thus you don't know what size to use when allocating the array. Therefore an ArrayList is a better choice.
The details are in the sub interfaces of Collection, like Set, List, and Map. Each of those types has semantics. A Set typically cannot contain duplicates, and has no notion of order (although some implementations do), following the mathematical concept of a Set. A List is closest to an Array. A Map has specific behavior for push and get. You push an object by its key, and you retrieve with the same key.
There are even more details in the implementations of each collection type. For example, any of the hash based collections (e.g. HashSet, HasMap) are based on the hashcode() method that exists on any Java object.
You could simulate the semantics of any collection type based of an array, but you would have to write a lot of code to do it. For example, to back a Map with an array, you would need to write a method that puts any object entered into your Map into a specific bucket in the array. You would need to handle duplicates. For an array simulating a Set, you would need to write code to not allow duplicates.
The Collection interface is just a base interface for specialised collections -- I am not aware yet of a class that simply just implements Collection; instead classes implement specialized interfaces which extend Collection. These specialized interfaces and abstract classes provide functionality for working with sets (unique objects), growing arrays (e.g. ArrayList), key-value maps etc -- all of which you cannot do out of the box with an array.
However, iterating through an array and setting/reading items from an array remains one of the fastest methods of dealing with data in Java.
One advantage is the Iterator interface. That is all Collections implement an Iterator. An Iterator is an object that knows how to iterate over the given collection and present the programmer with a uniformed interface regardless of the underlying implementation. That is, a linked list is traversed differently from a binary tree, but the iterator hides these differences from the programmer making it easier for the programmer to use one or the other collection.
This also leads to the ability to use various implementations of Collections interchangeably if the client code targets the Collection interface iteself.