Java LinkedList Tutorial with Examples

The LinkedList class in Java is part of the Java Collections Framework and provides a doubly linked list implementation of the List and Deque interfaces. It allows for efficient insertions and deletions and is suitable for various scenarios where dynamic data structures are required. This tutorial will cover all methods of LinkedList with examples and outputs, highlighting key points, use cases, best practices, performance considerations, and a real-time example with CRUD operations.

Table of Contents

  1. Introduction
  2. Key Points
  3. LinkedList Methods
    • add()
    • addFirst()
    • addLast()
    • addAll()
    • get()
    • getFirst()
    • getLast()
    • set()
    • remove()
    • removeFirst()
    • removeLast()
    • clear()
    • size()
    • isEmpty()
    • contains()
    • indexOf()
    • lastIndexOf()
    • toArray()
    • iterator()
    • listIterator()
    • subList()
  4. Use Cases
  5. Best Practices
  6. Performance Considerations
  7. Real-time Example with CRUD Operations
  8. Conclusion

1. Introduction

A LinkedList in Java is a part of the Java Collections Framework and provides a way to manage a dynamic sequence of elements. It is found in the java.util package and is one of the most flexible data structures in Java.

2. Key Points

  • LinkedList allows for constant-time insertions or removals using iterators.
  • It allows duplicate elements.
  • It maintains the insertion order.
  • It is not synchronized.
  • It supports both List and Deque operations.

3. LinkedList Methods

3.1. add()

The add() method is used to insert elements into the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        System.out.println(fruits);
    }
}

Output:

[Apple, Banana, Mango]

3.2. addFirst()

The addFirst() method inserts the specified element at the beginning of the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.addFirst("Apple");
        System.out.println(fruits);
    }
}

Output:

[Apple, Banana, Mango]

3.3. addLast()

The addLast() method inserts the specified element at the end of the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.addLast("Mango");
        System.out.println(fruits);
    }
}

Output:

[Apple, Banana, Mango]

3.4. addAll()

The addAll() method adds all elements of a collection to the LinkedList.

Example:

import java.util.LinkedList;
import java.util.Arrays;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.addAll(Arrays.asList("Banana", "Mango"));
        System.out.println(fruits);
    }
}

Output:

[Apple, Banana, Mango]

3.5. get()

The get() method returns the element at the specified index.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        System.out.println(fruits.get(1)); // Banana
    }
}

Output:

Banana

3.6. getFirst()

The getFirst() method returns the first element of the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        System.out.println(fruits.getFirst()); // Apple
    }
}

Output:

Apple

3.7. getLast()

The getLast() method returns the last element of the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        System.out.println(fruits.getLast()); // Mango
    }
}

Output:

Mango

3.8. set()

The set() method updates the element at the specified index.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.set(1, "Orange");
        System.out.println(fruits);
    }
}

Output:

[Apple, Orange, Mango]

3.9. remove()

The remove() method removes the element at the specified index or the first occurrence of the specified element.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.remove(1);
        System.out.println(fruits); // [Apple, Mango]

        fruits.remove("Mango");
        System.out.println(fruits); // [Apple]
    }
}

Output:

[Apple, Mango]
[Apple]

3.10. removeFirst()

The removeFirst() method removes and returns the first element of the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.removeFirst();
        System.out.println(fruits); // [Banana, Mango]
    }
}

Output:

[Banana, Mango]

3.11. removeLast()

The removeLast() method removes and returns the last element of the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.removeLast();
        System.out.println(fruits); // [Apple, Banana]
    }
}

Output:

[Apple, Banana]

3.12. clear()

The clear() method removes all elements from the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.clear();
        System.out.println(fruits);
    }
}

Output:

[]

3.13. size()

The size() method returns the number of elements in the LinkedList.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        System.out.println(fruits.size()); // 3
    }
}

Output:

3

3.14. isEmpty()

The isEmpty() method checks if the LinkedList is empty.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        System.out.println(fruits.isEmpty()); // true
        fruits.add("Apple");
        System.out.println(fruits.isEmpty()); // false
    }
}

Output:

true
false

3.15. contains()

The contains() method checks if the LinkedList contains a specified element.

Example:

import java.util.LinkedList;

