Skip to main content

Overview

The java.util package contains the collections framework, legacy collection classes, event model, date and time facilities, internationalization, and miscellaneous utility classes.

Collections Framework

The Java Collections Framework provides a unified architecture for representing and manipulating collections.

Core Interfaces

Collection<E>
├── List<E> (ordered, allows duplicates)
│   ├── ArrayList<E>
│   ├── LinkedList<E>
│   └── Vector<E>
├── Set<E> (no duplicates)
│   ├── HashSet<E>
│   ├── LinkedHashSet<E>
│   └── TreeSet<E>
└── Queue<E> (FIFO operations)
    ├── PriorityQueue<E>
    └── LinkedList<E>

Map<K,V> (key-value pairs)
├── HashMap<K,V>
├── LinkedHashMap<K,V>
├── TreeMap<K,V>
└── Hashtable<K,V>

List Interface

An ordered collection where users have precise control over where elements are inserted.
add(E element)
boolean
Appends the element to the end of the list.
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
add(int index, E element)
void
Inserts the element at the specified position.
list.add(1, "orange"); // Insert at index 1
get(int index)
E
Returns the element at the specified position.
String fruit = list.get(0); // "apple"
set(int index, E element)
E
Replaces the element at the specified position.
remove(int index)
E
Removes and returns the element at the specified position.
indexOf(Object o)
int
Returns the index of the first occurrence of the element, or -1 if not found.
size()
int
Returns the number of elements in the list.
isEmpty()
boolean
Returns true if the list contains no elements.
contains(Object o)
boolean
Returns true if the list contains the specified element.
clear()
void
Removes all elements from the list.

ArrayList

Resizable-array implementation of the List interface.
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, Serializable
ArrayList provides:
  • Dynamic resizing - Grows automatically as elements are added
  • Fast random access - O(1) time for get() and set()
  • Amortized constant time - O(1) amortized for add()
  • Not thread-safe - Use Collections.synchronizedList() for thread safety
// Creating ArrayLists
List<String> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>(100); // Initial capacity
List<String> list3 = new ArrayList<>(existingCollection);

// Adding elements
list1.add("first");
list1.add("second");
list1.add(0, "new first"); // Insert at position

// Accessing elements
String element = list1.get(1);
list1.set(1, "modified");

// Removing elements
list1.remove(0);              // Remove by index
list1.remove("second");       // Remove by value

// Iteration
for (String item : list1) {
    System.out.println(item);
}

// Capacity management
list1.ensureCapacity(1000);   // Pre-allocate capacity
list1.trimToSize();           // Reduce capacity to size
ArrayList is generally preferred over Vector due to better performance (no synchronization overhead).

HashMap

Hash table based implementation of the Map interface.
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable
HashMap provides:
  • Constant-time performance - O(1) for get() and put() (on average)
  • Permits null - Allows null keys and null values
  • No order guarantee - Does not maintain insertion order
  • Not thread-safe - Use ConcurrentHashMap for concurrent access
// Creating HashMaps
Map<String, Integer> map = new HashMap<>();
Map<String, Integer> map2 = new HashMap<>(100); // Initial capacity
Map<String, Integer> map3 = new HashMap<>(existingMap);

// Adding/updating entries
map.put("apple", 5);
map.put("banana", 3);
map.put("apple", 7);          // Overwrites previous value

// Conditional put
map.putIfAbsent("cherry", 2); // Only if key doesn't exist

// Retrieving values
Integer count = map.get("apple");           // 7
Integer defaultVal = map.getOrDefault("pear", 0); // 0

// Checking existence
boolean hasApple = map.containsKey("apple");   // true
boolean hasValue5 = map.containsValue(5);      // false

// Removing entries
map.remove("banana");
map.remove("apple", 7);       // Remove only if value matches

// Iteration
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

// Keys and values
Set<String> keys = map.keySet();
Collection<Integer> values = map.values();

// Advanced operations
map.compute("apple", (k, v) -> v == null ? 1 : v + 1);
map.merge("banana", 1, Integer::sum);
Performance Tips:
  • Initial capacity should be set based on expected size
  • Load factor (default 0.75) balances time vs space
  • Use LinkedHashMap to maintain insertion order
  • Use TreeMap for sorted keys

Map Interface

