Java Programming Core Packages
Utility Classes

Java Utility Package - Complete Guide

Master Java utility package (java.util): Learn Collections Framework, Date-Time API, utility classes, and essential tools for effective Java programming with practical examples.

150+ Classes

Comprehensive utilities

Date-Time API

Modern date handling

Collections

Data structures framework

Utility Classes

Arrays, Collections, Scanner

1. Introduction to java.util Package

The java.util package is one of the most important and frequently used packages in Java. It contains the Collections Framework, Date-Time API, and various utility classes for common programming tasks like random number generation, string tokenization, and property management.

Key Components
  • Collections Framework: Lists, Sets, Maps, Queues
  • Date-Time API (java.time): Modern date/time handling
  • Utility Classes: Arrays, Collections, Objects
  • Input/Output: Scanner, StringTokenizer
  • Random Generation: Random, SplittableRandom
  • Property Management: Properties, ResourceBundle
Common Use Cases
  • Data structure manipulation
  • Date and time calculations
  • Array sorting and searching
  • Random number generation
  • User input parsing
  • Configuration management

Package Hierarchy Overview

java.utiljava.util.concurrent (concurrency utilities)
java.utiljava.util.function (functional interfaces)
java.utiljava.util.stream (stream API)
java.utiljava.time (date-time API - Java 8+)

UtilPackageOverview.java
import java.util.*;
import java.time.*;
import java.util.stream.Collectors;

public class UtilPackageOverview {
    public static void main(String[] args) {
        System.out.println("=== Java Util Package Demonstration ===\n");
        
        // 1. Collections Framework
        System.out.println("1. Collections Framework Examples:");
        List fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));
        Set numbers = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
        Map wordCount = new HashMap<>();
        wordCount.put("hello", 3);
        wordCount.put("world", 2);
        
        System.out.println("   List: " + fruits);
        System.out.println("   Set: " + numbers);
        System.out.println("   Map: " + wordCount);
        
        // 2. Date-Time API (java.time)
        System.out.println("\n2. Date-Time API Examples:");
        LocalDate today = LocalDate.now();
        LocalTime now = LocalTime.now();
        LocalDateTime currentDateTime = LocalDateTime.now();
        
        System.out.println("   Today: " + today);
        System.out.println("   Current time: " + now);
        System.out.println("   Current date-time: " + currentDateTime);
        
        // 3. Arrays utility class
        System.out.println("\n3. Arrays Utility Examples:");
        int[] scores = {85, 92, 78, 90, 88};
        System.out.println("   Original array: " + Arrays.toString(scores));
        Arrays.sort(scores);
        System.out.println("   Sorted array: " + Arrays.toString(scores));
        System.out.println("   Binary search for 90: " + Arrays.binarySearch(scores, 90));
        
        // 4. Collections utility class
        System.out.println("\n4. Collections Utility Examples:");
        Collections.sort(fruits);
        System.out.println("   Sorted list: " + fruits);
        Collections.reverse(fruits);
        System.out.println("   Reversed list: " + fruits);
        System.out.println("   Max number: " + Collections.max(numbers));
        
        // 5. Random number generation
        System.out.println("\n5. Random Number Generation:");
        Random random = new Random();
        System.out.println("   Random int: " + random.nextInt(100));
        System.out.println("   Random double: " + random.nextDouble());
        System.out.println("   Random boolean: " + random.nextBoolean());
        
        // 6. Scanner for input
        System.out.println("\n6. Scanner Example (simulated):");
        String input = "John 25 75.5 true";
        Scanner scanner = new Scanner(input);
        System.out.println("   Parsing: \"" + input + "\"");
        System.out.println("   Name: " + scanner.next());
        System.out.println("   Age: " + scanner.nextInt());
        System.out.println("   Score: " + scanner.nextDouble());
        System.out.println("   Passed: " + scanner.nextBoolean());
        scanner.close();
        
        // 7. Stream API (Java 8+)
        System.out.println("\n7. Stream API Examples:");
        List filteredNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());
        System.out.println("   Even numbers: " + filteredNumbers);
        
        // 8. Optional class
        System.out.println("\n8. Optional Examples:");
        Optional optionalName = Optional.of("Alice");
        Optional emptyOptional = Optional.empty();
        
        System.out.println("   Optional with value: " + optionalName.orElse("Default"));
        System.out.println("   Empty optional: " + emptyOptional.orElse("Default"));
        
        System.out.println("\n=== End of Demonstration ===");
    }
}

2. Collections Framework

The Collections Framework provides a unified architecture for representing and manipulating collections. It includes interfaces, implementations, and algorithms for data structures.

Collections Framework Hierarchy
Iterable (interface)
    │
    └── Collection (interface)
        ├── List (interface)
        │   ├── ArrayList (class)
        │   ├── LinkedList (class)
        │   └── Vector (class)
        │       └── Stack (class)
        │
        ├── Set (interface)
        │   ├── HashSet (class)
        │   │   └── LinkedHashSet (class)
        │   └── SortedSet (interface)
        │       └── TreeSet (class)
        │
        └── Queue (interface)
            ├── PriorityQueue (class)
            └── Deque (interface)
                └── ArrayDeque (class)

Map (interface)
    ├── HashMap (class)
    │   └── LinkedHashMap (class)
    ├── Hashtable (class)
    └── SortedMap (interface)
        └── TreeMap (class)
CollectionsExamples.java
import java.util.*;
import java.util.stream.Collectors;

