Table of Contents

  1. Condition Statements
  2. Control Flow Statements
  3. String Handling
  4. Arrays
  5. Date and Time
  6. Searching
  7. Sorting
  8. Object-Oriented Programming
  9. Collections Framework
  10. Functional Programming
  11. Exception Handling
  12. Quick Reference & Tips

Condition Statements

Basic Syntax

// Simple if-else
if (condition) {
    // code
} else if (condition2) {
    // code
} else {
    // code
}
 
// Ternary operator
result = condition ? valueIfTrue : valueIfFalse;
 
// Switch statement (Java 14+)
switch (value) {
    case 1 -> "One";
    case 2 -> "Two";
    default -> "Other";
}

Common Patterns in Coding Problems

// Range checking
if (index >= 0 && index < array.length) {
    // safe to access
}
 
// Null checking
if (obj != null && obj.property != null) {
    // safe to use
}
 
// Multiple conditions
if (a > 0 && b > 0 && a + b < 100) {
    // all conditions must be true
}

Tips

  • Use && and || for short-circuit evaluation
  • Consider using Objects.equals() for null-safe comparisons
  • Use switch for multiple discrete values

Control Flow Statements

Loops

// For loop - when you know iteration count
for (int i = 0; i < n; i++) {
    // code
}
 
// Enhanced for loop - for collections/arrays
for (int element : array) {
    // code
}
 
// While loop - condition-based iteration
while (condition) {
    // code
}
 
// Do-while - execute at least once
do {
    // code
} while (condition);

Control Statements

// Break - exit loop
for (int i = 0; i < n; i++) {
    if (condition) break;
}
 
// Continue - skip current iteration
for (int i = 0; i < n; i++) {
    if (skipCondition) continue;
    // process
}
 
// Return - exit method
if (baseCase) return result;

Common Patterns

// Two pointers
int left = 0, right = array.length - 1;
while (left < right) {
    // process
    if (condition) left++;
    else right--;
}
 
// Sliding window
int left = 0;
for (int right = 0; right < array.length; right++) {
    // expand window
    while (windowInvalid) {
        // shrink window
        left++;
    }
}

String Handling

Essential String Methods

String str = "Hello World";
 
// Basic operations
str.length()                    // 11
str.charAt(0)                   // 'H'
str.substring(0, 5)             // "Hello"
str.indexOf('o')                // 4
str.lastIndexOf('o')            // 7
str.contains("World")           // true
str.startsWith("Hello")         // true
str.endsWith("World")           // true
 
// Case operations
str.toLowerCase()               // "hello world"
str.toUpperCase()               // "HELLO WORLD"
 
// Trimming and splitting
str.trim()                      // removes leading/trailing spaces
str.split(" ")                  // ["Hello", "World"]
str.replace("World", "Java")    // "Hello Java"
 
// Comparison
str.equals("Hello World")       // true (case-sensitive)
str.equalsIgnoreCase("hello world") // true
str.compareTo("Hello World")    // 0 (lexicographic comparison)

StringBuilder for Efficient String Building

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.insert(5, " Beautiful");
sb.delete(5, 15);
sb.reverse();
String result = sb.toString();

Common String Problem Patterns

// Palindrome check
boolean isPalindrome(String s) {
    int left = 0, right = s.length() - 1;
    while (left < right) {
        if (s.charAt(left++) != s.charAt(right--)) {
            return false;
        }
    }
    return true;
}
 
// Character frequency
Map<Character, Integer> getFrequency(String s) {
    Map<Character, Integer> freq = new HashMap<>();
    for (char c : s.toCharArray()) {
        freq.put(c, freq.getOrDefault(c, 0) + 1);
    }
    return freq;
}
 
// Anagram check
boolean areAnagrams(String s1, String s2) {
    if (s1.length() != s2.length()) return false;
    
    int[] count = new int[26];
    for (int i = 0; i < s1.length(); i++) {
        count[s1.charAt(i) - 'a']++;
        count[s2.charAt(i) - 'a']--;
    }
    
    for (int c : count) {
        if (c != 0) return false;
    }
    return true;
}

String Conversion Utilities

// String to primitives
int num = Integer.parseInt("123");
double d = Double.parseDouble("12.34");
boolean b = Boolean.parseBoolean("true");
 
// Primitives to String
String s1 = String.valueOf(123);
String s2 = Integer.toString(123);
 
// Character utilities
Character.isDigit('5')          // true
Character.isLetter('a')         // true
Character.isAlphaNumeric('a')   // true
Character.toLowerCase('A')      // 'a'

Arrays

Array Basics

// Declaration and initialization
int[] arr = new int[5];                    // [0,0,0,0,0]
int[] arr2 = {1, 2, 3, 4, 5};            // initialized array
int[] arr3 = new int[]{1, 2, 3, 4, 5};   // explicit initialization
 
// Common operations
arr.length                                // array size
arr[0] = 10;                             // assignment
int first = arr[0];                      // access
 
// 2D arrays
int[][] matrix = new int[3][4];          // 3x4 matrix
int[][] matrix2 = {{1,2},{3,4}};        // initialized 2D array

