Home/Java/List in Java

List in Java

Learn about ordered collections that can contain duplicates

💡 Think of a List like a shopping list - items are kept in order, you can have duplicates (like buying 2 apples), and each item has a numbered position! You can add items at the end, insert them in the middle, or remove specific items by their position.

📝 What is a List?

A List is an ordered collection (sequence) that can contain duplicate elements. Each element has an index position starting from 0. Lists maintain insertion order and allow you to access elements by their position.

BasicArrayList.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.ArrayList;
import java.util.List;
public class BasicArrayList {
public static void main(String[] args) {
// Creating an ArrayList
List<String> fruits = new ArrayList<>();
// Adding elements
fruits.add("Apple"); // [Apple]
fruits.add("Banana"); // [Apple, Banana]
fruits.add("Orange"); // [Apple, Banana, Orange]
fruits.add("Apple"); // [Apple, Banana, Orange, Apple] - duplicates OK!
// Getting elements by index
System.out.println("First fruit: " + fruits.get(0)); // Apple
System.out.println("Third fruit: " + fruits.get(2)); // Orange
// Size of the list
System.out.println("Total fruits: " + fruits.size()); // 4
// Checking if element exists
System.out.println("Has Banana? " + fruits.contains("Banana")); // true
// Removing elements
fruits.remove("Banana"); // Remove by value
fruits.remove(0); // Remove by index (removes "Apple")
System.out.println("After removal: " + fruits); // [Orange, Apple]
}
}

🔍 🎯 Types of Lists

Java provides different List implementations for different needs:

1

ArrayList

Fast random access using indexes, but slower when inserting/removing in the middle

2

LinkedList

Fast insertion and removal anywhere, but slower random access

3

Vector

Thread-safe version of ArrayList (rarely used in modern code)

4

Stack

Last-In-First-Out (LIFO) structure extending Vector

LinkedListExample.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.util.LinkedList;
import java.util.List;
public class LinkedListExample {
public static void main(String[] args) {
// LinkedList is great for frequent insertions/deletions
LinkedList<String> tasks = new LinkedList<>();
// Adding elements
tasks.add("Task 1");
tasks.add("Task 2");
tasks.add("Task 3");
// Adding at specific positions
tasks.addFirst("Urgent Task"); // Add at beginning
tasks.addLast("Final Task"); // Add at end
tasks.add(2, "Middle Task"); // Add at index 2
System.out.println(tasks);
// [Urgent Task, Task 1, Middle Task, Task 2, Task 3, Final Task]
// LinkedList can also work as a Queue
tasks.removeFirst(); // Remove from beginning
tasks.removeLast(); // Remove from end
// Peek at elements without removing
System.out.println("First: " + tasks.getFirst());
System.out.println("Last: " + tasks.getLast());
}
}

🛒 Real-World Example: Shopping List App

ShoppingList.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import java.util.ArrayList;
import java.util.List;
public class ShoppingList {
private List<String> items;
public ShoppingList() {
this.items = new ArrayList<>();
}
// Add item to the list
public void addItem(String item) {
items.add(item);
System.out.println("Added: " + item);
}
// Add item at specific position
public void addItemAt(int position, String item) {
if (position >= 0 && position <= items.size()) {
items.add(position, item);
System.out.println("Inserted " + item + " at position " + position);
}
}
// Remove item by name
public void removeItem(String item) {
if (items.remove(item)) {
System.out.println("Removed: " + item);
} else {
System.out.println(item + " not found!");
}
}
// Check if item is on the list
public boolean hasItem(String item) {
return items.contains(item);
}
// Get total items
public int getTotalItems() {
return items.size();
}
// Print the list
public void printList() {
System.out.println("\n=== Shopping List ===");
if (items.isEmpty()) {
System.out.println("List is empty!");
} else {
for (int i = 0; i < items.size(); i++) {
System.out.println((i + 1) + ". " + items.get(i));
}
}
System.out.println("Total items: " + items.size());
}
public static void main(String[] args) {
ShoppingList myList = new ShoppingList();
// Building the shopping list
myList.addItem("Milk");
myList.addItem("Bread");
myList.addItem("Eggs");
myList.addItem("Butter");
myList.printList();
// Forgot something important!
myList.addItemAt(0, "Coffee"); // Add at the top
myList.printList();
// Already bought milk
myList.removeItem("Milk");
myList.printList();
// Check if we need eggs
System.out.println("\nNeed eggs? " + myList.hasItem("Eggs"));
}
}

📚 Real-World Example: Student Grades