public class CollectionsExamples {
    public static void main(String[] args) {
        System.out.println("=== Collections Framework Examples ===\n");
        
        // 1. List Examples
        System.out.println("1. List Implementations:");
        
        // ArrayList - Resizable array, fast random access
        List arrayList = new ArrayList<>();
        arrayList.add("First");
        arrayList.add("Second");
        arrayList.add("Third");
        System.out.println("   ArrayList: " + arrayList);
        System.out.println("   Get element at index 1: " + arrayList.get(1));
        
        // LinkedList - Doubly linked list, fast insertions/deletions
        List linkedList = new LinkedList<>();
        linkedList.add(10);
        linkedList.add(20);
        linkedList.addFirst(5);  // Add at beginning
        linkedList.addLast(30);   // Add at end
        System.out.println("   LinkedList: " + linkedList);
        
        // 2. Set Examples
        System.out.println("\n2. Set Implementations:");
        
        // HashSet - No order, fastest
        Set hashSet = new HashSet<>();
        hashSet.add("Apple");
        hashSet.add("Banana");
        hashSet.add("Apple");  // Duplicate - ignored
        hashSet.add("Cherry");
        System.out.println("   HashSet (no order): " + hashSet);
        
        // TreeSet - Sorted order
        Set treeSet = new TreeSet<>();
        treeSet.add(50);
        treeSet.add(20);
        treeSet.add(80);
        treeSet.add(10);
        System.out.println("   TreeSet (sorted): " + treeSet);
        
        // LinkedHashSet - Insertion order
        Set linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("Zebra");
        linkedHashSet.add("Apple");
        linkedHashSet.add("Monkey");
        System.out.println("   LinkedHashSet (insertion order): " + linkedHashSet);
        
        // 3. Map Examples
        System.out.println("\n3. Map Implementations:");
        
        // HashMap - Key-value pairs, no order
        Map hashMap = new HashMap<>();
        hashMap.put("Alice", 25);
        hashMap.put("Bob", 30);
        hashMap.put("Charlie", 28);
        System.out.println("   HashMap: " + hashMap);
        System.out.println("   Bob's age: " + hashMap.get("Bob"));
        
        // TreeMap - Sorted by keys
        Map treeMap = new TreeMap<>();
        treeMap.put("Orange", 1.99);
        treeMap.put("Apple", 2.49);
        treeMap.put("Banana", 0.99);
        System.out.println("   TreeMap (sorted by key): " + treeMap);
        
        // LinkedHashMap - Insertion order
        Map linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put(3, "Third");
        linkedHashMap.put(1, "First");
        linkedHashMap.put(2, "Second");
        System.out.println("   LinkedHashMap (insertion order): " + linkedHashMap);
        
        // 4. Queue Examples
        System.out.println("\n4. Queue Implementations:");
        
        // PriorityQueue - Natural ordering or Comparator
        Queue priorityQueue = new PriorityQueue<>();
        priorityQueue.offer(30);
        priorityQueue.offer(10);
        priorityQueue.offer(20);
        System.out.println("   PriorityQueue (min-heap): " + priorityQueue);
        System.out.println("   Poll elements in order:");
        while (!priorityQueue.isEmpty()) {
            System.out.println("     " + priorityQueue.poll());
        }
        
        // ArrayDeque - Double-ended queue
        Deque arrayDeque = new ArrayDeque<>();
        arrayDeque.offerFirst("First");
        arrayDeque.offerLast("Last");
        arrayDeque.offerFirst("Very First");
        System.out.println("   ArrayDeque: " + arrayDeque);
        
        // 5. Collections Utility Methods
        System.out.println("\n5. Collections Utility Methods:");
        
        List numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 9, 3));
        System.out.println("   Original list: " + numbers);
        
        // Sorting
        Collections.sort(numbers);
        System.out.println("   After sort: " + numbers);
        
        // Reversing
        Collections.reverse(numbers);
        System.out.println("   After reverse: " + numbers);
        
        // Shuffling
        Collections.shuffle(numbers);
        System.out.println("   After shuffle: " + numbers);
        
        // Binary search
        Collections.sort(numbers);
        int index = Collections.binarySearch(numbers, 8);
        System.out.println("   Binary search for 8: index " + index);
        
        // Frequency
        List words = Arrays.asList("apple", "banana", "apple", "cherry", "apple");
        int frequency = Collections.frequency(words, "apple");
        System.out.println("   Frequency of 'apple': " + frequency);
        
        // 6. Java 8+ Stream API with Collections
        System.out.println("\n6. Stream API with Collections:");
        
        List names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
        
        // Filter and collect
        List filteredNames = names.stream()
            .filter(name -> name.length() > 4)
            .collect(Collectors.toList());
        System.out.println("   Names with length > 4: " + filteredNames);
        
        // Map and collect
        List nameLengths = names.stream()
            .map(String::length)
            .collect(Collectors.toList());
        System.out.println("   Name lengths: " + nameLengths);
        
        // Reduce
        Optional longestName = names.stream()
            .reduce((name1, name2) -> name1.length() > name2.length() ? name1 : name2);
        System.out.println("   Longest name: " + longestName.orElse("None"));
        
        // Grouping
        Map> namesByLength = names.stream()
            .collect(Collectors.groupingBy(String::length));
        System.out.println("   Names grouped by length: " + namesByLength);
    }
}
Collection Type Interface Implementations When to Use
List List<E> ArrayList, LinkedList, Vector Ordered collection with duplicates
Set Set<E> HashSet, TreeSet, LinkedHashSet Unique elements collection
Queue Queue<E> PriorityQueue, ArrayDeque FIFO or priority processing
Map Map<K,V> HashMap, TreeMap, LinkedHashMap Key-value pair storage

3. Date-Time API (java.time)

The java.time package (introduced in Java 8) provides a comprehensive date-time model that addresses the shortcomings of the old java.util.Date and java.util.Calendar classes.

DateTimeExamples.java
import java.time.*;
import java.time.format.*;
import java.time.temporal.*;
import java.util.*;