Array Utility Methods

import java.util.Arrays;
 
int[] arr = {3, 1, 4, 1, 5};
 
// Sorting
Arrays.sort(arr);                        // [1,1,3,4,5]
 
// Searching (array must be sorted)
int index = Arrays.binarySearch(arr, 3); // returns index or -(insertion_point + 1)
 
// Comparison
Arrays.equals(arr1, arr2);               // true if arrays are equal
 
// Copying
int[] copy = Arrays.copyOf(arr, arr.length);
int[] partial = Arrays.copyOfRange(arr, 1, 4); // elements from index 1 to 3
 
// Filling
Arrays.fill(arr, 0);                     // fill entire array with 0
 
// String representation
Arrays.toString(arr);                    // "[1, 1, 3, 4, 5]"

Common Array Patterns

// Two Sum Problem
int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement)) {
            return new int[]{map.get(complement), i};
        }
        map.put(nums[i], i);
    }
    return new int[]{};
}
 
// Maximum Subarray (Kadane's Algorithm)
int maxSubArray(int[] nums) {
    int maxSoFar = nums[0];
    int maxEndingHere = nums[0];
    
    for (int i = 1; i < nums.length; i++) {
        maxEndingHere = Math.max(nums[i], maxEndingHere + nums[i]);
        maxSoFar = Math.max(maxSoFar, maxEndingHere);
    }
    return maxSoFar;
}
 
// Remove Duplicates from Sorted Array
int removeDuplicates(int[] nums) {
    if (nums.length == 0) return 0;
    
    int slow = 0;
    for (int fast = 1; fast < nums.length; fast++) {
        if (nums[fast] != nums[slow]) {
            slow++;
            nums[slow] = nums[fast];
        }
    }
    return slow + 1;
}
 
// Rotate Array
void rotate(int[] nums, int k) {
    k %= nums.length;
    reverse(nums, 0, nums.length - 1);
    reverse(nums, 0, k - 1);
    reverse(nums, k, nums.length - 1);
}
 
void reverse(int[] nums, int start, int end) {
    while (start < end) {
        int temp = nums[start];
        nums[start] = nums[end];
        nums[end] = temp;
        start++;
        end--;
    }
}

Date and Time

Java 8+ Date/Time API

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
 
// Current date/time
LocalDate today = LocalDate.now();           // 2024-03-15
LocalTime now = LocalTime.now();             // 14:30:45.123
LocalDateTime dateTime = LocalDateTime.now(); // 2024-03-15T14:30:45.123
 
// Creating specific dates
LocalDate date = LocalDate.of(2024, 3, 15);
LocalTime time = LocalTime.of(14, 30, 45);
LocalDateTime dt = LocalDateTime.of(2024, 3, 15, 14, 30, 45);
 
// Parsing from strings
LocalDate parsed = LocalDate.parse("2024-03-15");
LocalDateTime parsedDT = LocalDateTime.parse("2024-03-15T14:30:45");
 
// Custom formatting
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String formatted = today.format(formatter);
LocalDate fromFormatted = LocalDate.parse("15/03/2024", formatter);

Common Operations

LocalDate date = LocalDate.now();
 
// Adding/Subtracting
LocalDate tomorrow = date.plusDays(1);
LocalDate nextWeek = date.plusWeeks(1);
LocalDate nextMonth = date.plusMonths(1);
LocalDate lastYear = date.minusYears(1);
 
// Getting components
int year = date.getYear();
Month month = date.getMonth();
int dayOfMonth = date.getDayOfMonth();
DayOfWeek dayOfWeek = date.getDayOfWeek();
 
// Comparisons
boolean isAfter = date1.isAfter(date2);
boolean isBefore = date1.isBefore(date2);
boolean isEqual = date1.isEqual(date2);
 
// Calculating differences
long daysBetween = ChronoUnit.DAYS.between(date1, date2);
long monthsBetween = ChronoUnit.MONTHS.between(date1, date2);

Legacy Date (if required)

import java.util.Date;
import java.util.Calendar;
import java.text.SimpleDateFormat;
 
// Current date
Date now = new Date();
 
// Formatting
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String formatted = sdf.format(now);
 
// Using Calendar
Calendar cal = Calendar.getInstance();
cal.set(2024, Calendar.MARCH, 15); // Month is 0-based
Date date = cal.getTime();

Common Date/Time Problems

// Check if year is leap year
boolean isLeapYear(int year) {
    return Year.of(year).isLeap();
}
 
// Get number of days in month
int daysInMonth(int year, int month) {
    return YearMonth.of(year, month).lengthOfMonth();
}
 
// Find day of week for a date
DayOfWeek findDayOfWeek(int year, int month, int day) {
    return LocalDate.of(year, month, day).getDayOfWeek();
}

Searching

// Basic linear search
int linearSearch(int[] arr, int target) {
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == target) {
            return i;
        }
    }
    return -1; // not found
}
// Iterative binary search
int binarySearch(int[] arr, int target) {
    int left = 0, right = arr.length - 1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2; // Prevents overflow
        
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1; // not found
}
 