put(K key, V value)
V
Associates the specified value with the specified key.
get(Object key)
V
Returns the value to which the specified key is mapped.
remove(Object key)
V
Removes the mapping for the specified key.
containsKey(Object key)
boolean
Returns true if this map contains a mapping for the specified key.
containsValue(Object value)
boolean
Returns true if this map maps one or more keys to the specified value.
keySet()
Set<K>
Returns a Set view of the keys contained in this map.
values()
Collection<V>
Returns a Collection view of the values contained in this map.
entrySet()
Set<Map.Entry<K,V>>
Returns a Set view of the mappings contained in this map.

Stream API

The Stream API provides functional-style operations on sequences of elements.

Stream Interface

public interface Stream<T> extends BaseStream<T, Stream<T>>
// From collections
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream1 = list.stream();
Stream<String> parallelStream = list.parallelStream();

// From arrays
String[] array = {"x", "y", "z"};
Stream<String> stream2 = Arrays.stream(array);

// From values
Stream<String> stream3 = Stream.of("one", "two", "three");

// From builder
Stream<String> stream4 = Stream.<String>builder()
    .add("a")
    .add("b")
    .build();

// Generate infinite streams
Stream<Double> randoms = Stream.generate(Math::random);
Stream<Integer> numbers = Stream.iterate(0, n -> n + 1);

// From ranges
IntStream range = IntStream.range(1, 11);  // 1 to 10
These operations return a new stream and are lazy (not executed until a terminal operation is invoked).
filter(Predicate<T> predicate)
Stream<T>
Returns a stream with elements matching the predicate.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> evens = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList()); // [2, 4, 6]
map(Function<T,R> mapper)
Stream<R>
Transforms each element using the provided function.
List<String> names = Arrays.asList("alice", "bob", "charlie");
List<String> upper = names.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
flatMap(Function<T,Stream<R>> mapper)
Stream<R>
Flattens nested streams into a single stream.
List<List<Integer>> nested = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4)
);
List<Integer> flat = nested.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList()); // [1, 2, 3, 4]
distinct()
Stream<T>
Returns a stream with distinct elements.
sorted()
Stream<T>
Returns a sorted stream.
limit(long maxSize)
Stream<T>
Returns a stream truncated to the specified size.
skip(long n)
Stream<T>
Returns a stream with the first n elements skipped.
These operations trigger the execution of the stream pipeline and produce a result.
forEach(Consumer<T> action)
void
Performs an action for each element.
list.stream().forEach(System.out::println);
collect(Collector<T,A,R> collector)
R
Accumulates elements into a collection or other result.
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
String joined = stream.collect(Collectors.joining(", "));
reduce(BinaryOperator<T> accumulator)
Optional<T>
Combines elements using an associative accumulation function.
Optional<Integer> sum = numbers.stream()
    .reduce((a, b) -> a + b);

int total = numbers.stream()
    .reduce(0, Integer::sum);
count()
long
Returns the count of elements in the stream.
anyMatch(Predicate<T> predicate)
boolean
Returns true if any element matches the predicate.
allMatch(Predicate<T> predicate)
boolean
Returns true if all elements match the predicate.
noneMatch(Predicate<T> predicate)
boolean
Returns true if no elements match the predicate.
findFirst()
Optional<T>
Returns an Optional describing the first element.
findAny()
Optional<T>
Returns an Optional describing some element.

Stream Examples

public class StreamExamples {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 35),
            new Person("Diana", 28)
        );
        
        // Filter and map
        List<String> namesOver30 = people.stream()
            .filter(p -> p.getAge() > 30)
            .map(Person::getName)
            .collect(Collectors.toList());
        
        // Average age
        double avgAge = people.stream()
            .mapToInt(Person::getAge)
            .average()
            .orElse(0.0);
        
        // Grouping
        Map<Integer, List<Person>> byAge = people.stream()
            .collect(Collectors.groupingBy(Person::getAge));
        
        // Partitioning
        Map<Boolean, List<Person>> over30 = people.stream()
            .collect(Collectors.partitioningBy(p -> p.getAge() > 30));
        
        // Finding max/min
        Optional<Person> oldest = people.stream()
            .max(Comparator.comparing(Person::getAge));
        
        // Parallel processing
        long count = people.parallelStream()
            .filter(p -> p.getAge() > 25)
            .count();
    }
}