public class DateTimeExamples {
    public static void main(String[] args) {
        System.out.println("=== Java Date-Time API Examples ===\n");
        
        // 1. Basic Date-Time Classes
        System.out.println("1. Basic Date-Time Classes:");
        
        // LocalDate - Date without time
        LocalDate today = LocalDate.now();
        LocalDate birthday = LocalDate.of(1990, Month.JUNE, 15);
        System.out.println("   Today: " + today);
        System.out.println("   Birthday: " + birthday);
        System.out.println("   Day of week: " + today.getDayOfWeek());
        System.out.println("   Day of year: " + today.getDayOfYear());
        
        // LocalTime - Time without date
        LocalTime now = LocalTime.now();
        LocalTime meetingTime = LocalTime.of(14, 30); // 2:30 PM
        System.out.println("   Current time: " + now);
        System.out.println("   Meeting time: " + meetingTime);
        System.out.println("   Hour: " + now.getHour());
        System.out.println("   Minute: " + now.getMinute());
        
        // LocalDateTime - Date and time
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalDateTime eventDateTime = LocalDateTime.of(2024, 12, 25, 20, 0);
        System.out.println("   Current date-time: " + currentDateTime);
        System.out.println("   Event date-time: " + eventDateTime);
        
        // 2. Date Arithmetic and Manipulation
        System.out.println("\n2. Date Arithmetic:");
        
        // Adding/subtracting time
        LocalDate tomorrow = today.plusDays(1);
        LocalDate nextWeek = today.plusWeeks(1);
        LocalDate nextMonth = today.plusMonths(1);
        LocalDate nextYear = today.plusYears(1);
        
        System.out.println("   Tomorrow: " + tomorrow);
        System.out.println("   Next week: " + nextWeek);
        System.out.println("   Next month: " + nextMonth);
        System.out.println("   Next year: " + nextYear);
        
        // Working with periods
        Period age = Period.between(birthday, today);
        System.out.println("   Age: " + age.getYears() + " years, " + 
                         age.getMonths() + " months, " + 
                         age.getDays() + " days");
        
        // 3. Time Zones
        System.out.println("\n3. Time Zones:");
        
        // ZonedDateTime - Date-time with timezone
        ZonedDateTime nowInNY = ZonedDateTime.now(ZoneId.of("America/New_York"));
        ZonedDateTime nowInTokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        
        System.out.println("   Current time in New York: " + nowInNY);
        System.out.println("   Current time in Tokyo: " + nowInTokyo);
        
        // Convert between timezones
        ZonedDateTime londonTime = nowInNY.withZoneSameInstant(ZoneId.of("Europe/London"));
        System.out.println("   Same moment in London: " + londonTime);
        
        // 4. Formatting and Parsing
        System.out.println("\n4. Formatting and Parsing:");
        
        // Predefined formatters
        DateTimeFormatter isoDate = DateTimeFormatter.ISO_LOCAL_DATE;
        DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        
        System.out.println("   ISO date format: " + today.format(isoDate));
        System.out.println("   ISO date-time format: " + currentDateTime.format(isoDateTime));
        
        // Custom formatters
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
        System.out.println("   Custom format: " + currentDateTime.format(customFormatter));
        
        // Parsing strings to dates
        String dateStr = "15/06/2024";
        LocalDate parsedDate = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        System.out.println("   Parsed date: " + parsedDate);
        
        // 5. Duration and Period
        System.out.println("\n5. Duration and Period:");
        
        // Duration for time-based amount
        LocalTime startTime = LocalTime.of(9, 0);
        LocalTime endTime = LocalTime.of(17, 30);
        Duration workDuration = Duration.between(startTime, endTime);
        System.out.println("   Work duration: " + workDuration.toHours() + " hours, " + 
                         (workDuration.toMinutes() % 60) + " minutes");
        
        // Period for date-based amount
        LocalDate projectStart = LocalDate.of(2024, 1, 1);
        LocalDate projectEnd = LocalDate.of(2024, 12, 31);
        Period projectPeriod = Period.between(projectStart, projectEnd);
        System.out.println("   Project period: " + projectPeriod.getMonths() + " months, " + 
                         projectPeriod.getDays() + " days");
        
        // 6. Temporal Adjusters
        System.out.println("\n6. Temporal Adjusters:");
        
        // Common adjustments
        LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
        LocalDate nextMonday = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
        LocalDate lastDayOfYear = today.with(TemporalAdjusters.lastDayOfYear());
        
        System.out.println("   First day of month: " + firstDayOfMonth);
        System.out.println("   Last day of month: " + lastDayOfMonth);
        System.out.println("   Next Monday: " + nextMonday);
        System.out.println("   Last day of year: " + lastDayOfYear);
        
        // 7. Instant (Machine time)
        System.out.println("\n7. Instant (Timestamp):");
        
        Instant instantNow = Instant.now();
        Instant oneHourLater = instantNow.plus(1, ChronoUnit.HOURS);
        
        System.out.println("   Current instant: " + instantNow);
        System.out.println("   Epoch seconds: " + instantNow.getEpochSecond());
        System.out.println("   One hour later: " + oneHourLater);
        
        // 8. Legacy Date Conversion
        System.out.println("\n8. Legacy Date Conversion:");
        
        // Convert java.util.Date to java.time
        Date legacyDate = new Date();
        Instant instantFromLegacy = legacyDate.toInstant();
        LocalDateTime dateTimeFromLegacy = LocalDateTime.ofInstant(instantFromLegacy, ZoneId.systemDefault());
        
        System.out.println("   Legacy Date: " + legacyDate);
        System.out.println("   Converted to LocalDateTime: " + dateTimeFromLegacy);
        
        // Convert java.time to java.util.Date
        Date legacyDateFromInstant = Date.from(instantNow);
        System.out.println("   Converted back to Date: " + legacyDateFromInstant);
        
        // 9. Practical Examples
        System.out.println("\n9. Practical Examples:");
        
        // Calculate age
        LocalDate birthDate = LocalDate.of(1995, 8, 20);
        long ageInYears = ChronoUnit.YEARS.between(birthDate, today);
        System.out.println("   Age in years: " + ageInYears);
        
        // Check if date is in range
        LocalDate startDate = LocalDate.of(2024, 1, 1);
        LocalDate endDate = LocalDate.of(2024, 12, 31);
        boolean isInRange = !today.isBefore(startDate) && !today.isAfter(endDate);
        System.out.println("   Is today in 2024? " + isInRange);
        
        // Calculate working days (excluding weekends)
        LocalDate start = LocalDate.of(2024, 1, 1);
        LocalDate end = LocalDate.of(2024, 1, 31);
        long workingDays = start.datesUntil(end)
            .filter(date -> date.getDayOfWeek() != DayOfWeek.SATURDAY && 
                           date.getDayOfWeek() != DayOfWeek.SUNDAY)
            .count();
        System.out.println("   Working days in January 2024: " + workingDays);
    }
}
java.time Advantages
  • Immutable: Thread-safe by design
  • Fluent API: Easy to read and write
  • Comprehensive: Covers all date-time use cases
  • Time Zone Aware: Proper timezone handling
  • ISO-8601 Compliant: Standard format
  • No Null Issues: Methods don't return null