// Recursive binary search
int binarySearchRecursive(int[] arr, int target, int left, int right) {
    if (left > right) return -1;
    
    int mid = left + (right - left) / 2;
    
    if (arr[mid] == target) return mid;
    else if (arr[mid] < target) return binarySearchRecursive(arr, target, mid + 1, right);
    else return binarySearchRecursive(arr, target, left, mid - 1);
}

Binary Search Variations

// Find first occurrence
int findFirst(int[] arr, int target) {
    int left = 0, right = arr.length - 1;
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] == target) {
            result = mid;
            right = mid - 1; // Continue searching in left half
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return result;
}
 
// Find last occurrence
int findLast(int[] arr, int target) {
    int left = 0, right = arr.length - 1;
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] == target) {
            result = mid;
            left = mid + 1; // Continue searching in right half
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return result;
}
 
// Search in rotated sorted array
int searchRotated(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (nums[mid] == target) return mid;
        
        // Left half is sorted
        if (nums[left] <= nums[mid]) {
            if (target >= nums[left] && target < nums[mid]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        // Right half is sorted
        else {
            if (target > nums[mid] && target <= nums[right]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
    }
    return -1;
}

Using Built-in Methods

import java.util.Arrays;
import java.util.Collections;
 
// Arrays.binarySearch (array must be sorted)
int[] arr = {1, 3, 5, 7, 9};
int index = Arrays.binarySearch(arr, 5); // returns 2
 
// Collections.binarySearch
List<Integer> list = Arrays.asList(1, 3, 5, 7, 9);
int index2 = Collections.binarySearch(list, 5); // returns 2

Sorting

Built-in Sorting

import java.util.Arrays;
import java.util.Collections;
 
// Array sorting
int[] arr = {3, 1, 4, 1, 5};
Arrays.sort(arr); // [1, 1, 3, 4, 5]
 
// Partial sorting
Arrays.sort(arr, 1, 4); // Sort elements from index 1 to 3
 
// Collection sorting
List<Integer> list = Arrays.asList(3, 1, 4, 1, 5);
Collections.sort(list); // [1, 1, 3, 4, 5]

Custom Sorting with Comparators

// Sort by custom criteria
String[] words = {"apple", "pie", "banana"};
 
// Sort by length
Arrays.sort(words, (a, b) -> a.length() - b.length());
// or
Arrays.sort(words, Comparator.comparing(String::length));
 
// Sort in reverse order
Arrays.sort(arr, Collections.reverseOrder());
 
// Multiple criteria sorting
Person[] people = {...};
Arrays.sort(people, Comparator
    .comparing(Person::getAge)
    .thenComparing(Person::getName));
 
// Custom object sorting
class Student {
    String name;
    int grade;
    
    // Constructor, getters, setters...
}
 
Student[] students = {...};
// Sort by grade (descending), then by name (ascending)
Arrays.sort(students, (s1, s2) -> {
    if (s1.grade != s2.grade) {
        return s2.grade - s1.grade; // descending
    }
    return s1.name.compareTo(s2.name); // ascending
});

Manual Sorting Algorithms

// Bubble Sort - O(n²)
void bubbleSort(int[] arr) {
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // swap
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
 
// Selection Sort - O(n²)
void selectionSort(int[] arr) {
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        int minIdx = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIdx]) {
                minIdx = j;
            }
        }
        // swap
        int temp = arr[minIdx];
        arr[minIdx] = arr[i];
        arr[i] = temp;
    }
}
 
// Insertion Sort - O(n²)
void insertionSort(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}
 
// Merge Sort - O(n log n)
void mergeSort(int[] arr, int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}
 
void merge(int[] arr, int left, int mid, int right) {
    int[] temp = new int[right - left + 1];
    int i = left, j = mid + 1, k = 0;
    
    while (i <= mid && j <= right) {
        if (arr[i] <= arr[j]) {
            temp[k++] = arr[i++];
        } else {
            temp[k++] = arr[j++];
        }
    }
    
    while (i <= mid) temp[k++] = arr[i++];
    while (j <= right) temp[k++] = arr[j++];
    
    System.arraycopy(temp, 0, arr, left, temp.length);
}
 
// Quick Sort - Average O(n log n)
void quickSort(int[] arr, int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}
 
int partition(int[] arr, int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    
    for (int j = low; j < high; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(arr, i, j);
        }
    }
    swap(arr, i + 1, high);
    return i + 1;
}
 
void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

Object-Oriented Programming

Classes and Objects

public class Student {
    // Instance variables (private for encapsulation)
    private String name;
    private int age;
    private double gpa;
    
    // Static variables (class-level)
    private static int totalStudents = 0;
    
    // Constructors
    public Student() {
        this("Unknown", 0, 0.0);
    }
    
    public Student(String name, int age, double gpa) {
        this.name = name;
        this.age = age;
        this.gpa = gpa;
        totalStudents++;
    }
    
    // Getter methods
    public String getName() { return name; }
    public int getAge() { return age; }
    public double getGpa() { return gpa; }
    
