Java 8 Streams Interview Study Guide
Basic Stream Operations
Section titled “Basic Stream Operations”Find Even Numbers
Section titled “Find Even Numbers”List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7,8);
List<Integer> even = nums.stream() .filter(n -> n % 2 == 0) .toList();Output:
[2,4,6,8]Find Odd Numbers
Section titled “Find Odd Numbers”nums.stream() .filter(n -> n % 2 != 0) .toList();Square Each Number
Section titled “Square Each Number”nums.stream() .map(n -> n * n) .toList();Convert Names to Uppercase
Section titled “Convert Names to Uppercase”names.stream() .map(String::toUpperCase) .toList();Count Elements
Section titled “Count Elements”long count = nums.stream().count();Find Maximum / Minimum
Section titled “Find Maximum / Minimum”int max = nums.stream().max(Integer::compareTo).get();int min = nums.stream().min(Integer::compareTo).get();int sum = nums.stream().mapToInt(Integer::intValue).sum();Intermediate Problems
Section titled “Intermediate Problems”Find Duplicate Elements
Section titled “Find Duplicate Elements”Set<Integer> set = new HashSet<>();
List<Integer> duplicates = nums.stream() .filter(n -> !set.add(n)) .toList();Remove Duplicates
Section titled “Remove Duplicates”nums.stream().distinct().toList();Find First vs Find Any
Section titled “Find First vs Find Any”nums.stream().findFirst().get();nums.parallelStream().findAny().get();| Method | Behavior |
|---|---|
findFirst() |
Preserves encounter order |
findAny() |
Optimized for parallel streams |
Sorting
Section titled “Sorting”nums.stream().sorted().toList();
nums.stream() .sorted(Comparator.reverseOrder()) .toList();Top 3 Highest
Section titled “Top 3 Highest”nums.stream() .sorted(Comparator.reverseOrder()) .limit(3) .toList();Second Highest
Section titled “Second Highest”Integer secondHighest = nums.stream() .distinct() .sorted(Comparator.reverseOrder()) .skip(1) .findFirst() .get();Frequency Map
Section titled “Frequency Map”Map<Integer, Long> frequency = nums.stream() .collect(Collectors.groupingBy( Function.identity(), Collectors.counting()));Character Frequency
Section titled “Character Frequency”String str = "programming";
Map<Character, Long> result = str.chars() .mapToObj(c -> (char)c) .collect(Collectors.groupingBy( Function.identity(), Collectors.counting()));Employee Problems
Section titled “Employee Problems”class Employee{ int id; String name; String department; double salary;}Salary > 50000
Section titled “Salary > 50000”employees.stream() .filter(e -> e.getSalary() > 50000) .toList();Highest Paid Employee
Section titled “Highest Paid Employee”employees.stream() .max(Comparator.comparing(Employee::getSalary)) .get();Average Salary
Section titled “Average Salary”employees.stream() .collect(Collectors.averagingDouble(Employee::getSalary));Group by Department
Section titled “Group by Department”employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment));Count by Department
Section titled “Count by Department”employees.stream() .collect(Collectors.groupingBy( Employee::getDepartment, Collectors.counting()));Highest Salary Per Department
Section titled “Highest Salary Per Department”employees.stream() .collect(Collectors.groupingBy( Employee::getDepartment, Collectors.maxBy( Comparator.comparing(Employee::getSalary))));Second Highest Salary
Section titled “Second Highest Salary”employees.stream() .sorted(Comparator.comparing(Employee::getSalary).reversed()) .skip(1) .findFirst() .get();Advanced Stream Operations
Section titled “Advanced Stream Operations”Partitioning
Section titled “Partitioning”employees.stream() .collect(Collectors.partitioningBy( e -> e.getSalary() > 50000));Difference:
| Collector | Purpose |
|---|---|
groupingBy() |
Many groups |
partitioningBy() |
Only true / false |
flatMap
Section titled “flatMap”list.stream() .flatMap(List::stream) .toList();Longest String
Section titled “Longest String”names.stream() .max(Comparator.comparingInt(String::length)) .get();Join Strings
Section titled “Join Strings”names.stream() .collect(Collectors.joining(","));List to Map
Section titled “List to Map”employees.stream() .collect(Collectors.toMap( Employee::getId, Employee::getName));Important Interview Concepts
Section titled “Important Interview Concepts”map vs flatMap
Section titled “map vs flatMap”| map | flatMap |
|---|---|
| One input → one output | Many collections → one stream |
reduce vs collect
Section titled “reduce vs collect”int sum = nums.stream().reduce(0,Integer::sum);nums.stream().collect(Collectors.toList());Lazy Evaluation
Section titled “Lazy Evaluation”Intermediate operations:
- filter
- map
- sorted
Executed only after a terminal operation:
- collect
- count
- findFirst
Stream Reuse
Section titled “Stream Reuse”Stream<Integer> s = nums.stream();s.count();s.count(); // IllegalStateExceptionParallel Stream Risks
Section titled “Parallel Stream Risks”- Race conditions
- Thread contention
- Order not guaranteed
- Poor performance for small datasets
Real Interview Pattern: Latest 3 Products Per Category
Section titled “Real Interview Pattern: Latest 3 Products Per Category”class Product { private Long id; private String name; private String category; private LocalDateTime createdDate;}Solution
Section titled “Solution”Map<String, List<Product>> result = products.stream() .collect(Collectors.groupingBy( Product::getCategory, Collectors.collectingAndThen( Collectors.toList(), list -> list.stream() .sorted( Comparator.comparing( Product::getCreatedDate) .reversed()) .limit(3) .toList() ) ));Stream Processing Flow
Section titled “Stream Processing Flow”flowchart LR A[Products Stream] --> B[groupingBy Category] B --> C[Convert each group to List] C --> D[Sort by createdDate Desc] D --> E[Limit to 3] E --> F[Map Category -> Latest 3 Products]
collectingAndThen()
Section titled “collectingAndThen()”Collectors.collectingAndThen( Collectors.toList(), list -> list.size())Similar Senior-Level Problems
Section titled “Similar Senior-Level Problems”Top 2 Highest Paid Employees per Department
Section titled “Top 2 Highest Paid Employees per Department”employees.stream().collect(Collectors.groupingBy( Employee::getDepartment, Collectors.collectingAndThen( Collectors.toList(), list -> list.stream() .sorted( Comparator.comparing(Employee::getSalary) .reversed()) .limit(2) .toList() )));Latest Employee per Department
Section titled “Latest Employee per Department”employees.stream().collect(Collectors.groupingBy( Employee::getDepartment, Collectors.collectingAndThen( Collectors.maxBy( Comparator.comparing(Employee::getJoiningDate)), Optional::get )));Highest Salary Employee per Department
Section titled “Highest Salary Employee per Department”employees.stream().collect(Collectors.groupingBy( Employee::getDepartment, Collectors.collectingAndThen( Collectors.maxBy( Comparator.comparing(Employee::getSalary)), Optional::get )));Top 3 Transactions per Customer
Section titled “Top 3 Transactions per Customer”transactions.stream().collect(Collectors.groupingBy( Transaction::getCustomerId, Collectors.collectingAndThen( Collectors.toList(), list -> list.stream() .sorted( Comparator.comparing(Transaction::getAmount) .reversed()) .limit(3) .toList() )));Most Recent Order per Customer
Section titled “Most Recent Order per Customer”orders.stream().collect(Collectors.groupingBy( Order::getCustomerId, Collectors.collectingAndThen( Collectors.maxBy( Comparator.comparing(Order::getOrderDate)), Optional::get )));Advanced Practice Problems
Section titled “Advanced Practice Problems”- Department with highest average salary
- Most expensive product in each category
- Top 3 customers by purchase amount
- Group employees by department and sort by salary descending
- First non-repeated character
Recognizing Common Patterns
Section titled “Recognizing Common Patterns”| Problem | Pattern |
|---|---|
| Top N per group | groupingBy + sorted + limit |
| Highest/latest per group | groupingBy + maxBy |
| Aggregation | groupingBy + summing/averaging/counting |
| Duplicate detection | groupingBy + counting |
| Nested collections | flatMap |
| List to Map | toMap |
| Ranking | sorted + skip + findFirst |
Character Frequency: Insertion Order and Duplicates
Section titled “Character Frequency: Insertion Order and Duplicates”Preserve Insertion Order
Section titled “Preserve Insertion Order”Map<Character, Long> frequencyMap = str.chars() .mapToObj(c -> (char) c) .collect(Collectors.groupingBy( Function.identity(), LinkedHashMap::new, Collectors.counting()));Print Duplicate Characters
Section titled “Print Duplicate Characters”frequencyMap.entrySet() .stream() .filter(entry -> entry.getValue() > 1) .forEach(System.out::println);Output (for "programming"):
r=2g=2m=2Find Minimum and Maximum Value in an Array
Section titled “Find Minimum and Maximum Value in an Array”Input
int[] arr = {10, 5, 20, 8, 15};Using Streams
Section titled “Using Streams”int min = Arrays.stream(arr) .min() .orElseThrow();
int max = Arrays.stream(arr) .max() .orElseThrow();Using IntSummaryStatistics (Single Traversal)
Section titled “Using IntSummaryStatistics (Single Traversal)”IntSummaryStatistics stats = Arrays.stream(arr) .summaryStatistics();
System.out.println("Min: " + stats.getMin());System.out.println("Max: " + stats.getMax());Without Streams (Most Optimal)
Section titled “Without Streams (Most Optimal)”int min = arr[0];int max = arr[0];
for (int i = 1; i < arr.length; i++) { min = Math.min(min, arr[i]); max = Math.max(max, arr[i]);}Complexity Comparison
Section titled “Complexity Comparison”| Approach | Time | Space | Notes |
|---|---|---|---|
Streams (min() and max()) |
O(n) | O(1) | Two traversals |
summaryStatistics() |
O(n) | O(1) | Single traversal |
| Manual Loop | O(n) | O(1) | Most efficient |
Key Takeaways
Section titled “Key Takeaways”- Learn the reusable
groupingBy + collectingAndThenpattern for Top-N questions. - Use
maxByfor latest/highest record in each group. - Understand when to use
map,flatMap,reduce, andcollect. - Master sorting, grouping, aggregation, and ranking patterns.
- Practice real-world business problems rather than only basic Stream APIs.
- Prefer
IntSummaryStatisticsover separatemin()/max()calls when both are needed, since it computes them in a single traversal.