Sitemap

List Interface in Java

8 min readJan 13, 2025

--

In this tutorial, We’ll be exploring lists in Java.

What is a List in Java?
The List interface in Java, part of the java.util package, extends the Collection interface. It is designed to store ordered collections of elements, allowing you to manage data sequentially.

What are the advantages of using a List?
1. It maintains the order of elements as they are added.
2. Allows insertion of duplicate elements.
3. Can include null values, depending on the implementation.
4. ListIterator, helps to traverse through the list in both directions.

Implement a List in Java?
List<Obj>list = new ArrayList<>();
Here Obj is the type of Object and It can be any class or Object of your choice.

Types of List in Java
1. ArrayList:
It is a resizeable array implementation of the List interface, which allows fast random access but slower insertion or deletion compared to LinkedList. It is suitable for applications that require frequent access to elements by index.
2. LinkedList: It is a doubly-linked list implementation of the List interface, allowing faster insertion and deletion than ArrayList slower random access. It is ideal for applications that require frequent insertion and deletion of elements.
3. Vector: A synchronized, resizable array implementation of the List interface. It is thread-safe due to the synchronization overhead. It is ideal for applications that require thread-safe operations on lists.
4. Stack: A subclass that implements a last-in, first-out (LIFO) stack, which provides operations like push, pop and peek making it useful for stack operations.

Operations available in List:
The List of operations available in List are:
1. size()
2. isEmpty()
3. contains(Object o)
4. iterator()
5. toArray()
6. add(E e)
7. remove(Object o)
8. containsAll(Collection<?> c)
9. add(Collection<? extends E> c)
10. add(int index, Collection<? extends E> c)
11. removeAll(Collection<?> c)
12. retainAll(Collection<?> c)
13. sort(Comparator<? super E> c)
14. equals(Object o)
15. clear()
16. hashCode()
17. E get(int index)
18. E set(int index, E element)
19. void add(int index, E element)
20. int indexOf(Object o)
21. E remove(int index)
22. int lastIndexOf(Object o)
23. ListIterator<E> listIterator()
24. ListIterator<E> listIterator(int index)
25. List<E> subList(int fromIndex, int toIndex)
26. <E> List<E> of(E e1, E e2)
27. static <E> List<E> copyOf(Collection<? extends E> coll)
and many more which can be seen in the package java.util;

Let us Dive into implementing the code for all of the above.

Get Nikhil Sharma’s stories in your inbox

Join Medium for free to get updates from this writer.

Problem statement 1: write a code showcasing to create a LinkedList
Solution (Way 1): Versions before Java 10 had to add all the data sequences by increasing the code's length.

import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<Integer> listOfIntegers = new ArrayList<>();
listOfIntegers.add(1);
listOfIntegers.add(2);
listOfIntegers.add(3);
listOfIntegers.add(4);
listOfIntegers.add(5);
listOfIntegers.forEach(System.out::println);
}
}

Solution (Way 2): Versions from Java 10 had received an of method in the List interface which reduced the code significantly.

import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<Integer> listOfIntegers = new ArrayList<>(List.of(1,2,3,4,5,6,7));
listOfIntegers.forEach(System.out::println);
}
}

Problem statement 2: write a code in Java to show the use of List and perform several operations on it.
Solution: Please follow the comments to understand each line of code

package com.journaldev.collections.linkedlist.example1;

import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<Integer> listOfIntegers = new ArrayList<>(List.of(1,2,3,4,4,5,6,7));
System.out.println("Initial list: " + listOfIntegers);

//To add data to the list
listOfIntegers.add(8);
System.out.println("After adding 8: " + listOfIntegers);

// To remove data from the list using index
listOfIntegers.remove(0);
System.out.println("After removing element at index 0: " + listOfIntegers);

// To remove data based on value
listOfIntegers.remove(Integer.valueOf(8));
System.out.println("After removing value 8: " + listOfIntegers);

// To get data from the list
System.out.println("Element at index 0: " + listOfIntegers.get(0));

// To get the size of the list
System.out.println("Size of list: " + listOfIntegers.size());

// To check if the list is empty
System.out.println("Is list empty: " + listOfIntegers.isEmpty());

// To check if the list contains a particular value
System.out.println("Does list contain 2: " + listOfIntegers.contains(2));

// To add a data in the index
listOfIntegers.add(0, 0);
System.out.println("After adding 0 at index 0: " + listOfIntegers);

// To get the first element of the list
System.out.println("First element: " + listOfIntegers.getFirst());

// To get the last element of the list
System.out.println("Last element: " + listOfIntegers.getLast());

// To get the index of a particular element
System.out.println("Index of 2: " + listOfIntegers.indexOf(2));

// To get the index of a particular element
System.out.println("Index of 4: " + listOfIntegers.indexOf(4));

// To get the last index of a particular element
System.out.println("Last index of 2: " + listOfIntegers.lastIndexOf(2));

// To get the sublist from the list
System.out.println("Sublist from index 0 to 2: " + listOfIntegers.subList(0, 2));

// To replace the element at a particular index
listOfIntegers.set(0, 1);
System.out.println("After replacing element at index 0 with 1: " + listOfIntegers);

System.out.print("Final list elements: " + listOfIntegers);
}
}

Output is:

Initial list: [1, 2, 3, 4, 4, 5, 6, 7]
After adding 8: [1, 2, 3, 4, 4, 5, 6, 7, 8]
After removing element at index 0: [2, 3, 4, 4, 5, 6, 7, 8]
After removing value 8: [2, 3, 4, 4, 5, 6, 7]
Element at index 0: 2
Size of list: 7
Is list empty: false
Does list contain 2: true
After adding 0 at index 0: [0, 2, 3, 4, 4, 5, 6, 7]
First element: 0
Last element: 7
Index of 2: 1
Index of 4: 3
Last index of 2: 1
Sublist from index 0 to 2: [0, 2]
After replacing element at index 0 with 1: [1, 2, 3, 4, 4, 5, 6, 7]
Final list elements: 12344567