    // Setter methods
    public void setName(String name) { this.name = name; }
    public void setAge(int age) { 
        if (age >= 0) this.age = age; 
    }
    public void setGpa(double gpa) { 
        if (gpa >= 0.0 && gpa <= 4.0) this.gpa = gpa; 
    }
    
    // Instance methods
    public boolean isHonorStudent() {
        return gpa >= 3.5;
    }
    
    // Static methods
    public static int getTotalStudents() {
        return totalStudents;
    }
    
    // Override toString for string representation
    @Override
    public String toString() {
        return String.format("Student{name='%s', age=%d, gpa=%.2f}", name, age, gpa);
    }
    
    // Override equals for object comparison
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Student student = (Student) obj;
        return age == student.age && 
               Double.compare(student.gpa, gpa) == 0 && 
               Objects.equals(name, student.name);
    }
    
    // Override hashCode when equals is overridden
    @Override
    public int hashCode() {
        return Objects.hash(name, age, gpa);
    }
}

Inheritance

// Base class
public class Person {
    protected String name;
    protected int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void displayInfo() {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}
 
// Derived class
public class Employee extends Person {
    private double salary;
    private String department;
    
    public Employee(String name, int age, double salary, String department) {
        super(name, age); // Call parent constructor
        this.salary = salary;
        this.department = department;
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo(); // Call parent method
        System.out.println("Salary: " + salary + ", Department: " + department);
    }
    
    // Additional methods specific to Employee
    public double getAnnualSalary() {
        return salary * 12;
    }
}

Polymorphism and Interfaces

// Interface
interface Drawable {
    void draw(); // implicitly public abstract
    
    // Default method (Java 8+)
    default void print() {
        System.out.println("Printing...");
    }
    
    // Static method (Java 8+)
    static void info() {
        System.out.println("This is Drawable interface");
    }
}
 
// Abstract class
abstract class Shape implements Drawable {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Abstract method
    public abstract double getArea();
    
    // Concrete method
    public void setColor(String color) {
        this.color = color;
    }
}
 
// Concrete implementations
class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " circle");
    }
}
 
class Rectangle extends Shape {
    private double width, height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " rectangle");
    }
}

Common OOP Patterns in Coding Problems

// Singleton Pattern
class Singleton {
    private static Singleton instance;
    
    private Singleton() {} // Private constructor
    
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
 
// Builder Pattern
class Product {
    private String name;
    private double price;
    private String category;
    
    private Product(Builder builder) {
        this.name = builder.name;
        this.price = builder.price;
        this.category = builder.category;
    }
    
    public static class Builder {
        private String name;
        private double price;
        private String category;
        
        public Builder setName(String name) {
            this.name = name;
            return this;
        }
        
        public Builder setPrice(double price) {
            this.price = price;
            return this;
        }
        
        public Builder setCategory(String category) {
            this.category = category;
            return this;
        }
        
        public Product build() {
            return new Product(this);
        }
    }
}
 
// Usage: Product p = new Product.Builder().setName("Laptop").setPrice(999.99).build();

Collections Framework

List Interface

import java.util.*;
 
// ArrayList - Dynamic array, good for random access
List<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(0, 0); // Insert at index
arrayList.get(0);    // Access by index
arrayList.set(0, 10); // Update at index
arrayList.remove(0); // Remove by index
arrayList.remove(Integer.valueOf(2)); // Remove by value
 
// LinkedList - Good for frequent insertions/deletions
List<Integer> linkedList = new LinkedList<>();
linkedList.addFirst(1);
linkedList.addLast(3);
linkedList.add(1, 2);
 
// Vector - Synchronized version of ArrayList
List<Integer> vector = new Vector<>();
 
// Common List operations
Collections.sort(arrayList);
Collections.reverse(arrayList);
Collections.shuffle(arrayList);
int max = Collections.max(arrayList);
int min = Collections.min(arrayList);

Set Interface

// HashSet - No duplicates, no ordering
Set<String> hashSet = new HashSet<>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("apple"); // Won't be added again
 
// LinkedHashSet - Maintains insertion order
Set<String> linkedHashSet = new LinkedHashSet<>();
 
// TreeSet - Sorted order
Set<String> treeSet = new TreeSet<>();
treeSet.add("zebra");
treeSet.add("apple");
// Contains: [apple, zebra]
 
// Set operations
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5, 6));
 
// Union
Set<Integer> union = new HashSet<>(set1);
union.addAll(set2); // {1, 2, 3, 4, 5, 6}
 
// Intersection
Set<Integer> intersection = new HashSet<>(set1);
intersection.retainAll(set2); // {3, 4}
 
// Difference
Set<Integer> difference = new HashSet<>(set1);
difference.removeAll(set2); // {1, 2}

Map Interface

// HashMap - Key-value pairs, no ordering
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("apple", 5);
hashMap.put("banana", 3);
hashMap.put("orange", 7);
 
// Access operations
int apples = hashMap.get("apple"); // 5
int pears = hashMap.getOrDefault("pears", 0); // 0 (default value)
hashMap.putIfAbsent("grape", 10); // Only adds if key doesn't exist
 
// LinkedHashMap - Maintains insertion order
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
 