Key Classes
  • LocalDate: Date without time
  • LocalTime: Time without date
  • LocalDateTime: Date and time
  • ZonedDateTime: Date-time with timezone
  • Instant: Machine timestamp
  • Duration: Time-based amount
  • Period: Date-based amount

4. Utility Classes: Arrays, Collections, Objects

Java provides several utility classes with static methods for common operations on arrays, collections, and objects.

UtilityClassesExamples.java
import java.util.*;
import java.util.function.*;
import java.util.stream.*;

public class UtilityClassesExamples {
    public static void main(String[] args) {
        System.out.println("=== Utility Classes Examples ===\n");
        
        // 1. Arrays Utility Class
        System.out.println("1. Arrays Utility Methods:");
        
        int[] numbers = {5, 2, 8, 1, 9, 3, 7, 4, 6};
        System.out.println("   Original array: " + Arrays.toString(numbers));
        
        // Sorting
        Arrays.sort(numbers);
        System.out.println("   Sorted array: " + Arrays.toString(numbers));
        
        // Binary search
        int index = Arrays.binarySearch(numbers, 7);
        System.out.println("   Binary search for 7: index " + index);
        
        // Copying
        int[] copiedArray = Arrays.copyOf(numbers, 5);
        System.out.println("   Copied first 5 elements: " + Arrays.toString(copiedArray));
        
        // Filling
        int[] filledArray = new int[5];
        Arrays.fill(filledArray, 42);
        System.out.println("   Filled array with 42: " + Arrays.toString(filledArray));
        
        // Comparing
        int[] arr1 = {1, 2, 3};
        int[] arr2 = {1, 2, 3};
        int[] arr3 = {1, 2, 4};
        System.out.println("   arr1 equals arr2? " + Arrays.equals(arr1, arr2));
        System.out.println("   arr1 equals arr3? " + Arrays.equals(arr1, arr3));
        
        // Deep comparison for multidimensional arrays
        int[][] matrix1 = {{1, 2}, {3, 4}};
        int[][] matrix2 = {{1, 2}, {3, 4}};
        int[][] matrix3 = {{1, 2}, {3, 5}};
        System.out.println("   matrix1 deep equals matrix2? " + Arrays.deepEquals(matrix1, matrix2));
        System.out.println("   matrix1 deep equals matrix3? " + Arrays.deepEquals(matrix1, matrix3));
        
        // Stream from array
        IntStream stream = Arrays.stream(numbers);
        OptionalDouble average = stream.average();
        System.out.println("   Average of numbers: " + average.orElse(0));
        
        // 2. Collections Utility Class
        System.out.println("\n2. Collections Utility Methods:");
        
        List fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry", "Date", "Elderberry"));
        System.out.println("   Original list: " + fruits);
        
        // Sorting
        Collections.sort(fruits);
        System.out.println("   Sorted: " + fruits);
        
        // Reverse
        Collections.reverse(fruits);
        System.out.println("   Reversed: " + fruits);
        
        // Shuffle
        Collections.shuffle(fruits);
        System.out.println("   Shuffled: " + fruits);
        
        // Binary search (list must be sorted)
        Collections.sort(fruits);
        int fruitIndex = Collections.binarySearch(fruits, "Cherry");
        System.out.println("   Binary search for 'Cherry': index " + fruitIndex);
        
        // Min and Max
        List nums = Arrays.asList(45, 12, 89, 34, 67, 23);
        System.out.println("   Numbers: " + nums);
        System.out.println("   Min: " + Collections.min(nums));
        System.out.println("   Max: " + Collections.max(nums));
        
        // Frequency
        List words = Arrays.asList("apple", "banana", "apple", "cherry", "apple", "banana");
        int appleCount = Collections.frequency(words, "apple");
        int bananaCount = Collections.frequency(words, "banana");
        System.out.println("   Frequency - Apple: " + appleCount + ", Banana: " + bananaCount);
        
        // Replace all
        Collections.replaceAll(words, "apple", "orange");
        System.out.println("   After replaceAll: " + words);
        
        // Unmodifiable collections
        List unmodifiableList = Collections.unmodifiableList(fruits);
        System.out.println("   Unmodifiable list created (size: " + unmodifiableList.size() + ")");
        
        // Synchronized collections
        List synchronizedList = Collections.synchronizedList(new ArrayList<>(fruits));
        System.out.println("   Synchronized list created (thread-safe)");
        
        // 3. Objects Utility Class (Java 7+)
        System.out.println("\n3. Objects Utility Methods:");
        
        String str1 = "Hello";
        String str2 = "World";
        String str3 = null;
        
        // equals - null-safe comparison
        System.out.println("   Objects.equals(str1, str2): " + Objects.equals(str1, str2));
        System.out.println("   Objects.equals(str1, str1): " + Objects.equals(str1, str1));
        System.out.println("   Objects.equals(str1, null): " + Objects.equals(str1, null));
        System.out.println("   Objects.equals(null, null): " + Objects.equals(null, null));
        
        // hashCode - null-safe
        System.out.println("   Objects.hashCode(str1): " + Objects.hashCode(str1));
        System.out.println("   Objects.hashCode(null): " + Objects.hashCode(null));
        
        // toString - with null handling
        System.out.println("   Objects.toString(str1): " + Objects.toString(str1));
        System.out.println("   Objects.toString(null): " + Objects.toString(null));
        System.out.println("   Objects.toString(null, \"default\"): " + Objects.toString(null, "default"));
        
        // requireNonNull - validation
        try {
            Objects.requireNonNull(str1, "String cannot be null");
            System.out.println("   requireNonNull(str1): OK");
            // Objects.requireNonNull(str3, "String cannot be null"); // This would throw NPE
        } catch (NullPointerException e) {
            System.out.println("   requireNonNull(str3): " + e.getMessage());
        }
        
        // compare - null-aware comparison
        Comparator naturalOrder = Comparator.naturalOrder();
        int comparison = Objects.compare(str1, str2, naturalOrder);
        System.out.println("   Objects.compare(str1, str2): " + comparison);
        
        // 4. Random Utility Class
        System.out.println("\n4. Random Number Generation:");
        
        Random random = new Random();
        
        // Various random values
        System.out.println("   Random int (0-99): " + random.nextInt(100));
        System.out.println("   Random double: " + random.nextDouble());
        System.out.println("   Random boolean: " + random.nextBoolean());
        System.out.println("   Random Gaussian: " + random.nextGaussian());
        
        // Stream of random values
        System.out.println("   5 Random ints:");
        random.ints(5, 1, 101)
              .forEach(n -> System.out.println("     " + n));
        
        // Seeded random (reproducible)
        Random seededRandom = new Random(12345L);
        System.out.println("   Seeded random (always same): " + seededRandom.nextInt(100));
        
        // 5. Scanner Class
        System.out.println("\n5. Scanner Examples:");
        
        // Simulating user input
        String input = "John Doe 25 85.5 true\nAlice Smith 30 92.0 false";
        Scanner scanner = new Scanner(input);
        
        System.out.println("   Parsing input: \"" + input + "\"");
        
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            Scanner lineScanner = new Scanner(line);
            
            String firstName = lineScanner.next();
            String lastName = lineScanner.next();
            int age = lineScanner.nextInt();
            double score = lineScanner.nextDouble();
            boolean passed = lineScanner.nextBoolean();
            
            System.out.printf("     %s %s, Age: %d, Score: %.1f, Passed: %b\n",
                firstName, lastName, age, score, passed);
            
            lineScanner.close();
        }
        scanner.close();
        