public class LinkedListExample

 {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        System.out.println(fruits.contains("Banana")); // true
        System.out.println(fruits.contains("Mango")); // false
    }
}

Output:

true
false

3.16. indexOf()

The indexOf() method returns the index of the first occurrence of the specified element.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Apple");
        System.out.println(fruits.indexOf("Apple")); // 0
    }
}

Output:

0

3.17. lastIndexOf()

The lastIndexOf() method returns the index of the last occurrence of the specified element.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Apple");
        System.out.println(fruits.lastIndexOf("Apple")); // 2
    }
}

Output:

2

3.18. toArray()

The toArray() method converts the LinkedList into an array.

Example:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        String[] fruitsArray = fruits.toArray(new String[0]);
        for (String fruit : fruitsArray) {
            System.out.println(fruit);
        }
    }
}

Output:

Apple
Banana
Mango

3.19. iterator()

The iterator() method returns an iterator for the elements in the LinkedList.

Example:

import java.util.LinkedList;
import java.util.Iterator;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        Iterator<String> iterator = fruits.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

Output:

Apple
Banana
Mango

3.20. listIterator()

The listIterator() method returns a list iterator for the elements in the LinkedList.

Example:

import java.util.LinkedList;
import java.util.ListIterator;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        ListIterator<String> listIterator = fruits.listIterator();
        while (listIterator.hasNext()) {
            System.out.println(listIterator.next());
        }
        while (listIterator.hasPrevious()) {
            System.out.println(listIterator.previous());
        }
    }
}

Output:

Apple
Banana
Mango
Mango
Banana
Apple

3.21. subList()

The subList() method returns a view of the portion of the LinkedList between the specified indices.

Example:

import java.util.LinkedList;
import java.util.List;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Mango");
        fruits.add("Orange");
        List<String> subList = fruits.subList(1, 3);
        System.out.println(subList);
    }
}

Output:

[Banana, Mango]

4. Use Cases

  • Dynamic lists: LinkedList is used when the number of elements is constantly changing.
  • Frequent insertions/deletions: It is efficient for scenarios where elements are frequently added or removed.

5. Best Practices

  • Use generics: Always use generics to ensure type safety.
  • Choose based on use case: Prefer ArrayList for frequent access and LinkedList for frequent insertions/deletions.
  • Avoid frequent traversals: Traversing a LinkedList can be slow, so minimize the number of traversals.

6. Performance Considerations

  • Insertions and deletions: LinkedList provides constant-time performance for add and remove operations.
  • Memory usage: Each element in a LinkedList requires extra memory for storing pointers.
  • Access time: Accessing elements by index is slower compared to ArrayList due to sequential access.

7. Real-time Example with CRUD Operations

Managing an Animal Shelter:

Animal.java:

public class Animal {
    private String name;
    private int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Animal{name='" + name + "', age=" + age + "}";
    }
}

Main.java:

import java.util.LinkedList;
import java.util.Iterator;

public class Main {
    public static void main(String[] args) {
        LinkedList<Animal> animalShelter = new LinkedList<>();

        // Create
        animalShelter.add(new Animal("Lion", 5));
        animalShelter.add(new Animal("Tiger", 4));
        animalShelter.add(new Animal("Elephant", 10));

        // Read
        for (Animal animal : animalShelter) {
            System.out.println(animal);
        }

        // Update
        animalShelter.set(1, new Animal("Panther", 3));
        System.out.println("After Update:");
        for (Animal animal : animalShelter) {
            System.out.println(animal);
        }

        // Delete
        animalShelter.remove(0);
        System.out.println("After Deletion:");
        for (Animal animal : animalShelter) {
            System.out.println(animal);
        }
    }
}

Output:

Animal{name='Lion', age=5}
Animal{name='Tiger', age=4}
Animal{name='Elephant', age=10}
After Update:
Animal{name='Lion', age=5}
Animal{name='Panther', age=3}
Animal{name='Elephant', age=10}
After Deletion:
Animal{name='Panther', age=3}
Animal{name='Elephant', age=10}

8. Conclusion

The LinkedList class in Java is a versatile and efficient data structure for managing dynamic sequences of elements. By understanding its methods, use cases, and best practices, you can effectively utilize LinkedList in your Java applications. This tutorial covers the essential methods with examples and demonstrates a real-time example with CRUD operations.

Comments