// TreeMap - Sorted by keys
Map<String, Integer> treeMap = new TreeMap<>();
 
// Common Map operations
hashMap.containsKey("apple");     // true
hashMap.containsValue(5);         // true
hashMap.keySet();                 // Set of all keys
hashMap.values();                 // Collection of all values
hashMap.entrySet();               // Set of key-value pairs
 
// Iterating over map
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
 
// Using forEach (Java 8+)
hashMap.forEach((key, value) -> System.out.println(key + ": " + value));

Queue Interface

// LinkedList as Queue
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);  // Add to rear
queue.offer(2);
queue.offer(3);
int front = queue.poll(); // Remove from front, returns 1
int peek = queue.peek();  // Look at front without removing, returns 2
 
// PriorityQueue - Min heap by default
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.offer(5);
minHeap.offer(2);
minHeap.offer(8);
int min = minHeap.poll(); // Returns 2
 
// Max heap
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
maxHeap.offer(5);
maxHeap.offer(2);
maxHeap.offer(8);
int max = maxHeap.poll(); // Returns 8
 
// Custom comparator for PriorityQueue
PriorityQueue<String> pq = new PriorityQueue<>((a, b) -> a.length() - b.length());

Stack

// Using Stack class (legacy, prefer Deque)
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
int top = stack.pop();  // Returns 3
int peek = stack.peek(); // Returns 2 (top element)
 
// Using Deque as Stack (recommended)
Deque<Integer> stack2 = new ArrayDeque<>();
stack2.push(1);
stack2.push(2);
int top2 = stack2.pop();

Deque (Double-ended Queue)

Deque<Integer> deque = new ArrayDeque<>();
 
// Add elements
deque.addFirst(1);  // Add to front
deque.addLast(2);   // Add to rear
deque.offerFirst(0); // Alternative to addFirst
deque.offerLast(3);  // Alternative to addLast
 
// Remove elements
int first = deque.removeFirst(); // Remove from front
int last = deque.removeLast();   // Remove from rear
int polledFirst = deque.pollFirst(); // Returns null if empty
int polledLast = deque.pollLast();   // Returns null if empty
 
// Peek elements
int peekFirst = deque.peekFirst();
int peekLast = deque.peekLast();

Common Collection Utility Methods

import java.util.Collections;
 
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5));
 
// Sorting and searching
Collections.sort(list);
Collections.reverse(list);
Collections.shuffle(list);
int index = Collections.binarySearch(list, 4);
 
// Min/Max
int min = Collections.min(list);
int max = Collections.max(list);
 
// Frequency
int freq = Collections.frequency(list, 1); // Count occurrences
 
// Fill and copy
Collections.fill(list, 0); // Fill with 0
List<Integer> copy = new ArrayList<>(Collections.nCopies(5, 10)); // [10,10,10,10,10]
 
// Synchronization
List<Integer> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
 
// Unmodifiable collections
List<Integer> readOnlyList = Collections.unmodifiableList(list);

Common Collection Problem Patterns

// Group Anagrams
Map<String, List<String>> groupAnagrams(String[] strs) {
    Map<String, List<String>> groups = new HashMap<>();
    
    for (String str : strs) {
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        String key = new String(chars);
        
        groups.computeIfAbsent(key, k -> new ArrayList<>()).add(str);
    }
    
    return groups;
}
 
// Top K Frequent Elements
List<Integer> topKFrequent(int[] nums, int k) {
    Map<Integer, Integer> count = new HashMap<>();
    for (int num : nums) {
        count.put(num, count.getOrDefault(num, 0) + 1);
    }
    
    PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>(
        (a, b) -> b.getValue() - a.getValue()
    );
    
    pq.addAll(count.entrySet());
    
    List<Integer> result = new ArrayList<>();
    for (int i = 0; i < k; i++) {
        result.add(pq.poll().getKey());
    }
    
    return result;
}
 
// Valid Parentheses
boolean isValid(String s) {
    Stack<Character> stack = new Stack<>();
    Map<Character, Character> mapping = new HashMap<>();
    mapping.put(')', '(');
    mapping.put('}', '{');
    mapping.put(']', '[');
    
    for (char c : s.toCharArray()) {
        if (mapping.containsKey(c)) {
            if (stack.isEmpty() || stack.pop() != mapping.get(c)) {
                return false;
            }
        } else {
            stack.push(c);
        }
    }
    
    return stack.isEmpty();
}

Functional Programming

Lambda Expressions

// Basic lambda syntax: (parameters) -> expression/statement block
Runnable r = () -> System.out.println("Hello World");
 
// Single parameter (parentheses optional)
Function<String, Integer> length = s -> s.length();
Function<String, Integer> length2 = (s) -> s.length();
 
// Multiple parameters
BinaryOperator<Integer> add = (a, b) -> a + b;
 
// Block body
Predicate<String> startsWithA = s -> {
    return s.startsWith("A");
};
 
// Method references
List<String> words = Arrays.asList("apple", "banana", "cherry");
words.forEach(System.out::println); // Method reference
words.sort(String::compareToIgnoreCase); // Method reference