        // 6. StringTokenizer (legacy)
        System.out.println("\n6. StringTokenizer (Legacy):");
        
        String text = "Java,Python,JavaScript,C++,Ruby";
        StringTokenizer tokenizer = new StringTokenizer(text, ",");
        
        System.out.println("   Tokens from \"" + text + "\":");
        while (tokenizer.hasMoreTokens()) {
            System.out.println("     " + tokenizer.nextToken());
        }
        
        // 7. Optional Class (Java 8+)
        System.out.println("\n7. Optional Examples:");
        
        // Creating Optionals
        Optional presentOptional = Optional.of("Hello");
        Optional emptyOptional = Optional.empty();
        Optional nullableOptional = Optional.ofNullable(null);
        
        // Checking and accessing
        System.out.println("   presentOptional isPresent: " + presentOptional.isPresent());
        System.out.println("   emptyOptional isPresent: " + emptyOptional.isPresent());
        
        // Getting values with defaults
        System.out.println("   presentOptional orElse: " + presentOptional.orElse("Default"));
        System.out.println("   emptyOptional orElse: " + emptyOptional.orElse("Default"));
        System.out.println("   emptyOptional orElseGet: " + emptyOptional.orElseGet(() -> "Generated Default"));
        
        // Mapping and filtering
        Optional upperCase = presentOptional.map(String::toUpperCase);
        Optional filtered = presentOptional.filter(s -> s.length() > 10);
        
        System.out.println("   Mapped to uppercase: " + upperCase.orElse("Empty"));
        System.out.println("   Filtered (length > 10): " + filtered.orElse("Filtered out"));
    }
}

5. Advanced Utilities and Functional Programming

AdvancedUtilities.java
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.prefs.*;

