Java Tutorial

Operators

Flow Control

String

Number and Date

Built-in Classes

Array

Class and Object

Inheritance and Polymorphism

Exception Handling

Collections, Generics and Enumerations

Reflection

Input/Output Stream

Annotation

Java Collections

Java Collections Framework is a set of interfaces and classes that provides a unified architecture for storing and manipulating groups of objects. It offers various data structures and algorithms for working with collections, such as lists, sets, maps, and queues.

In this tutorial, we'll provide an overview of the key interfaces and classes in the Java Collections Framework.

  • Collection Interface:

The Collection interface is the root interface for all collections in Java. It declares basic methods like add(), remove(), contains(), size(), and iterator(). There are three main subinterfaces of Collection: List, Set, and Queue.

  • List Interface:

The List interface represents an ordered collection (also known as a sequence) that allows duplicates. Elements in a list can be accessed by their index. Some common implementations of the List interface are:

  • ArrayList: A resizable array that provides fast random access and insertion/removal in the middle or end of the list.
  • LinkedList: A doubly-linked list that provides fast insertion/removal at the beginning, middle, or end of the list, but slower random access.

Example of using an ArrayList:

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

public class Main {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Carol");

        for (String name : names) {
            System.out.println(name);
        }
    }
}
  • Set Interface:

The Set interface represents an unordered collection that doesn't allow duplicates. Some common implementations of the Set interface are:

  • HashSet: A hash table-based implementation that provides fast insertion, removal, and search, but with no guarantee on the order of elements.
  • LinkedHashSet: A hash table and linked list implementation that maintains the insertion order of elements.
  • TreeSet: A balanced binary search tree implementation that keeps elements in a sorted order, but with slower insertion and removal compared to HashSet.

Example of using a HashSet:

import java.util.HashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<String> names = new HashSet<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Alice");

        for (String name : names) {
            System.out.println(name);
        }
    }
}
  • Map Interface:

The Map interface represents a collection of key-value pairs, where each key is unique. Some common implementations of the Map interface are:

  • HashMap: A hash table-based implementation that provides fast insertion, removal, and search, but with no guarantee on the order of keys.
  • LinkedHashMap: A hash table and linked list implementation that maintains the insertion order of keys.
  • TreeMap: A balanced binary search tree implementation that keeps keys in a sorted order, but with slower insertion and removal compared to HashMap.

Example of using a HashMap:

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> ageMap = new HashMap<>();
        ageMap.put("Alice", 30);
        ageMap.put("Bob", 25);
        ageMap.put("Carol", 35);

        for (Map.Entry<String, Integer> entry : ageMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}
  1. List Interface in Java Collections: The List interface represents an ordered collection of elements. It allows duplicate elements and provides methods to access, insert, update, and delete elements.

    import java.util.List;
    import java.util.ArrayList;
    
    public class ListExample {
        public static void main(String[] args) {
            List<String> names = new ArrayList<>();
            names.add("Alice");
            names.add("Bob");
            names.add("Charlie");
    
            System.out.println(names); // [Alice, Bob, Charlie]
        }
    }
    
  2. Java Set Interface and Its Implementations: The Set interface represents an unordered collection of unique elements. Common implementations include HashSet, TreeSet, and LinkedHashSet.

    import java.util.Set;
    import java.util.HashSet;
    
    public class SetExample {
        public static void main(String[] args) {
            Set<String> uniqueNames = new HashSet<>();
            uniqueNames.add("Alice");
            uniqueNames.add("Bob");
            uniqueNames.add("Alice"); // Duplicate, ignored
    
            System.out.println(uniqueNames); // [Alice, Bob]
        }
    }
    
  3. HashMap vs. HashTable in Java Collections: Both HashMap and HashTable are implementations of the Map interface. HashMap is not synchronized, while HashTable is synchronized.

    import java.util.HashMap;
    import java.util.Hashtable;
    import java.util.Map;
    
    public class MapExample {
        public static void main(String[] args) {
            Map<String, Integer> hashMap = new HashMap<>();
            Map<String, Integer> hashTable = new Hashtable<>();
            // Add, remove, and manipulate key-value pairs
        }
    }
    
  4. Sorting Elements in Java Collections: Use the Collections.sort() method or implement the Comparable interface for custom sorting.

    import java.util.Collections;
    import java.util.List;
    import java.util.ArrayList;
    
    public class SortingExample {
        public static void main(String[] args) {
            List<Integer> numbers = new ArrayList<>();
            numbers.add(5);
            numbers.add(2);
            numbers.add(8);
    
            Collections.sort(numbers);
            System.out.println(numbers); // [2, 5, 8]
        }
    }
    
  5. Working with ArrayList in Java Collections: ArrayList is a dynamic array that provides resizable arrays. It is widely used for its flexibility and efficiency.

    import java.util.ArrayList;
    import java.util.List;
    
    public class ArrayListExample {
        public static void main(String[] args) {
            List<String> colors = new ArrayList<>();
            colors.add("Red");
            colors.add("Green");
            colors.add("Blue");
    
            System.out.println(colors.get(1)); // Green
        }
    }
    
  6. Java LinkedList and Its Advantages: LinkedList is a doubly-linked list implementation in Java, providing fast insertion and deletion operations.

    import java.util.LinkedList;
    import java.util.List;
    
    public class LinkedListExample {
        public static void main(String[] args) {
            List<String> names = new LinkedList<>();
            names.add("Alice");
            names.add("Bob");
            names.add("Charlie");
    
            System.out.println(names.get(1)); // Bob
        }
    }
    
  7. Using Iterator in Java Collections: Iterator provides a way to traverse elements in a collection. It is especially useful for removing elements during traversal.

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class IteratorExample {
        public static void main(String[] args) {
            List<String> fruits = new ArrayList<>();
            fruits.add("Apple");
            fruits.add("Banana");
            fruits.add("Orange");
    
            Iterator<String> iterator = fruits.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        }
    }
    
  8. Java Collections Synchronized vs. Concurrent: Synchronized collections provide thread safety through explicit synchronization, while concurrent collections use advanced techniques for better concurrent performance.

    import java.util.Collections;
    import java.util.List;
    import java.util.ArrayList;
    
    public class SynchronizedExample {
        public static void main(String[] args) {
            List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
            // Thread-safe operations on synchronizedList
        }
    }
    
  9. Common Pitfalls in Java Collections Usage:

    • Forgetting to synchronize access to non-thread-safe collections in a multi-threaded environment.
    • Not handling null values properly in collections.
    • Using raw types instead of generics.

    Always be mindful of thread safety and proper usage to avoid common pitfalls.