List is a type of collection that offers the following basic features:
-
Elements are ordered in a sequence, one after the other, similar to what we saw with arrays.
-
All elements have a position/index associated with them. This means you can
get
/insert
elements at specific positions in the list. It also means you can search for theindexOf
a particular element. -
Elements can be duplicated. This means, the same object in the list can appear more than once.
For example, we could have the following list of elements:
As mentioned before, List
is an interface that defines the contract of the operations provided by different types of list implementations. In this section, we’ll make use of the ArrayList
class as the concrete implementation to show some examples.
An ArrayList
, as the name suggests, stores the elements inside of an array. However, this class will automatically manage the cases where the array size limit is reached and will resize the array automatically for us.
Some of the methods that we’ll introduce in this section come directly from the Collection interface, which means they are available not only for List but also for other types of collections (for example, also available to Set ).
|
Creating an ArrayList
Let’s create an ArrayList
to hold the example list of strings in the image above:
In the example code run the JavaBasicArrayListApp
|
List<String> sentence = new ArrayList<>();
System.out.println("Initial size of the list: " + sentence.size());
Output:
Initial size of the list: 0
In this case we’re creating a variable called sentence
that represents our list of strings. At this stage, the sentence
list of strings is empty, it has just been created hence it has no elements.
We can check the number of elements inside any Collection using the size() method as with the example above.
|
Note that it is good practice to use the interface type instead of the implementation type for the variable, to reduce the dependency your code will have to behaviors that might be implementation-specific. For example, above we’re using List<String> sentence
instead of ArrayList<String> sentence
.
Adding elements
To insert elements into a List
we can make use of the add
methods. To recreate our list in the image above, we could do:
List<String> sentence = new ArrayList<>();
sentence.add("This");
sentence.add("is");
sentence.add("a");
sentence.add("sentence");
Using the add(E element)
method causes the elements to be added automatically at the end of the list.
The add(E element)
method can be used with any Collection
. However, List
offers an overloaded add(int index, E object)
method where we can specify the position where the element should be inserted. For example, sentence.add(0, "Test")
would add the "Test"
string at the beginning of the list.
Retrieving an element by index
One of the features of a List
is that we have a method get(int index)
that allows us to retrieve the element in a specific position of our list. Similar to arrays, this index is zero-based and is the equivalent of doing array[index]
, for example, if we want to get the second word of our sentence
:
String secondWord = sentence.get(1);
System.out.println("Second word: " + secondWord);
Output:
Second word: is
Iterating over elements
To iterate over elements, we can use similar approaches to what we did with arrays, we can use a standard for
loop or an enhanced-for
loop:
For example, to print out the words in our sentence list of strings, we can do either of these:
for (int i = 0; i < sentence.size(); i++) {
String word = sentence.get(i);
System.out.println(word);
}
or
for (String word : sentence) {
System.out.println(word);
}
Output:
This
is
a
sentence
As discussed before, since Java 8 there are more ways of doing this. These will be covered in a later chapter after we introduce the concept of lambdas. |
Checking if an element exists
Another operation that we can perform with List
and Collection
in general is to check if an object already exists inside our collection of elements. The contains(E element)
method will return true
if the element already exists in our collection or false
otherwise.
For example:
System.out.println("Sentence contains a: " + sentence.contains("a"));
System.out.println("Sentence contains b: " + sentence.contains("b"));
Output:
Sentence contains a: true
Sentence contains b: false
The contains and indexOf operations rely on the equals method of the objects in the list.
|
Checking where an element is
In particular for List
, not only we can check if an element exists, we can also check in what index it is placed. The indexOf(E element)
method will return an integer that represents the position where the element
is stored in the list, or a negative value (-1
) if it doesn’t exist in the list.
For example:
System.out.println("Index of a: " + sentence.indexOf("a"));
System.out.println("Index of b: " + sentence.indexOf("b"));
Output:
Index of a: 2
Index of b: -1
Common operations and performance
The examples above cover some of the most common operations on List
and Collection
in general. However, one of the most important things to understand when working with data structures are the performance characteristics of each of them.
Different data structures offer features/characteristics that are meant for use in different scenarios. In the next sections, we’ll go into details about ArrayList
, HashSet
and HashMap
and explain how they work behind the scenes and what performance can we expect out of each of these.
Understanding what data structure to use given a particular problem/scenario is an important task when developing software.