public class AdvancedUtilities {
    public static void main(String[] args) {
        System.out.println("=== Advanced Java Utilities ===\n");
        
        // 1. Functional Interfaces (java.util.function)
        System.out.println("1. Functional Interfaces:");
        
        // Predicate - test a condition
        Predicate isLong = s -> s.length() > 5;
        System.out.println("   Predicate test 'Hello': " + isLong.test("Hello"));
        System.out.println("   Predicate test 'Hello World': " + isLong.test("Hello World"));
        
        // Function - transform input to output
        Function lengthFunction = String::length;
        System.out.println("   Function apply 'Java': " + lengthFunction.apply("Java"));
        
        // Consumer - accept input, no output
        Consumer printer = System.out::println;
        System.out.print("   Consumer: ");
        printer.accept("Hello Consumer!");
        
        // Supplier - provide values
        Supplier randomSupplier = Math::random;
        System.out.println("   Supplier random: " + randomSupplier.get());
        
        // BinaryOperator - combine two values
        BinaryOperator adder = Integer::sum;
        System.out.println("   BinaryOperator 5 + 3: " + adder.apply(5, 3));
        
        // 2. Stream API Advanced Features
        System.out.println("\n2. Stream API Advanced Features:");
        
        List people = Arrays.asList(
            new Person("Alice", 25, "Engineering"),
            new Person("Bob", 30, "Sales"),
            new Person("Charlie", 28, "Engineering"),
            new Person("Diana", 35, "Marketing"),
            new Person("Eve", 22, "Engineering")
        );
        
        // Grouping by department
        Map> byDept = people.stream()
            .collect(Collectors.groupingBy(Person::getDepartment));
        System.out.println("   Grouped by department: " + byDept.keySet());
        
        // Average age by department
        Map avgAgeByDept = people.stream()
            .collect(Collectors.groupingBy(
                Person::getDepartment,
                Collectors.averagingInt(Person::getAge)
            ));
        System.out.println("   Average age by department: " + avgAgeByDept);
        
        // Partitioning (true/false)
        Map> youngAndOld = people.stream()
            .collect(Collectors.partitioningBy(p -> p.getAge() < 30));
        System.out.println("   Under 30: " + youngAndOld.get(true).size() + " people");
        System.out.println("   30 and over: " + youngAndOld.get(false).size() + " people");
        
        // Joining strings
        String allNames = people.stream()
            .map(Person::getName)
            .collect(Collectors.joining(", "));
        System.out.println("   All names: " + allNames);
        
        // 3. Concurrent Collections
        System.out.println("\n3. Concurrent Collections:");
        
        // ConcurrentHashMap - thread-safe map
        ConcurrentHashMap concurrentMap = new ConcurrentHashMap<>();
        concurrentMap.put("A", 1);
        concurrentMap.put("B", 2);
        concurrentMap.put("C", 3);
        
        // Atomic update
        concurrentMap.compute("A", (key, value) -> value == null ? 1 : value + 1);
        System.out.println("   ConcurrentHashMap: " + concurrentMap);
        
        // CopyOnWriteArrayList - thread-safe list
        CopyOnWriteArrayList copyOnWriteList = new CopyOnWriteArrayList<>();
        copyOnWriteList.add("First");
        copyOnWriteList.add("Second");
        copyOnWriteList.add("Third");
        System.out.println("   CopyOnWriteArrayList: " + copyOnWriteList);
        
        // BlockingQueue for producer-consumer
        BlockingQueue queue = new LinkedBlockingQueue<>(5);
        
        // Producer thread
        new Thread(() -> {
            try {
                for (int i = 1; i <= 10; i++) {
                    queue.put(i);
                    System.out.println("   Produced: " + i);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
        
        // Consumer thread
        new Thread(() -> {
            try {
                for (int i = 1; i <= 10; i++) {
                    Integer item = queue.take();
                    System.out.println("   Consumed: " + item);
                    Thread.sleep(150);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
        
        // 4. Atomic Classes (java.util.concurrent.atomic)
        System.out.println("\n4. Atomic Classes:");
        
        AtomicInteger atomicInt = new AtomicInteger(0);
        System.out.println("   Initial value: " + atomicInt.get());
        
        // Atomic operations
        atomicInt.incrementAndGet();
        System.out.println("   After increment: " + atomicInt.get());
        
        atomicInt.addAndGet(5);
        System.out.println("   After add 5: " + atomicInt.get());
        
        // Compare and set
        boolean updated = atomicInt.compareAndSet(6, 10);
        System.out.println("   CAS updated: " + updated + ", value: " + atomicInt.get());
        
        // 5. Properties and Preferences
        System.out.println("\n5. Properties and Preferences:");
        
        // Properties - configuration
        Properties props = new Properties();
        props.setProperty("database.url", "jdbc:mysql://localhost:3306/mydb");
        props.setProperty("database.user", "admin");
        props.setProperty("database.password", "secret");
        
        System.out.println("   Database URL: " + props.getProperty("database.url"));
        System.out.println("   Default value: " + props.getProperty("server.port", "8080"));
        
        // Preferences - user/system preferences
        Preferences prefs = Preferences.userRoot().node("/com/myapp");
        prefs.put("theme", "dark");
        prefs.putInt("font_size", 14);
        prefs.putBoolean("auto_save", true);
        
        System.out.println("   Theme: " + prefs.get("theme", "light"));
        System.out.println("   Font size: " + prefs.getInt("font_size", 12));
        System.out.println("   Auto save: " + prefs.getBoolean("auto_save", false));
        
        // 6. ResourceBundle - Internationalization
        System.out.println("\n6. ResourceBundle (I18N):");
        
        // Note: Actual usage requires properties files
        // ResourceBundle bundle = ResourceBundle.getBundle("Messages", locale);
        System.out.println("   (Requires properties files for actual i18n)");
        
        // 7. ServiceLoader - Service Provider Interface
        System.out.println("\n7. ServiceLoader (SPI):");
        
        // Load services implementing an interface
        // ServiceLoader loader = ServiceLoader.load(MyService.class);
        System.out.println("   (Used for plugin architectures)");
        
        // 8. Base64 Encoding (Java 8+)
        System.out.println("\n8. Base64 Encoding:");
        
        String original = "Hello World!";
        String encoded = Base64.getEncoder().encodeToString(original.getBytes());
        String decoded = new String(Base64.getDecoder().decode(encoded));
        
        System.out.println("   Original: " + original);
        System.out.println("   Encoded: " + encoded);
        System.out.println("   Decoded: " + decoded);
        
        // Wait for threads to complete
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    static class Person {
        private String name;
        private int age;
        private String department;
        
        public Person(String name, int age, String department) {
            this.name = name;
            this.age = age;
            this.department = department;
        }
        
        public String getName() { return name; }
        public int getAge() { return age; }
        public String getDepartment() { return department; }
        
        @Override
        public String toString() {
            return name + "(" + age + ")";
        }
    }
}
Utility Category Key Classes Primary Use Java Version
Collections List, Set, Map, Queue Data structure management Java 1.2+
Date-Time LocalDate, LocalTime, ZonedDateTime Date and time operations Java 8+
Functional Predicate, Function, Consumer Functional programming Java 8+
Concurrent ConcurrentHashMap, CopyOnWriteArrayList Thread-safe collections Java 5+
Stream API Stream, Collectors Data processing pipelines Java 8+
Utility Arrays, Collections, Objects Common operations utilities Java 1.0+

6. Practical Utility Examples

Example 1: E-commerce Shopping Cart

import java.util.*;
import java.util.stream.*;
import java.time.*;
import java.time.format.*;

public class ShoppingCartSystem {
    private Map products = new HashMap<>();
    private Map userCarts = new HashMap<>();
    private List orders = new ArrayList<>();
    
    public ShoppingCartSystem() {
        // Initialize some products
        products.put("P001", new Product("P001", "Laptop", 999.99, "Electronics", 10));
        products.put("P002", new Product("P002", "Smartphone", 699.99, "Electronics", 20));
        products.put("P003", new Product("P003", "Headphones", 199.99, "Audio", 50));
        products.put("P004", new Product("P004", "Book", 29.99, "Books", 100));
        products.put("P005", new Product("P005", "Mouse", 49.99, "Electronics", 30));
    }
    
    // Add product to user's cart
    public void addToCart(String userId, String productId, int quantity) {
        Product product = products.get(productId);
        if (product == null) {
            throw new IllegalArgumentException("Product not found: " + productId);
        }
        
        if (product.getStock() < quantity) {
            throw new IllegalArgumentException("Insufficient stock");
        }
        
        Cart cart = userCarts.computeIfAbsent(userId, k -> new Cart());
        cart.addItem(product, quantity);
        
        // Update product stock
        product.setStock(product.getStock() - quantity);
    }
    
    // Remove product from cart
    public void removeFromCart(String userId, String productId) {
        Cart cart = userCarts.get(userId);
        if (cart != null) {
            int quantity = cart.removeItem(productId);
            if (quantity > 0) {
                Product product = products.get(productId);
                product.setStock(product.getStock() + quantity);
            }
        }
    }
    
    // Checkout and create order
    public Order checkout(String userId, String shippingAddress) {
        Cart cart = userCarts.get(userId);
        if (cart == null || cart.isEmpty()) {
            throw new IllegalStateException("Cart is empty");
        }
        
        Order order = new Order(
            generateOrderId(),
            userId,
            new HashMap<>(cart.getItems()),
            cart.getTotal(),
            shippingAddress,
            LocalDateTime.now()
        );
        
        orders.add(order);
        userCarts.remove(userId);
        
        return order;
    }
    
    // Get user's cart summary
    public CartSummary getCartSummary(String userId) {
        Cart cart = userCarts.get(userId);
        if (cart == null) {
            return new CartSummary(0, 0.0, Collections.emptyList());
        }
        
        return new CartSummary(
            cart.getTotalItems(),
            cart.getTotal(),
            cart.getItems().entrySet().stream()
                .map(entry -> new CartItem(
                    entry.getKey(),
                    entry.getValue().getProduct().getName(),
                    entry.getValue().getQuantity(),
                    entry.getValue().getPrice(),
                    entry.getValue().getTotal()
                ))
                .collect(Collectors.toList())
        );
    }
    
    // Get product recommendations based on cart contents
    public List getRecommendations(String userId) {
        Cart cart = userCarts.get(userId);
        if (cart == null || cart.isEmpty()) {
            return getPopularProducts(3);
        }
        
        // Get categories of products in cart
        Set cartCategories = cart.getItems().values().stream()
            .map(item -> item.getProduct().getCategory())
            .collect(Collectors.toSet());
        
        // Find products in same categories, not already in cart
        return products.values().stream()
            .filter(p -> cartCategories.contains(p.getCategory()))
            .filter(p -> !cart.getItems().containsKey(p.getId()))
            .filter(p -> p.getStock() > 0)
            .sorted(Comparator.comparingDouble(Product::getPrice))
            .limit(5)
            .collect(Collectors.toList());
    }
    
    // Get sales statistics
    public SalesStatistics getSalesStatistics(LocalDate startDate, LocalDate endDate) {
        List filteredOrders = orders.stream()
            .filter(order -> !order.getOrderDate().toLocalDate().isBefore(startDate))
            .filter(order -> !order.getOrderDate().toLocalDate().isAfter(endDate))
            .collect(Collectors.toList());
        
        double totalRevenue = filteredOrders.stream()
            .mapToDouble(Order::getTotalAmount)
            .sum();
        
        Map productsSold = filteredOrders.stream()
            .flatMap(order -> order.getItems().values().stream())
            .collect(Collectors.groupingBy(
                item -> item.getProduct().getCategory(),
                Collectors.summingLong(CartItemDetail::getQuantity)
            ));
        
        return new SalesStatistics(
            filteredOrders.size(),
            totalRevenue,
            productsSold
        );
    }
    
    private String generateOrderId() {
        return "ORD" + System.currentTimeMillis() + "-" + 
               UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }
    
    private List getPopularProducts(int count) {
        return products.values().stream()
            .filter(p -> p.getStock() > 0)
            .sorted(Comparator.comparingInt(Product::getStock).reversed())
            .limit(count)
            .collect(Collectors.toList());
    }
    
    // Inner classes
    static class Product {
        private String id;
        private String name;
        private double price;
        private String category;
        private int stock;
        
        // Constructor, getters, setters
        public Product(String id, String name, double price, String category, int stock) {
            this.id = id;
            this.name = name;
            this.price = price;
            this.category = category;
            this.stock = stock;
        }
        
        // Getters and setters
        public String getId() { return id; }
        public String getName() { return name; }
        public double getPrice() { return price; }
        public String getCategory() { return category; }
        public int getStock() { return stock; }
        public void setStock(int stock) { this.stock = stock; }
    }
    
    static class Cart {
        private Map items = new HashMap<>();
        
        public void addItem(Product product, int quantity) {
            CartItemDetail item = items.computeIfAbsent(product.getId(), 
                k -> new CartItemDetail(product, 0));
            item.setQuantity(item.getQuantity() + quantity);
        }
        
        public int removeItem(String productId) {
            CartItemDetail item = items.remove(productId);
            return item != null ? item.getQuantity() : 0;
        }
        
        public int getTotalItems() {
            return items.values().stream()
                .mapToInt(CartItemDetail::getQuantity)
                .sum();
        }
        
        public double getTotal() {
            return items.values().stream()
                .mapToDouble(CartItemDetail::getTotal)
                .sum();
        }
        
        public boolean isEmpty() { return items.isEmpty(); }
        public Map getItems() { return items; }
    }
    
    static class CartItemDetail {
        private Product product;
        private int quantity;
        
        public CartItemDetail(Product product, int quantity) {
            this.product = product;
            this.quantity = quantity;
        }
        
        public Product getProduct() { return product; }
        public int getQuantity() { return quantity; }
        public void setQuantity(int quantity) { this.quantity = quantity; }
        public double getPrice() { return product.getPrice(); }
        public double getTotal() { return product.getPrice() * quantity; }
    }
    
    static class Order {
        private String orderId;
        private String userId;
        private Map items;
        private double totalAmount;
        private String shippingAddress;
        private LocalDateTime orderDate;
        
        public Order(String orderId, String userId, Map items,
                    double totalAmount, String shippingAddress, LocalDateTime orderDate) {
            this.orderId = orderId;
            this.userId = userId;
            this.items = items;
            this.totalAmount = totalAmount;
            this.shippingAddress = shippingAddress;
            this.orderDate = orderDate;
        }
        
        // Getters
        public String getOrderId() { return orderId; }
        public String getUserId() { return userId; }
        public Map getItems() { return items; }
        public double getTotalAmount() { return totalAmount; }
        public String getShippingAddress() { return shippingAddress; }
        public LocalDateTime getOrderDate() { return orderDate; }
    }
    
    // DTOs for API responses
    static class CartSummary {
        private int totalItems;
        private double totalAmount;
        private List items;
        
        public CartSummary(int totalItems, double totalAmount, List items) {
            this.totalItems = totalItems;
            this.totalAmount = totalAmount;
            this.items = items;
        }
        
        // Getters
        public int getTotalItems() { return totalItems; }
        public double getTotalAmount() { return totalAmount; }
        public List getItems() { return items; }
    }
    
    static class CartItem {
        private String productId;
        private String productName;
        private int quantity;
        private double unitPrice;
        private double totalPrice;
        
        public CartItem(String productId, String productName, int quantity, 
                       double unitPrice, double totalPrice) {
            this.productId = productId;
            this.productName = productName;
            this.quantity = quantity;
            this.unitPrice = unitPrice;
            this.totalPrice = totalPrice;
        }
        
        // Getters
        public String getProductId() { return productId; }
        public String getProductName() { return productName; }
        public int getQuantity() { return quantity; }
        public double getUnitPrice() { return unitPrice; }
        public double getTotalPrice() { return totalPrice; }
    }
    
    static class SalesStatistics {
        private int totalOrders;
        private double totalRevenue;
        private Map productsSoldByCategory;
        
        public SalesStatistics(int totalOrders, double totalRevenue, 
                              Map productsSoldByCategory) {
            this.totalOrders = totalOrders;
            this.totalRevenue = totalRevenue;
            this.productsSoldByCategory = productsSoldByCategory;
        }
        
        // Getters
        public int getTotalOrders() { return totalOrders; }
        public double getTotalRevenue() { return totalRevenue; }
        public Map getProductsSoldByCategory() { return productsSoldByCategory; }
    }
    
    // Demo usage
    public static void main(String[] args) {
        ShoppingCartSystem system = new ShoppingCartSystem();
        
        // User adds items to cart
        system.addToCart("user123", "P001", 1);  // Laptop
        system.addToCart("user123", "P003", 2);  // Headphones
        system.addToCart("user123", "P005", 1);  // Mouse
        
        // Get cart summary
        CartSummary summary = system.getCartSummary("user123");
        System.out.println("Cart Summary:");
        System.out.println("Total Items: " + summary.getTotalItems());
        System.out.println("Total Amount: $" + summary.getTotalAmount());
        
        // Get recommendations
        List recommendations = system.getRecommendations("user123");
        System.out.println("\nRecommendations:");
        recommendations.forEach(p -> 
            System.out.println("- " + p.getName() + ": $" + p.getPrice()));
        
        // Checkout
        Order order = system.checkout("user123", "123 Main St, City, Country");
        System.out.println("\nOrder created:");
        System.out.println("Order ID: " + order.getOrderId());
        System.out.println("Total: $" + order.getTotalAmount());
        System.out.println("Date: " + order.getOrderDate());
        
        // Sales statistics
        SalesStatistics stats = system.getSalesStatistics(
            LocalDate.now().minusDays(30),
            LocalDate.now()
        );
        System.out.println("\nSales Statistics (last 30 days):");
        System.out.println("Total Orders: " + stats.getTotalOrders());
        System.out.println("Total Revenue: $" + stats.getTotalRevenue());
    }
}

7. Best Practices and Performance Tips

Common Utility Package Mistakes:
  1. Using legacy Date/Calendar: Prefer java.time package
  2. Not specifying initial capacity: Causes resizing overhead
  3. Ignoring thread safety: Using non-thread-safe collections in multi-threaded environments
  4. Not using Arrays/Collections utility methods: Reinventing the wheel
  5. Memory leaks with large collections: Not clearing references
  6. Inefficient iteration: Using for loops instead of enhanced for or streams
Best Practices
  • Always use java.time for date-time operations
  • Prefer immutable collections when possible
  • Use diamond operator for type inference
  • Specify initial capacity for large collections
  • Use try-with-resources with Scanner and other closable resources
  • Prefer Optional over null returns
  • Use Stream API for complex data processing
Performance Tips
  • HashMap vs TreeMap: Use HashMap unless you need sorted order
  • ArrayList vs LinkedList: Use ArrayList for random access, LinkedList for frequent insertions/deletions
  • Arrays.copyOf vs System.arraycopy: Use Arrays.copyOf for convenience
  • Parallel streams: Use for large datasets, avoid for small collections
  • Collections.unmodifiableXXX: Create read-only views for safety
  • StringJoiner/String.join: More efficient than StringBuilder for joining strings

Key Takeaways

  • java.util is the most important utility package in Java
  • Collections Framework provides data structure implementations
  • java.time is the modern date-time API (Java 8+)
  • Utility classes (Arrays, Collections, Objects) provide common operations
  • Functional interfaces and Stream API enable functional programming
  • Choose the right collection/utility for your specific use case