Utility Classes

Collections Class

Provides static methods to operate on collections.
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5));

// Sorting
Collections.sort(list);                    // [1, 1, 3, 4, 5]
Collections.sort(list, Collections.reverseOrder());

// Searching
int index = Collections.binarySearch(list, 3);

// Shuffling
Collections.shuffle(list);

// Min/Max
int min = Collections.min(list);
int max = Collections.max(list);

// Frequency
int count = Collections.frequency(list, 1); // Count of 1s

// Reverse
Collections.reverse(list);

// Fill
Collections.fill(list, 0);                 // Fill with zeros

// Synchronized wrappers
List<Integer> syncList = Collections.synchronizedList(list);
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());

// Unmodifiable wrappers
List<Integer> unmodifiable = Collections.unmodifiableList(list);

// Empty collections
List<String> empty = Collections.emptyList();
Set<String> emptySet = Collections.emptySet();
Map<String, Integer> emptyMap = Collections.emptyMap();

// Singleton
Set<String> singleton = Collections.singleton("only");

Arrays Class

Provides static methods to operate on arrays.
int[] numbers = {5, 2, 8, 1, 9};

// Sorting
Arrays.sort(numbers);              // [1, 2, 5, 8, 9]

// Binary search (array must be sorted)
int index = Arrays.binarySearch(numbers, 5);

// Fill
Arrays.fill(numbers, 0);           // All elements = 0

// Copy
int[] copy = Arrays.copyOf(numbers, numbers.length);
int[] partial = Arrays.copyOfRange(numbers, 0, 3);

// Equals
boolean same = Arrays.equals(numbers, copy);

// Convert to List
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

// Convert to String
String str = Arrays.toString(numbers);

// Stream
int sum = Arrays.stream(numbers).sum();

Optional Class

A container object which may or may not contain a non-null value.
// Creating Optionals
Optional<String> present = Optional.of("value");
Optional<String> empty = Optional.empty();
Optional<String> nullable = Optional.ofNullable(possiblyNull);

// Checking presence
if (present.isPresent()) {
    String value = present.get();
}

// Alternative: ifPresent
present.ifPresent(value -> System.out.println(value));

// Default values
String value = empty.orElse("default");
String value2 = empty.orElseGet(() -> "computed default");

// Throw exception if empty
String value3 = empty.orElseThrow();
String value4 = empty.orElseThrow(IllegalStateException::new);

// Transforming
Optional<Integer> length = present.map(String::length);
Optional<String> upper = present.map(String::toUpperCase);

// Filtering
Optional<String> filtered = present.filter(s -> s.length() > 3);

// flatMap for nested Optionals
Optional<String> result = present.flatMap(this::findRelated);

Complete Example

import java.util.*;
import java.util.stream.*;

public class CollectionsExample {
    public static void main(String[] args) {
        // Create a list of numbers
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // Stream processing
        List<Integer> evenSquares = numbers.stream()
            .filter(n -> n % 2 == 0)           // Keep only even numbers
            .map(n -> n * n)                   // Square each number
            .collect(Collectors.toList());     // [4, 16, 36, 64, 100]
        
        // Working with Maps
        Map<String, Integer> inventory = new HashMap<>();
        inventory.put("apple", 10);
        inventory.put("banana", 5);
        inventory.put("orange", 8);
        
        // Update inventory
        inventory.merge("apple", 5, Integer::sum);    // apple: 15
        inventory.computeIfAbsent("grape", k -> 0);   // grape: 0
        
        // Process entries
        inventory.forEach((fruit, count) -> 
            System.out.println(fruit + ": " + count));
        
        // Working with Sets
        Set<String> set1 = new HashSet<>(Arrays.asList("a", "b", "c"));
        Set<String> set2 = new HashSet<>(Arrays.asList("b", "c", "d"));
        
        // Union
        Set<String> union = new HashSet<>(set1);
        union.addAll(set2);  // [a, b, c, d]
        
        // Intersection
        Set<String> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);  // [b, c]
        
        // Difference
        Set<String> diff = new HashSet<>(set1);
        diff.removeAll(set2);  // [a]
    }
}
The Collections Framework is designed to be interoperable. All implementations provide constructors that accept other collection types, making it easy to convert between different collection types.

Build docs developers (and LLMs) love