Functional Interfaces

import java.util.function.*;
 
// Predicate<T> - takes T, returns boolean
Predicate<String> isEmpty = String::isEmpty;
Predicate<Integer> isEven = n -> n % 2 == 0;
 
// Function<T, R> - takes T, returns R
Function<String, Integer> strLength = String::length;
Function<Integer, String> intToStr = Object::toString;
 
// Consumer<T> - takes T, returns nothing
Consumer<String> print = System.out::println;
 
// Supplier<T> - takes nothing, returns T
Supplier<String> hello = () -> "Hello World";
 
// BinaryOperator<T> - takes two T, returns T
BinaryOperator<Integer> multiply = (a, b) -> a * b;
 
// UnaryOperator<T> - takes T, returns T
UnaryOperator<String> toUpper = String::toUpperCase;
 
// BiPredicate<T, U> - takes T and U, returns boolean
BiPredicate<String, String> equals = String::equals;
 
// Custom functional interface
@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);
}
 
MathOperation addition = (a, b) -> a + b;
MathOperation subtraction = (a, b) -> a - b;

Streams API

import java.util.stream.*;
 
List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
 
// Basic stream operations
words.stream()
     .filter(word -> word.length() > 5)    // Intermediate operation
     .map(String::toUpperCase)             // Intermediate operation
     .forEach(System.out::println);        // Terminal operation
 
// Collecting results
List<String> filtered = words.stream()
                            .filter(word -> word.startsWith("a"))
                            .collect(Collectors.toList());
 
Set<Integer> lengths = words.stream()
                           .map(String::length)
                           .collect(Collectors.toSet());
 
// Numeric streams
IntStream.range(1, 10)           // 1 to 9
         .filter(n -> n % 2 == 0) // Even numbers
         .sum();                  // Sum them up
 
// Stream from array
int[] numbers = {1, 2, 3, 4, 5};
int sum = Arrays.stream(numbers).sum();
 
// Common stream operations
words.stream().count();                    // Count elements
words.stream().findFirst();                // Optional<String>
words.stream().anyMatch(s -> s.contains("a")); // boolean
words.stream().allMatch(s -> s.length() > 3);  // boolean
words.stream().noneMatch(String::isEmpty);      // boolean
 
// Sorting
List<String> sorted = words.stream()
                          .sorted()
                          .collect(Collectors.toList());
 
List<String> sortedByLength = words.stream()
                                  .sorted(Comparator.comparing(String::length))
                                  .collect(Collectors.toList());
 
// Grouping
Map<Integer, List<String>> grouped = words.stream()
    .collect(Collectors.groupingBy(String::length));
 
// Partitioning
Map<Boolean, List<String>> partitioned = words.stream()
    .collect(Collectors.partitioningBy(s -> s.length() > 5));
 
// Advanced operations
String joined = words.stream()
                    .collect(Collectors.joining(", "));
 
OptionalInt maxLength = words.stream()
                            .mapToInt(String::length)
                            .max();
 
// Reduce operations
Optional<String> longest = words.stream()
    .reduce((s1, s2) -> s1.length() > s2.length() ? s1 : s2);
 
int totalLength = words.stream()
    .map(String::length)
    .reduce(0, Integer::sum);
 
// FlatMap - flattening nested structures
List<List<String>> nestedList = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d", "e")
);
 
List<String> flattened = nestedList.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList());

Parallel Streams

// Convert to parallel stream
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
 
int sum = numbers.parallelStream()
                 .mapToInt(Integer::intValue)
                 .sum();
 
// Be careful with parallel streams:
// - Use for CPU-intensive operations
// - Ensure operations are stateless and associative
// - Consider overhead for small datasets
 
// Example: Parallel processing
List<String> results = words.parallelStream()
    .map(this::expensiveOperation) // CPU-intensive operation
    .collect(Collectors.toList());

Optional Class

// Creating Optionals
Optional<String> optional1 = Optional.of("Hello");        // Non-null value
Optional<String> optional2 = Optional.ofNullable(null);   // Possibly null
Optional<String> optional3 = Optional.empty();            // Empty optional
 
// Checking presence
if (optional1.isPresent()) {
    System.out.println(optional1.get());
}
 
// Better approach using ifPresent
optional1.ifPresent(System.out::println);
 
// Default values
String value = optional2.orElse("Default");
String value2 = optional2.orElseGet(() -> "Generated Default");
 
// Throwing exceptions
String value3 = optional2.orElseThrow(() -> new RuntimeException("Value not found"));
 
// Chaining operations
Optional<String> result = Optional.of("hello")
    .filter(s -> s.length() > 3)
    .map(String::toUpperCase)
    .flatMap(s -> Optional.of(s + " WORLD"));
 
// Common pattern in stream processing
List<String> validStrings = Arrays.asList("hello", null, "world", "", "java")
    .stream()
    .map(s -> Optional.ofNullable(s))
    .filter(opt -> opt.isPresent() && !opt.get().isEmpty())
    .map(Optional::get)
    .collect(Collectors.toList());

Common Functional Programming Patterns

// Filter-Map-Reduce pattern
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
 
