Skip to content

Latest commit

Β 

History

History
343 lines (285 loc) Β· 8.99 KB

File metadata and controls

343 lines (285 loc) Β· 8.99 KB

Java Stream API & Problem Solving - Quick Reference Cheatsheet

πŸš€ Essential Stream Operations

Basic Operations

// Filtering
stream.filter(x -> x > 5)
stream.filter(String::isEmpty)

// Mapping
stream.map(String::toUpperCase)
stream.mapToInt(String::length)
stream.mapToDouble(Employee::getSalary)

// Collecting
stream.collect(Collectors.toList())
stream.collect(Collectors.toSet())
stream.toList() // Java 16+

Aggregation Operations

// Numeric aggregations
stream.sum()
stream.average().orElse(0.0)
stream.max(Comparator.naturalOrder())
stream.min(Integer::compareTo)
stream.count()

// String joining
stream.collect(Collectors.joining(", "))
stream.collect(Collectors.joining(", ", "[", "]"))

πŸ“Š Grouping & Partitioning

Basic Grouping

// Group by single field
Map<String, List<Employee>> byDept = 
    employees.stream().collect(Collectors.groupingBy(Employee::getDept));

// Group with counting
Map<String, Long> countByDept = 
    employees.stream().collect(Collectors.groupingBy(Employee::getDept, Collectors.counting()));

// Group with sum/average
Map<String, Double> avgSalaryByDept = 
    employees.stream().collect(Collectors.groupingBy(Employee::getDept, 
        Collectors.averagingDouble(Employee::getSalary)));

Advanced Grouping

// Multi-level grouping
Map<String, Map<String, List<Employee>>> multiLevel = 
    employees.stream().collect(Collectors.groupingBy(Employee::getDept,
        Collectors.groupingBy(Employee::getLevel)));

// Partitioning (binary split)
Map<Boolean, List<Employee>> partitioned = 
    employees.stream().collect(Collectors.partitioningBy(emp -> emp.getAge() > 30));

πŸ” Finding & Matching

Finding Elements

// Find first/any
Optional<String> first = stream.findFirst();
Optional<String> any = stream.findAny();

// Top N elements
List<Employee> top3 = employees.stream()
    .sorted(Comparator.comparingDouble(Employee::getSalary).reversed())
    .limit(3)
    .toList();

// Second largest
Optional<Integer> secondLargest = numbers.stream()
    .distinct()
    .sorted(Comparator.reverseOrder())
    .skip(1)
    .findFirst();

Matching Operations

// Check all/any/none
boolean allPositive = numbers.stream().allMatch(n -> n > 0);
boolean anyNegative = numbers.stream().anyMatch(n -> n < 0);
boolean noneZero = numbers.stream().noneMatch(n -> n == 0);

πŸ“ String Processing Patterns

Character Analysis

// Character frequency
Map<Character, Long> charFreq = text.chars()
    .mapToObj(c -> (char) c)
    .filter(Character::isAlphabetic)
    .collect(Collectors.groupingBy(Character::toLowerCase, Collectors.counting()));

// Word operations
List<String> words = Arrays.stream(text.split("\\s+"))
    .filter(word -> word.length() > 3)
    .map(String::toLowerCase)
    .toList();

String Transformations

// Reverse strings
List<String> reversed = strings.stream()
    .map(s -> new StringBuilder(s).reverse().toString())
    .toList();

// Palindrome check
boolean isPalindrome = word.equals(new StringBuilder(word).reverse().toString());

πŸ”’ Numeric Operations

Mathematical Operations

// Sum of squares of even numbers
int sumSquares = numbers.stream()
    .filter(n -> n % 2 == 0)
    .mapToInt(n -> n * n)
    .sum();

// Moving average (window size k)
IntStream.range(0, list.size() - k + 1)
    .forEach(i -> {
        double avg = list.stream()
            .skip(i)
            .limit(k)
            .mapToDouble(Integer::doubleValue)
            .average()
            .orElse(0.0);
    });

Sorting & Ranking

// Sort by multiple criteria
employees.stream()
    .sorted(Comparator.comparing(Employee::getDept)
        .thenComparing(Employee::getSalary, Comparator.reverseOrder()))
    .toList();

// Custom sorting
numbers.stream()
    .sorted((a, b) -> Integer.compare(a.toString().length(), b.toString().length()))
    .toList();

πŸ—‚οΈ Collection Utilities