StudentGrades.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class StudentGrades {
public static void main(String[] args) {
// Store test scores
List<Integer> scores = new ArrayList<>();
// Add scores
scores.add(85);
scores.add(92);
scores.add(78);
scores.add(95);
scores.add(88);
System.out.println("Scores: " + scores);
// Calculate average
double sum = 0;
for (int score : scores) {
sum += score;
}
double average = sum / scores.size();
System.out.println("Average: " + average);
// Find highest and lowest
int highest = Collections.max(scores);
int lowest = Collections.min(scores);
System.out.println("Highest: " + highest);
System.out.println("Lowest: " + lowest);
// Sort scores
Collections.sort(scores);
System.out.println("Sorted: " + scores);
// Reverse sort (highest first)
Collections.sort(scores, Collections.reverseOrder());
System.out.println("Descending: " + scores);
// Count scores above 90
int highScores = 0;
for (int score : scores) {
if (score >= 90) {
highScores++;
}
}
System.out.println("Scores >= 90: " + highScores);
}
}

🔧 Common List Operations

ListOperations.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ListOperations {
public static void main(String[] args) {
List<String> colors = new ArrayList<>();
// 1. Adding elements
colors.add("Red");
colors.add("Blue");
colors.add("Green");
colors.addAll(Arrays.asList("Yellow", "Purple"));
// 2. Accessing elements
String first = colors.get(0);
String last = colors.get(colors.size() - 1);
// 3. Modifying elements
colors.set(1, "Dark Blue"); // Replace "Blue" with "Dark Blue"
// 4. Searching
int index = colors.indexOf("Green"); // Returns 2
boolean hasRed = colors.contains("Red"); // Returns true
// 5. Removing elements
colors.remove("Yellow"); // Remove by value
colors.remove(0); // Remove by index
colors.removeIf(c -> c.startsWith("D")); // Remove if condition met
// 6. Size and empty check
int size = colors.size();
boolean isEmpty = colors.isEmpty();
// 7. Iteration
System.out.println("Using for-each:");
for (String color : colors) {
System.out.println(color);
}
System.out.println("\nUsing index:");
for (int i = 0; i < colors.size(); i++) {
System.out.println(i + ": " + colors.get(i));
}
// 8. Sublist
List<String> subList = colors.subList(0, 2); // From index 0 to 1
// 9. Converting to array
String[] colorArray = colors.toArray(new String[0]);
// 10. Clearing the list
colors.clear();
System.out.println("\nList cleared. Size: " + colors.size());
}
}

⚖️ List vs Array

ListVsArray.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ListVsArray {
public static void main(String[] args) {
// ARRAY: Fixed size, can't grow
String[] arrayNames = new String[3];
arrayNames[0] = "Alice";
arrayNames[1] = "Bob";
arrayNames[2] = "Charlie";
// arrayNames[3] = "David"; // ERROR! Index out of bounds
System.out.println("Array: " + Arrays.toString(arrayNames));
// LIST: Dynamic size, can grow and shrink
List<String> listNames = new ArrayList<>();
listNames.add("Alice");
listNames.add("Bob");
listNames.add("Charlie");
listNames.add("David"); // Works fine!
listNames.add("Eve"); // Keep adding!
System.out.println("List: " + listNames);
// Converting between array and list
// Array to List
String[] fruits = {"Apple", "Banana", "Orange"};
List<String> fruitList = new ArrayList<>(Arrays.asList(fruits));
// List to Array
String[] fruitArray = fruitList.toArray(new String[0]);
// Key differences:
System.out.println("\n=== Key Differences ===");
System.out.println("Array size is fixed: " + arrayNames.length);
System.out.println("List size is dynamic: " + listNames.size());
System.out.println("\nArray uses length property");
System.out.println("List uses size() method");
System.out.println("\nArray: faster, less memory");
System.out.println("List: flexible, more features");
}
}

🔑 Key Concepts

Ordered Collection

Elements maintain the order they were inserted

If you add [A, B, C], they stay in that exact order

Indexed Access

Access elements by their position number (0-based)

list.get(0) returns the first element

Duplicates Allowed

You can have the same element multiple times

[Apple, Banana, Apple] is perfectly fine

Dynamic Size

Lists grow and shrink automatically as you add/remove elements

No need to declare size upfront like arrays

Best Practices

  • Use ArrayList by default unless you need frequent insertions/deletions
  • Specify initial capacity if you know the approximate size: new ArrayList<>(100)
  • Use enhanced for-loop or streams instead of manual indexing when possible
  • Prefer List<String> interface type over ArrayList<String> in declarations
  • Use List.of() or Arrays.asList() for creating immutable lists
  • Avoid removing elements during iteration without using Iterator.remove()

💼 Interview Tips

  • Know the difference between ArrayList (array-backed) and LinkedList (doubly-linked nodes)
  • ArrayList is O(1) for get/set, O(n) for add/remove in middle
  • LinkedList is O(n) for get/set, O(1) for add/remove at ends
  • Understand that ArrayList needs to resize and copy when capacity exceeded
  • Remember that List maintains insertion order unlike Set
  • Know how to convert between arrays and lists
  • Understand fail-fast behavior with ConcurrentModificationException