int sumOfSquaresOfEvens = numbers.stream()
    .filter(n -> n % 2 == 0)           // Filter evens
    .map(n -> n * n)                   // Square them
    .reduce(0, Integer::sum);          // Sum them up
 
// Finding elements
Optional<String> firstLong = words.stream()
    .filter(s -> s.length() > 6)
    .findFirst();
 
// Converting collections
Map<String, Integer> wordLengths = words.stream()
    .collect(Collectors.toMap(
        Function.identity(),    // Key: the word itself
        String::length         // Value: word length
    ));
 
// Complex transformations
class Person {
    String name;
    int age;
    String city;
    
    // Constructor, getters, setters...
}
 
List<Person> people = Arrays.asList(/* ... */);
 
// Group people by city, then get average age per city
Map<String, Double> avgAgeByCity = people.stream()
    .collect(Collectors.groupingBy(
        Person::getCity,
        Collectors.averagingInt(Person::getAge)
    ));

Exception Handling

Try-Catch Basics

// Basic try-catch
try {
    int result = 10 / 0; // This will throw ArithmeticException
} catch (ArithmeticException e) {
    System.out.println("Cannot divide by zero: " + e.getMessage());
}
 
// Multiple catch blocks
try {
    String str = null;
    int length = str.length(); // NullPointerException
    int[] arr = new int[5];
    int value = arr[10];       // ArrayIndexOutOfBoundsException
} catch (NullPointerException e) {
    System.out.println("Null pointer error: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Array index error: " + e.getMessage());
} catch (Exception e) {
    System.out.println("General error: " + e.getMessage());
}
 
// Multi-catch (Java 7+)
try {
    // risky code
} catch (IOException | SQLException e) {
    System.out.println("IO or SQL error: " + e.getMessage());
}

Finally Block

FileInputStream file = null;
try {
    file = new FileInputStream("data.txt");
    // process file
} catch (IOException e) {
    System.out.println("File error: " + e.getMessage());
} finally {
    // This block always executes
    if (file != null) {
        try {
            file.close();
        } catch (IOException e) {
            System.out.println("Error closing file");
        }
    }
}

Try-with-Resources (Java 7+)

// Automatic resource management
try (FileInputStream file = new FileInputStream("data.txt");
     BufferedReader reader = new BufferedReader(new InputStreamReader(file))) {
    
    String line = reader.readLine();
    // process line
    
} catch (IOException e) {
    System.out.println("File error: " + e.getMessage());
}
// Resources are automatically closed
 
// Multiple resources
try (Scanner scanner = new Scanner(System.in);
     PrintWriter writer = new PrintWriter("output.txt")) {
    
    String input = scanner.nextLine();
    writer.println(input);
    
} catch (IOException e) {
    e.printStackTrace();
}

Custom Exceptions

// Custom checked exception
class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
    
    public InvalidAgeException(String message, Throwable cause) {
        super(message, cause);
    }
}
 
// Custom unchecked exception
class InsufficientFundsException extends RuntimeException {
    private double deficit;
    
    public InsufficientFundsException(double deficit) {
        super("Insufficient funds. Deficit: " + deficit);
        this.deficit = deficit;
    }
    
    public double getDeficit() {
        return deficit;
    }
}
 
// Using custom exceptions
public class BankAccount {
    private double balance;
    
    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException(amount - balance);
        }
        balance -= amount;
    }
    
    public void setAge(int age) throws InvalidAgeException {
        if (age < 0 || age > 150) {
            throw new InvalidAgeException("Age must be between 0 and 150: " + age);
        }
        // set age
    }
}

Exception Hierarchy and Common Exceptions

// Checked exceptions (must be handled)
try {
    Thread.sleep(1000);                    // InterruptedException
    Class.forName("NonExistentClass");     // ClassNotFoundException
    new FileInputStream("missing.txt");    // FileNotFoundException
} catch (InterruptedException | ClassNotFoundException | FileNotFoundException e) {
    e.printStackTrace();
}
 
// Unchecked exceptions (RuntimeException subclasses)
// NullPointerException
String str = null;
// int len = str.length(); // NPE
 
// ArrayIndexOutOfBoundsException
int[] arr = {1, 2, 3};
// int value = arr[5]; // AIOOBE
 
// NumberFormatException
// int num = Integer.parseInt("abc"); // NFE
 
// IllegalArgumentException
// Thread.sleep(-1000); // IAE

Best Practices and Patterns

// Don't catch and ignore
try {
    riskyOperation();
} catch (Exception e) {
    // BAD: Swallowing exception
}
 
// Better: Log and handle appropriately
try {
    riskyOperation();
} catch (SpecificException e) {
    logger.error("Operation failed", e);
    return defaultValue();
}
 
// Rethrowing with context
public void processFile(String filename) throws ProcessingException {
    try {
        // file processing
    } catch (IOException e) {
        throw new ProcessingException("Failed to process file: " + filename, e);
    }
}
 
// Validation pattern
public void setScore(int score) {
    if (score < 0 || score > 100) {
        throw new IllegalArgumentException("Score must be between 0 and 100: " + score);
    }
    this.score = score;
}
 