Duplicate Handling

// Find duplicates
List<String> duplicates = list.stream()
    .collect(Collectors.groupingBy(s -> s, Collectors.counting()))
    .entrySet().stream()
    .filter(entry -> entry.getValue() > 1)
    .map(Map.Entry::getKey)
    .toList();

// Remove duplicates preserving order
List<String> unique = list.stream()
    .distinct()
    .toList();

Map Processing

// Sort map by value
Map<String, Integer> sorted = map.entrySet().stream()
    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (e1, e2) -> e1,
        LinkedHashMap::new));

// Top N from map
List<String> topKeys = map.entrySet().stream()
    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
    .limit(3)
    .map(Map.Entry::getKey)
    .toList();

🎯 Common Problem Patterns

Pattern 1: Frequency Analysis

// Template for any frequency analysis
Map<T, Long> frequency = collection.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

Pattern 2: Group-Aggregate-Filter

// Template for group-aggregate-filter operations
Map<String, Double> result = items.stream()
    .collect(Collectors.groupingBy(Item::getCategory,
        Collectors.summingDouble(Item::getValue)))
    .entrySet().stream()
    .filter(entry -> entry.getValue() > threshold)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Pattern 3: Multi-step Transformation

// Template for complex transformations
List<Result> results = source.stream()
    .filter(predicate1)
    .map(transformation1)
    .filter(predicate2)
    .map(transformation2)
    .sorted(comparator)
    .limit(n)
    .toList();

πŸ’‘ Performance Tips

Efficiency Guidelines

// Use primitive streams for numbers
IntStream.range(0, 1000).sum(); // Better than Stream<Integer>

// Parallel streams for large datasets
largeList.parallelStream().filter(predicate).count();

// Avoid multiple terminal operations
List<String> result = stream.collect(Collectors.toList()); // Create once, use multiple times

Memory Optimization

// Use StringBuilder for string building
StringBuilder sb = new StringBuilder();
strings.forEach(sb::append);

// Lazy evaluation - streams don't execute until terminal operation
Stream<String> lazy = list.stream().filter(expensive_operation); // Not executed yet
List<String> result = lazy.toList(); // Now executed

πŸ› οΈ Utility Methods

Custom Collectors

// String compression utility
public static String compress(String input) {
    if (input == null || input.isEmpty()) return input;
    
    StringBuilder result = new StringBuilder();
    char current = input.charAt(0);
    int count = 1;
    
    for (int i = 1; i < input.length(); i++) {
        if (input.charAt(i) == current) {
            count++;
        } else {
            result.append(current).append(count);
            current = input.charAt(i);
            count = 1;
        }
    }
    result.append(current).append(count);
    return result.toString();
}

Method References Quick Guide

// Static method reference
Class::staticMethod

// Instance method reference
instance::instanceMethod

// Constructor reference
Class::new

// Instance method of particular type
String::length // equivalent to str -> str.length()

πŸ§ͺ Testing Patterns

Validation Helpers

// Null-safe operations
Optional.ofNullable(value)
    .filter(v -> v.length() > 0)
    .map(String::toUpperCase)
    .orElse("DEFAULT");

// Edge case handling
if (list == null || list.isEmpty()) {
    return Collections.emptyList();
}

Debug Helpers

// Peek for debugging
list.stream()
    .filter(x -> x > 0)
    .peek(System.out::println) // Debug output
    .map(x -> x * 2)
    .toList();

πŸ“š Common Problem Types & Solutions

Problem Type Key Operations Example
Find duplicates groupingBy + counting + filter Find duplicate employees
Top N elements sorted + limit Top 5 salaries
Group and sum groupingBy + summingDouble Total salary by department
String analysis chars() + groupingBy Character frequency
Data validation allMatch/anyMatch/noneMatch All positive numbers
Complex filtering Multi-level filter chains Active employees in IT dept
Data transformation map + flatMap Convert and flatten data
Statistical analysis average/min/max/count Employee statistics

🎨 Code Style Best Practices

  1. Use method references when possible: Employee::getName instead of e -> e.getName()
  2. Chain operations logically: filter β†’ map β†’ collect
  3. Handle optionals properly: Use orElse(), orElseThrow(), or ifPresent()
  4. Name variables clearly: employeesByDepartment instead of map
  5. Break complex chains into multiple steps for readability
  6. Use records for simple data classes (Java 14+)
  7. Prefer immutable collections when possible