Problem statement 3: write a code in Java to show the difference in operation speeds while reading or insertion and deletion in ArrayList, Vectors and LinkedList.
Solution: Please follow the comments to understand each line of code

package com.journaldev.collections.linkedlist.example1;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

public class Main {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
LinkedList<Integer> linkedList = new LinkedList<>();
Vector<Integer> vector = new Vector<>();

// Test insertion at end
long startTime = System.nanoTime();
for(int i = 0; i < 100000; i++) {
arrayList.add(i);
}
long endTime = System.nanoTime();
System.out.println("Time taken for ArrayList insertion at end: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 100000; i++) {
linkedList.add(i);
}
endTime = System.nanoTime();
System.out.println("Time taken for LinkedList insertion at end: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 100000; i++) {
vector.add(i);
}
endTime = System.nanoTime();
System.out.println("Time taken for Vector insertion at end: " + (endTime - startTime) + " ns");

// Test insertion at beginning
startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
arrayList.add(0, i);
}
endTime = System.nanoTime();
System.out.println("Time taken for ArrayList insertion at beginning: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
linkedList.addFirst(i);
}
endTime = System.nanoTime();
System.out.println("Time taken for LinkedList insertion at beginning: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
vector.add(0, i);
}
endTime = System.nanoTime();
System.out.println("Time taken for Vector insertion at beginning: " + (endTime - startTime) + " ns");

// Test random access
startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
arrayList.get(i);
}
endTime = System.nanoTime();
System.out.println("Time taken for ArrayList random access: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
linkedList.get(i);
}
endTime = System.nanoTime();
System.out.println("Time taken for LinkedList random access: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
vector.get(i);
}
endTime = System.nanoTime();
System.out.println("Time taken for Vector random access: " + (endTime - startTime) + " ns");

// Test deletion from beginning
startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
arrayList.remove(0);
}
endTime = System.nanoTime();
System.out.println("Time taken for ArrayList deletion from beginning: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
linkedList.removeFirst();
}
endTime = System.nanoTime();
System.out.println("Time taken for LinkedList deletion from beginning: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
for(int i = 0; i < 1000; i++) {
vector.remove(0);
}
endTime = System.nanoTime();
System.out.println("Time taken for Vector deletion from beginning: " + (endTime - startTime) + " ns");
}
}
Time taken for ArrayList insertion at end: 7714000 ns
Time taken for LinkedList insertion at end: 15606800 ns
Time taken for Vector insertion at end: 10998900 ns
Time taken for ArrayList insertion at beginning: 28226200 ns
Time taken for LinkedList insertion at beginning: 147900 ns
Time taken for Vector insertion at beginning: 26981300 ns
Time taken for ArrayList random access: 74400 ns
Time taken for LinkedList random access: 2685300 ns
Time taken for Vector random access: 45900 ns
Time taken for ArrayList deletion from beginning: 24694500 ns
Time taken for LinkedList deletion from beginning: 93200 ns
Time taken for Vector deletion from beginning: 18161300 ns

As it can be seen the difference between the different List Implementation are compared below.

Press enter or click to view image in full size
All the values are in ns
  1. ArrayList performs the best with the lowest time (7,714,000).
  2. LinkedList is the slowest (15,606,800), likely due to its need to traverse the list to find the end.
  3. Vector is in between (10,998,900), but still slower than ArrayList.
  4. LinkedList excels with the lowest time (147,900) due to its efficient handling of insertions at the beginning.
  5. ArrayList and Vector are significantly slower (28,226,200 and 26,981,300, respectively) because they need to shift all elements to accommodate the new element.
  6. ArrayList and Vector perform similarly well (74,400 and 45,900, respectively) due to their array-based structure, which allows fast random access.
  7. LinkedList is much slower (2,685,300) because it needs to traverse the list to access elements randomly.
  8. LinkedList is the fastest (93,200) due to its efficient handling of deletions at the beginning.
  9. ArrayList and Vector are slower (24,694,500 and 18,161,300, respectively) because they need to shift all elements after the deletion.
Press enter or click to view image in full size
Image showing the time complexity

Problem Statement 4: Write the program in Java to create a department class and show the use of an iterator
Solution:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class Department {
private String name;
private List<String> employees;

public Department(String name) {
this.name = name;
this.employees = new ArrayList<>();
}

public void addEmployee(String employee) {
employees.add(employee);
}

public Iterator<String> getEmployeeIterator() {
return employees.iterator();
}

public String getName() {
return name;
}
}

public class Main {
public static void main(String[] args) {
// Create department
Department dept = new Department("Engineering");

// Add employees
dept.addEmployee("John");
dept.addEmployee("Mary");
dept.addEmployee("Steve");

// Get iterator
Iterator<String> iterator = dept.getEmployeeIterator();

// Iterate through employees
System.out.println("Employees in " + dept.getName() + " department:");
while(iterator.hasNext()) {
String employee = iterator.next();
System.out.println(employee);
}

// Use iterator to remove an employee
iterator = dept.getEmployeeIterator();
while(iterator.hasNext()) {
String employee = iterator.next();
if(employee.equals("Mary")) {
iterator.remove();
}
}

// Print remaining employees
System.out.println("\nEmployees after removal:");
iterator = dept.getEmployeeIterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Employees in Engineering department:
John
Mary
Steve

Employees after removal:
John
Steve

--

--