// Optional pattern for methods that might fail
public Optional<String> readFirstLine(String filename) {
    try (BufferedReader reader = Files.newBufferedReader(Paths.get(filename))) {
        return Optional.ofNullable(reader.readLine());
    } catch (IOException e) {
        logger.warn("Could not read file: " + filename, e);
        return Optional.empty();
    }
}
 
// Exception handling in streams
List<String> validNumbers = Arrays.asList("1", "2", "abc", "4", "xyz")
    .stream()
    .map(this::parseIntSafely)
    .filter(Optional::isPresent)
    .map(Optional::get)
    .map(String::valueOf)
    .collect(Collectors.toList());
 
private Optional<Integer> parseIntSafely(String str) {
    try {
        return Optional.of(Integer.parseInt(str));
    } catch (NumberFormatException e) {
        return Optional.empty();
    }
}

Quick Reference & Tips

Array and Collection Quick Operations

// Reverse array in-place
void reverseArray(int[] arr) {
    int left = 0, right = arr.length - 1;
    while (left < right) {
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
}
 
// Reverse list
Collections.reverse(list);
 
// Convert array to list
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// Note: This creates a fixed-size list
 
// Convert list to array
Integer[] array = list.toArray(new Integer[0]);
 
// Convert between primitive and wrapper arrays
int[] primitives = {1, 2, 3, 4, 5};
Integer[] wrappers = Arrays.stream(primitives).boxed().toArray(Integer[]::new);
int[] backToPrimitives = Arrays.stream(wrappers).mapToInt(Integer::intValue).toArray();

Sorting Shortcuts

// Sort array in descending order
Integer[] arr = {3, 1, 4, 1, 5};
Arrays.sort(arr, Collections.reverseOrder());
 
// Sort by multiple criteria
Person[] people = {...};
Arrays.sort(people, 
    Comparator.comparing(Person::getAge)
              .thenComparing(Person::getName));
 
// Custom sort for primitives (convert to Integer first)
int[] primitives = {3, 1, 4, 1, 5};
Integer[] wrappers = Arrays.stream(primitives).boxed().toArray(Integer[]::new);
Arrays.sort(wrappers, Collections.reverseOrder());
 
// Sort part of array
Arrays.sort(arr, 1, 4); // Sort elements from index 1 to 3

Mathematical Utilities

// Math class essentials
Math.abs(-5);           // 5
Math.max(3, 7);         // 7
Math.min(3, 7);         // 3
Math.pow(2, 3);         // 8.0
Math.sqrt(16);          // 4.0
Math.ceil(3.2);         // 4.0
Math.floor(3.8);        // 3.0
Math.round(3.6);        // 4
 
// Random numbers
Random rand = new Random();
int randomInt = rand.nextInt(10);        // 0-9
double randomDouble = rand.nextDouble(); // 0.0-1.0

String Processing Shortcuts

// Check if string is numeric
boolean isNumeric(String str) {
    try {
        Integer.parseInt(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}
 
// Count character occurrences
long count = str.chars().filter(ch -> ch == 'a').count();
 
// Remove all non-alphanumeric characters
String cleaned = str.replaceAll("[^a-zA-Z0-9]", "");
 
// Check if two strings are anagrams
boolean areAnagrams(String s1, String s2) {
    char[] arr1 = s1.toLowerCase().toCharArray();
    char[] arr2 = s2.toLowerCase().toCharArray();
    Arrays.sort(arr1);
    Arrays.sort(arr2);
    return Arrays.equals(arr1, arr2);
}

Common Coding Patterns

// Sliding window maximum
int[] maxSlidingWindow(int[] nums, int k) {
    Deque<Integer> deque = new ArrayDeque<>();
    List<Integer> result = new ArrayList<>();
    
    for (int i = 0; i < nums.length; i++) {
        // Remove elements outside window
        while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
            deque.pollFirst();
        }
        
        // Remove smaller elements
        while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
            deque.pollLast();
        }
        
        deque.offerLast(i);
        
        if (i >= k - 1) {
            result.add(nums[deque.peekFirst()]);
        }
    }
    
    return result.stream().mapToInt(i -> i).toArray();
}
 
// Find intersection of two arrays
int[] intersect(int[] nums1, int[] nums2) {
    Map<Integer, Integer> count = new HashMap<>();
    for (int num : nums1) {
        count.put(num, count.getOrDefault(num, 0) + 1);
    }
    
    List<Integer> result = new ArrayList<>();
    for (int num : nums2) {
        if (count.getOrDefault(num, 0) > 0) {
            result.add(num);
            count.put(num, count.get(num) - 1);
        }
    }
    
    return result.stream().mapToInt(i -> i).toArray();
}
 
// Check if array is sorted
boolean isSorted(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] < arr[i-1]) {
            return false;
        }
    }
    return true;
}

Input/Output Shortcuts

// Fast input reading
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String line = sc.nextLine();
String[] parts = line.split(" ");
 
// StringBuilder for output
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
    sb.append(i).append(" ");
}
System.out.println(sb.toString());