Skip to main content

Java 8 Stream Practice Problems with Solutions

Category 1: filter() - Filtering Operationsโ€‹

1. Filter Even Numbersโ€‹

Given a list of integers, filter and return only even numbers.

public static List<Integer> filterEvenNumbers(List<Integer> numbers) {
return numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
}

2. Filter Strings by Lengthโ€‹

From a list of strings, filter strings that have length greater than 5.

public static List<String> filterStringsByLength(List<String> strings) {
return strings.stream()
.filter(s -> s.length() > 5)
.collect(Collectors.toList());
}

3. Filter Employees by Salaryโ€‹

Given a list of Employee objects, filter employees whose salary is greater than 50000.

public static List<Employee> filterEmployeesBySalary(List<Employee> employees) {
return employees.stream()
.filter(e -> e.getSalary() > 50000)
.collect(Collectors.toList());
}

4. Filter Null Valuesโ€‹

Remove all null values from a list of strings.

public static List<String> filterNullValues(List<String> strings) {
return strings.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
}

5. Filter by Multiple Conditionsโ€‹

From a list of products, filter products where price > 100 AND category equals "Electronics".

public static List<Product> filterByMultipleConditions(List<Product> products) {
return products.stream()
.filter(p -> p.getPrice() > 100 && "Electronics".equals(p.getCategory()))
.collect(Collectors.toList());
}

6. Filter Distinct Prime Numbersโ€‹

Filter prime numbers from a list and remove duplicates.

public static List<Integer> filterDistinctPrimeNumbers(List<Integer> numbers) {
return numbers.stream()
.filter(Java8StreamSolutions::isPrime)
.distinct()
.collect(Collectors.toList());
}

private static boolean isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) return false;
}
return true;
}

Category 2: map() - Transformation Operationsโ€‹

7. Convert to Uppercaseโ€‹

Convert all strings in a list to uppercase.

public static List<String> convertToUppercase(List<String> strings) {
return strings.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
}

8. Extract Propertyโ€‹

From a list of Employee objects, extract and return a list of all employee names.

public static List<String> extractEmployeeNames(List<Employee> employees) {
return employees.stream()
.map(Employee::getName)
.collect(Collectors.toList());
}

9. Square Numbersโ€‹

Given a list of integers, return a list with each number squared.

public static List<Integer> squareNumbers(List<Integer> numbers) {
return numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());
}

10. String to Lengthโ€‹

Convert a list of strings to a list of their lengths.

public static List<Integer> stringToLength(List<String> strings) {
return strings.stream()
.map(String::length)
.collect(Collectors.toList());
}

11. Object Transformationโ€‹

Convert a list of Employee objects to EmployeeDTO objects.

public static List<EmployeeDTO> transformToDTO(List<Employee> employees) {
return employees.stream()
.map(e -> new EmployeeDTO(e.getId(), e.getName(), e.getSalary()))
.collect(Collectors.toList());
}

12. Concatenate Prefixโ€‹

Add a prefix "Mr. " to all names in a list.

public static List<String> concatenatePrefix(List<String> names) {
return names.stream()
.map(name -> "Mr. " + name)
.collect(Collectors.toList());
}

Category 3: flatMap() - Flattening Operationsโ€‹

13. Flatten Nested Listsโ€‹

Given a list of lists of integers, flatten it to a single list.

public static List<Integer> flattenNestedLists(List<List<Integer>> nestedLists) {
return nestedLists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
}

14. Split and Flattenโ€‹

From a list of sentences, split each into words and return all words as a single list.

public static List<String> splitAndFlatten(List<String> sentences) {
return sentences.stream()
.flatMap(s -> Arrays.stream(s.split("\\s+")))
.collect(Collectors.toList());
}

15. Flatten Object Collectionsโ€‹

Given a list of Department objects (each containing a list of Employees), get all employees in a single list.

public static List<Employee> flattenDepartmentEmployees(List<Department> departments) {
return departments.stream()
.flatMap(d -> d.getEmployees().stream())
.collect(Collectors.toList());
}

16. Character Streamโ€‹

Convert a list of strings into a stream of all individual characters.

public static List<Character> getCharacterStream(List<String> strings) {
return strings.stream()
.flatMap(s -> s.chars().mapToObj(c -> (char) c))
.collect(Collectors.toList());
}

17. Flatten Optional Valuesโ€‹

Given a list of Optional<String>, flatten to get all present values.

public static List<String> flattenOptionals(List<Optional<String>> optionals) {
return optionals.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}

Category 4: distinct() - Removing Duplicatesโ€‹

18. Remove Duplicate Numbersโ€‹

From a list of integers with duplicates, return unique values.

public static List<Integer> removeDuplicateNumbers(List<Integer> numbers) {
return numbers.stream()
.distinct()
.collect(Collectors.toList());
}

19. Unique Employee IDsโ€‹

From a list of employees, get unique employee IDs.

public static List<Long> getUniqueEmployeeIds(List<Employee> employees) {
return employees.stream()
.map(Employee::getId)
.distinct()
.collect(Collectors.toList());
}

20. Case-Insensitive Unique Stringsโ€‹

Get unique strings ignoring case sensitivity.

public static List<String> caseInsensitiveUnique(List<String> strings) {
return strings.stream()
.map(String::toLowerCase)
.distinct()
.collect(Collectors.toList());
}

Category 5: sorted() - Sorting Operationsโ€‹

21. Sort Numbers Ascendingโ€‹

Sort a list of integers in ascending order.

public static List<Integer> sortNumbersAscending(List<Integer> numbers) {
return numbers.stream()
.sorted()
.collect(Collectors.toList());
}

22. Sort Strings Descendingโ€‹

Sort a list of strings in descending order.

public static List<String> sortStringsDescending(List<String> strings) {
return strings.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
}

23. Sort by Multiple Fieldsโ€‹

Sort employees first by department, then by salary within each department.

public static List<Employee> sortByMultipleFields(List<Employee> employees) {
return employees.stream()
.sorted(Comparator.comparing(Employee::getDepartment)
.thenComparing(Employee::getSalary))
.collect(Collectors.toList());
}

24. Sort by Custom Comparatorโ€‹

Sort products by price in descending order, then by name alphabetically.

public static List<Product> sortByCustomComparator(List<Product> products) {
return products.stream()
.sorted(Comparator.comparing(Product::getPrice).reversed()
.thenComparing(Product::getName))
.collect(Collectors.toList());
}

25. Sort with Null Handlingโ€‹

Sort a list of strings where some values might be null (nulls last).

public static List<String> sortWithNullHandling(List<String> strings) {
return strings.stream()
.sorted(Comparator.nullsLast(Comparator.naturalOrder()))
.collect(Collectors.toList());
}

Category 6: limit() & skip() - Pagination Operationsโ€‹

26. Get First N Elementsโ€‹

Return the first 5 elements from a list.

public static List<Integer> getFirstNElements(List<Integer> numbers) {
return numbers.stream()
.limit(5)
.collect(Collectors.toList());
}

27. Skip and Takeโ€‹

Skip first 10 elements and take next 5 elements.

public static List<Integer> skipAndTake(List<Integer> numbers) {
return numbers.stream()
.skip(10)
.limit(5)
.collect(Collectors.toList());
}

28. Top 3 Salariesโ€‹

Get the top 3 highest salaries from employee list.

public static List<Double> getTop3Salaries(List<Employee> employees) {
return employees.stream()
.map(Employee::getSalary)
.sorted(Comparator.reverseOrder())
.distinct()
.limit(3)
.collect(Collectors.toList());
}

29. Paginationโ€‹

Implement pagination - get page 3 with page size 10.

public static List<Employee> getPaginatedResults(List<Employee> employees, int page, int pageSize) {
return employees.stream()
.skip((long) (page - 1) * pageSize)
.limit(pageSize)
.collect(Collectors.toList());
}

Category 7: peek() - Debugging Operationsโ€‹

30. Debug Stream Pipelineโ€‹

Use peek() to print each element while processing.

public static List<Integer> debugStreamPipeline(List<Integer> numbers) {
return numbers.stream()
.peek(n -> System.out.println("Original: " + n))
.filter(n -> n % 2 == 0)
.peek(n -> System.out.println("After filter: " + n))
.map(n -> n * 2)
.peek(n -> System.out.println("After map: " + n))
.collect(Collectors.toList());
}

31. Logging Transformationโ€‹

Log each element before and after transformation.

public static List<String> loggingTransformation(List<String> strings) {
return strings.stream()
.peek(s -> System.out.println("Before: " + s))
.map(String::toUpperCase)
.peek(s -> System.out.println("After: " + s))
.collect(Collectors.toList());
}

Category 8: collect() - Collection Operationsโ€‹

32. Collect to Listโ€‹

Convert stream to ArrayList.

public static List<String> collectToList(Stream<String> stream) {
return stream.collect(Collectors.toCollection(ArrayList::new));
}

33. Collect to Setโ€‹

Convert stream to HashSet to remove duplicates.

public static Set<Integer> collectToSet(List<Integer> numbers) {
return numbers.stream()
.collect(Collectors.toCollection(HashSet::new));
}

34. Collect to Mapโ€‹

Convert list of employees to a Map with employeeId as key.

public static Map<Long, Employee> collectToMap(List<Employee> employees) {
return employees.stream()
.collect(Collectors.toMap(Employee::getId, e -> e));
}

35. Joining Stringsโ€‹

Join all strings in a list with comma separator.

public static String joiningStrings(List<String> strings) {
return strings.stream()
.collect(Collectors.joining(", "));
}

36. Partitioningโ€‹

Partition employees into two groups: salary > 50000 and salary <= 50000.

public static Map<Boolean, List<Employee>> partitionEmployees(List<Employee> employees) {
return employees.stream()
.collect(Collectors.partitioningBy(e -> e.getSalary() > 50000));
}

37. Grouping by Propertyโ€‹

Group employees by their department.

public static Map<String, List<Employee>> groupByDepartment(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
}

38. Grouping with Countingโ€‹

Count number of employees in each department.

public static Map<String, Long> groupAndCount(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()));
}

39. Grouping with Sumโ€‹

Calculate total salary by department.

public static Map<String, Double> groupAndSum(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.summingDouble(Employee::getSalary)));
}

40. Multi-level Groupingโ€‹

Group employees by department, then by city within each department.

public static Map<String, Map<String, List<Employee>>> multiLevelGrouping(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.groupingBy(Employee::getCity)));
}

Category 9: reduce() - Reduction Operationsโ€‹

41. Sum of Numbersโ€‹

Calculate sum of all integers in a list using reduce.

public static int sumOfNumbers(List<Integer> numbers) {
return numbers.stream()
.reduce(0, Integer::sum);
}

42. Product of Numbersโ€‹

Calculate product of all numbers.

public static int productOfNumbers(List<Integer> numbers) {
return numbers.stream()
.reduce(1, (a, b) -> a * b);
}

43. Concatenate Stringsโ€‹

Concatenate all strings using reduce.

public static String concatenateStrings(List<String> strings) {
return strings.stream()
.reduce("", (a, b) -> a + b);
}

44. Find Maximumโ€‹

Find maximum number using reduce.

public static Optional<Integer> findMaximum(List<Integer> numbers) {
return numbers.stream()
.reduce(Integer::max);
}

45. Find Minimum Salaryโ€‹

Find employee with minimum salary using reduce.

public static Optional<Employee> findMinimumSalary(List<Employee> employees) {
return employees.stream()
.reduce((e1, e2) -> e1.getSalary() < e2.getSalary() ? e1 : e2);
}

46. Complex Reductionโ€‹

Calculate total price of products after applying 10% discount.

public static double calculateTotalWithDiscount(List<Product> products) {
return products.stream()
.map(p -> p.getPrice() * 0.9)
.reduce(0.0, Double::sum);
}

Category 10: count() - Counting Operationsโ€‹

47. Count Elementsโ€‹

Count total number of elements in a stream.

public static long countElements(List<String> strings) {
return strings.stream()
.count();
}

48. Count After Filterโ€‹

Count how many employees have salary > 50000.

public static long countAfterFilter(List<Employee> employees) {
return employees.stream()
.filter(e -> e.getSalary() > 50000)
.count();
}

49. Count Distinct Valuesโ€‹

Count unique values in a list.

public static long countDistinctValues(List<Integer> numbers) {
return numbers.stream()
.distinct()
.count();
}

Category 11: anyMatch(), allMatch(), noneMatch()โ€‹

50. Any Matchโ€‹

Check if any employee has salary > 100000.

public static boolean anyMatchSalary(List<Employee> employees) {
return employees.stream()
.anyMatch(e -> e.getSalary() > 100000);
}

51. All Matchโ€‹

Check if all products have price > 0.

public static boolean allMatchPrice(List<Product> products) {
return products.stream()
.allMatch(p -> p.getPrice() > 0);
}

52. None Matchโ€‹

Check if no employee is below 18 years old.

public static boolean noneMatchAge(List<Employee> employees) {
return employees.stream()
.noneMatch(e -> e.getAge() < 18);
}

53. Multiple Conditionsโ€‹

Check if any string starts with "A" and has length > 5.

public static boolean multipleConditionsMatch(List<String> strings) {
return strings.stream()
.anyMatch(s -> s.startsWith("A") && s.length() > 5);
}

Category 12: findFirst() & findAny()โ€‹

54. Find First Elementโ€‹

Get the first element from a stream.

public static Optional<String> findFirstElement(List<String> strings) {
return strings.stream()
.findFirst();
}

55. Find First After Filterโ€‹

Find first employee with salary > 50000.

public static Optional<Employee> findFirstAfterFilter(List<Employee> employees) {
return employees.stream()
.filter(e -> e.getSalary() > 50000)
.findFirst();
}

56. Find Any in Parallelโ€‹

Use findAny() in parallel stream.

public static Optional<Integer> findAnyInParallel(List<Integer> numbers) {
return numbers.parallelStream()
.filter(n -> n > 100)
.findAny();
}

57. Find First Even Numberโ€‹

Find first even number greater than 100.

public static Optional<Integer> findFirstEven(List<Integer> numbers) {
return numbers.stream()
.filter(n -> n > 100 && n % 2 == 0)
.findFirst();
}

Category 13: min() & max()โ€‹

58. Find Maximum Salaryโ€‹

Find employee with maximum salary.

public static Optional<Employee> findMaxSalary(List<Employee> employees) {
return employees.stream()
.max(Comparator.comparing(Employee::getSalary));
}

59. Find Minimum Length Stringโ€‹

Find shortest string in a list.

public static Optional<String> findMinLength(List<String> strings) {
return strings.stream()
.min(Comparator.comparing(String::length));
}

60. Find Max Using Custom Comparatorโ€‹

Find oldest employee by date of birth.

public static Optional<Employee> findOldestEmployee(List<Employee> employees) {
return employees.stream()
.min(Comparator.comparing(Employee::getDateOfBirth));
}

Category 14: forEach() & forEachOrdered()โ€‹

61. Print All Elementsโ€‹

Print each element in the stream.

public static void printAllElements(List<String> strings) {
strings.stream()
.forEach(System.out::println);
}

62. Update Stateโ€‹

Increase salary of all employees by 10% (use forEach).

public static void increaseSalary(List<Employee> employees) {
employees.forEach(e -> e.setSalary(e.getSalary() * 1.1));
}

63. Ordered Processingโ€‹

Ensure elements are processed in order using forEachOrdered.

public static void orderedProcessing(List<Integer> numbers) {
numbers.parallelStream()
.forEachOrdered(System.out::println);
}

Category 15: toArray()โ€‹

64. Convert to Arrayโ€‹

Convert stream of strings to String array.

public static String[] convertToArray(List<String> strings) {
return strings.stream()
.toArray(String[]::new);
}

65. Convert to Integer Arrayโ€‹

Convert list to Integer[] array.

public static Integer[] convertToIntegerArray(List<Integer> numbers) {
return numbers.stream()
.toArray(Integer[]::new);
}

Category 16: Numeric Stream Operationsโ€‹

66. Sum Using IntStreamโ€‹

Calculate sum using IntStream.sum().

public static int sumUsingIntStream(List<Integer> numbers) {
return numbers.stream()
.mapToInt(Integer::intValue)
.sum();
}

67. Average Calculationโ€‹

Calculate average of numbers using average().

public static OptionalDouble calculateAverage(List<Integer> numbers) {
return numbers.stream()
.mapToInt(Integer::intValue)
.average();
}

68. Range Generationโ€‹

Generate numbers from 1 to 100 using IntStream.range().

public static List<Integer> generateRange() {
return IntStream.rangeClosed(1, 100)
.boxed()
.collect(Collectors.toList());
}

69. Statisticsโ€‹

Get max, min, average, sum in one go using summaryStatistics().

public static IntSummaryStatistics getStatistics(List<Integer> numbers) {
return numbers.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
}

70. Map to Intโ€‹

Convert list of strings to IntStream of their lengths and find sum.

public static int sumOfLengths(List<String> strings) {
return strings.stream()
.mapToInt(String::length)
.sum();
}

Category 17: Parallel Streamsโ€‹

71. Parallel Processingโ€‹

Convert sequential stream to parallel and compare performance.

public static List<Integer> parallelProcessing(List<Integer> numbers) {
return numbers.parallelStream()
.map(n -> n * 2)
.collect(Collectors.toList());
}

72. Parallel Sumโ€‹

Calculate sum of large list using parallel stream.

public static int parallelSum(List<Integer> numbers) {
return numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();
}

73. Thread Safetyโ€‹

Demonstrate thread-safety issues with parallel streams.

public static List<Integer> threadSafetyDemo(List<Integer> numbers) {
// Thread-safe approach
return numbers.parallelStream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
}

Category 18: Optional Operationsโ€‹

74. Handle Empty Streamโ€‹

Use Optional to handle empty stream results.

public static String handleEmptyStream(List<String> strings) {
return strings.stream()
.findFirst()
.orElse("Default Value");
}

75. Optional with orElseโ€‹

Find employee by ID, return default if not found.

public static Employee findEmployeeById(List<Employee> employees, Long id) {
return employees.stream()
.filter(e -> e.getId().equals(id))
.findFirst()
.orElse(new Employee());
}

76. Optional Chainingโ€‹

Use Optional with map and flatMap.

public static Optional<String> optionalChaining(List<Employee> employees, Long id) {
return employees.stream()
.filter(e -> e.getId().equals(id))
.findFirst()
.map(Employee::getDepartment)
.map(String::toUpperCase);
}

Category 19: Collectors Advancedโ€‹

77. Collectors.toMap with Merge Functionโ€‹

Handle duplicate keys while collecting to map.

public static Map<String, Employee> toMapWithMerge(List<Employee> employees) {
return employees.stream()
.collect(Collectors.toMap(
Employee::getDepartment,
e -> e,
(e1, e2) -> e1.getSalary() > e2.getSalary() ? e1 : e2));
}

78. Downstream Collectorsโ€‹

Group by department and get max salary in each.

public static Map<String, Optional<Employee>> downstreamCollectors(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
}

79. Mapping Collectorโ€‹

Group employees by department and collect only their names.

public static Map<String, List<String>> mappingCollector(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.mapping(Employee::getName, Collectors.toList())));
}

80. Custom Collectorโ€‹

Create a custom collector to calculate median.

public static double calculateMedian(List<Integer> numbers) {
List<Integer> sorted = numbers.stream()
.sorted()
.collect(Collectors.toList());
int size = sorted.size();
if (size % 2 == 0) {
return (sorted.get(size / 2 - 1) + sorted.get(size / 2)) / 2.0;
} else {
return sorted.get(size / 2);
}
}

Category 20: Complex Real-World Problemsโ€‹

81. Second Highest Salaryโ€‹

Find second highest salary from employee list.

public static Optional<Double> secondHighestSalary(List<Employee> employees) {
return employees.stream()
.map(Employee::getSalary)
.distinct()
.sorted(Comparator.reverseOrder())
.skip(1)
.findFirst();
}

82. Most Frequent Elementโ€‹

Find the most frequently occurring element in a list.

public static Optional<Integer> mostFrequentElement(List<Integer> numbers) {
return numbers.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey);
}

83. Remove Duplicates Preserve Orderโ€‹

Remove duplicates while maintaining insertion order.

public static List<Integer> removeDuplicatesPreserveOrder(List<Integer> numbers) {
return numbers.stream()
.distinct()
.collect(Collectors.toList());
}

84. Anagram Groupingโ€‹

Group strings that are anagrams of each other.

public static Map<String, List<String>> groupAnagrams(List<String> strings) {
return strings.stream()
.collect(Collectors.groupingBy(s -> {
char[] chars = s.toCharArray();
Arrays.sort(chars);
return new String(chars);
}));
}

85. Duplicate Elementsโ€‹

Find all duplicate elements in a list.

public static List<Integer> findDuplicates(List<Integer> numbers) {
return numbers.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() > 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}

86. Nth Highest Elementโ€‹

Find nth highest salary (generic solution).

public static Optional<Double> nthHighestSalary(List<Employee> employees, int n) {
return employees.stream()
.map(Employee::getSalary)
.distinct()
.sorted(Comparator.reverseOrder())
.skip(n - 1)
.findFirst();
}

87. Merge Two Listsโ€‹

Merge two lists and remove duplicates.

public static List<Integer> mergeLists(List<Integer> list1, List<Integer> list2) {
return Stream.concat(list1.stream(), list2.stream())
.distinct()
.collect(Collectors.toList());
}

88. Department with Max Employeesโ€‹

Find department with maximum number of employees.

public static Optional<String> departmentWithMaxEmployees(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey);
}

89. String Frequency Mapโ€‹

Create a map of each string and its frequency count.

public static Map<String, Long> stringFrequencyMap(List<String> strings) {
return strings.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}

90. Employee with Longest Nameโ€‹

Find employee with the longest name in each department.

public static Map<String, Optional<Employee>> longestNameByDepartment(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.maxBy(Comparator.comparing(e -> e.getName().length()))));
}

91. Cumulative Sumโ€‹

Create a list of cumulative sums from original list.

public static List<Integer> cumulativeSum(List<Integer> numbers) {
return numbers.stream()
.collect(() -> new ArrayList<Integer>(),
(list, n) -> {
int sum = list.isEmpty() ? n : list.get(list.size() - 1) + n;
list.add(sum);
},
ArrayList::addAll);
}

92. Intersection of Listsโ€‹

Find common elements between two lists.

public static List<Integer> findIntersection(List<Integer> list1, List<Integer> list2) {
return list1.stream()
.filter(list2::contains)
.distinct()
.collect(Collectors.toList());
}

93. Partition and Transformโ€‹

Partition list into two groups and apply different transformations.

public static Map<Boolean, List<Integer>> partitionAndTransform(List<Integer> numbers) {
Map<Boolean, List<Integer>> partitioned = numbers.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));

// Transform even numbers (multiply by 2)
partitioned.put(true, partitioned.get(true).stream()
.map(n -> n * 2)
.collect(Collectors.toList()));

// Transform odd numbers (add 1)
partitioned.put(false, partitioned.get(false).stream()
.map(n -> n + 1)
.collect(Collectors.toList()));

return partitioned;
}

94. Reverse Each Wordโ€‹

Reverse each word in a sentence while maintaining word order.

public static String reverseEachWord(String sentence) {
return Arrays.stream(sentence.split("\\s+"))
.map(word -> new StringBuilder(word).reverse().toString())
.collect(Collectors.joining(" "));
}

95. Find Missing Numbersโ€‹

Find missing numbers in a sequence from 1 to N.

public static List<Integer> findMissingNumbers(List<Integer> numbers, int n) {
Set<Integer> numSet = new HashSet<>(numbers);
return IntStream.rangeClosed(1, n)
.filter(i -> !numSet.contains(i))
.boxed()
.collect(Collectors.toList());
}

96. Age Group Classificationโ€‹

Classify employees into age groups (18-30, 31-50, 51+).

public static Map<String, List<Employee>> classifyByAgeGroup(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(e -> {
int age = e.getAge();
if (age <= 30) return "18-30";
else if (age <= 50) return "31-50";
else return "51+";
}));
}

97. Calculate Percentileโ€‹

Calculate 90th percentile of salaries.

public static double calculate90thPercentile(List<Employee> employees) {
List<Double> sortedSalaries = employees.stream()
.map(Employee::getSalary)
.sorted()
.collect(Collectors.toList());

int index = (int) Math.ceil(0.90 * sortedSalaries.size()) - 1;
return sortedSalaries.get(index);
}

98. Rolling Averageโ€‹

Calculate rolling average of last 3 elements.

public static List<Double> rollingAverage(List<Integer> numbers, int windowSize) {
return IntStream.range(0, numbers.size())
.filter(i -> i >= windowSize - 1)
.mapToObj(i -> {
double sum = 0;
for (int j = 0; j < windowSize; j++) {
sum += numbers.get(i - j);
}
return sum / windowSize;
})
.collect(Collectors.toList());
}

99. Pair Sum Targetโ€‹

Find pairs of numbers that sum to a target value.

public static List<int[]> findPairsWithSum(List<Integer> numbers, int target) {
Set<Integer> seen = new HashSet<>();
return numbers.stream()
.filter(n -> {
int complement = target - n;
if (seen.contains(complement)) {
return true;
}
seen.add(n);
return false;
})
.map(n -> new int[]{target - n, n})
.collect(Collectors.toList());
}

100. Hierarchical Groupingโ€‹

Create hierarchical grouping: Country -> State -> City -> Employees.

public static Map<String, Map<String, Map<String, List<Employee>>>> hierarchicalGrouping(
List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
Employee::getCountry,
Collectors.groupingBy(
Employee::getState,
Collectors.groupingBy(Employee::getCity))));
}

Supporting Classesโ€‹

// Employee Class
class Employee {
private Long id;
private String name;
private double salary;
private String department;
private String city;
private String state;
private String country;
private int age;
private LocalDate dateOfBirth;

// Constructors
public Employee() {}

public Employee(Long id, String name, double salary, String department) {
this.id = id;
this.name = name;
this.salary = salary;
this.department = department;
}

// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

public String getName() { return name; }
public void setName(String name) { this.name = name; }

public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary = salary; }

public String getDepartment() { return department; }
public void setDepartment(String department) { this.department = department; }

public String getCity() { return city; }
public void setCity(String city) { this.city = city; }

public String getState() { return state; }
public void setState(String state) { this.state = state; }

public String getCountry() { return country; }
public void setCountry(String country) { this.country = country; }

public int getAge() { return age; }
public void setAge(int age) { this.age = age; }

public LocalDate getDateOfBirth() { return dateOfBirth; }
public void setDateOfBirth(LocalDate dateOfBirth) { this.dateOfBirth = dateOfBirth; }
}

// EmployeeDTO Class
class EmployeeDTO {
private Long id;
private String name;
private double salary;

public EmployeeDTO(Long id, String name, double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}

// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

public String getName() { return name; }
public void setName(String name) { this.name = name; }

public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary = salary; }
}

// Product Class
class Product {
private Long id;
private String name;
private double price;
private String category;

public Product() {}

public Product(Long id, String name, double price, String category) {
this.id = id;
this.name = name;
this.price = price;
this.category = category;
}

// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

public String getName() { return name; }
public void setName(String name) { this.name = name; }

public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }

public String getCategory() { return category; }
public void setCategory(String category) { this.category = category; }
}

// Department Class
class Department {
private Long id;
private String name;
private List<Employee> employees;

public Department() {
this.employees = new ArrayList<>();
}

public Department(Long id, String name, List<Employee> employees) {
this.id = id;
this.name = name;
this.employees = employees;
}

// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

public String getName() { return name; }
public void setName(String name) { this.name = name; }

public List<Employee> getEmployees() { return employees; }
public void setEmployees(List<Employee> employees) { this.employees = employees; }
}

Bonus: Interview Favorites Solutionsโ€‹

Find First Non-Repeated Characterโ€‹

public static Optional<Character> findFirstNonRepeatedChar(String str) {
Map<Character, Long> charCount = str.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(Function.identity(),
LinkedHashMap::new, Collectors.counting()));

return charCount.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(Map.Entry::getKey)
.findFirst();
}

Sort Map by Valuesโ€‹

public static Map<String, Integer> sortMapByValues(Map<String, Integer> map) {
return map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new));
}

Calculate Running Totalโ€‹

public static List<Integer> calculateRunningTotal(List<Integer> numbers) {
List<Integer> result = new ArrayList<>();
numbers.stream()
.reduce(0, (sum, n) -> {
int newSum = sum + n;
result.add(newSum);
return newSum;
});
return result;
}

Find Elements That Appear Onceโ€‹

public static List<Integer> findElementsAppearingOnce(List<Integer> numbers) {
return numbers.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}

Convert List to Map with Indexโ€‹

public static Map<Integer, String> listToMapWithIndex(List<String> list) {
return IntStream.range(0, list.size())
.boxed()
.collect(Collectors.toMap(
i -> i,
list::get));
}

Usage Examplesโ€‹

public class Main {
public static void main(String[] args) {
// Example 1: Filter Even Numbers
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = filterEvenNumbers(numbers);
System.out.println("Even numbers: " + evenNumbers);

// Example 2: Group Employees by Department
List<Employee> employees = Arrays.asList(
new Employee(1L, "John", 60000, "IT"),
new Employee(2L, "Jane", 75000, "HR"),
new Employee(3L, "Bob", 55000, "IT"),
new Employee(4L, "Alice", 80000, "HR")
);

Map<String, List<Employee>> groupedByDept = groupByDepartment(employees);
System.out.println("Employees by department: " + groupedByDept);

// Example 3: Second Highest Salary
Optional<Double> secondHighest = secondHighestSalary(employees);
secondHighest.ifPresent(salary ->
System.out.println("Second highest salary: " + salary));

// Example 4: Find Duplicates
List<Integer> numbersWithDuplicates = Arrays.asList(1, 2, 3, 2, 4, 5, 3, 6);
List<Integer> duplicates = findDuplicates(numbersWithDuplicates);
System.out.println("Duplicates: " + duplicates);

// Example 5: String Frequency
List<String> words = Arrays.asList("apple", "banana", "apple", "cherry", "banana");
Map<String, Long> frequency = stringFrequencyMap(words);
System.out.println("Word frequency: " + frequency);
}
}

Key Takeawaysโ€‹

  1. filter() - Use for filtering elements based on conditions
  2. map() - Use for transforming elements
  3. flatMap() - Use for flattening nested structures
  4. collect() - Terminal operation to gather results
  5. reduce() - For aggregation operations
  6. Collectors - Powerful utility for complex collection operations
  7. Optional - Handle null safely
  8. Parallel Streams - For performance with large datasets
  9. Method References - Clean and readable code
  10. Chaining - Combine multiple operations for complex logic

Performance Tipsโ€‹

  • Use parallel streams for large datasets (10,000+ elements)
  • Avoid unnecessary boxing/unboxing - use primitive streams when possible
  • Short-circuit operations (findFirst, anyMatch) can improve performance
  • Stateless operations are preferred for parallel processing
  • Consider memory overhead of intermediate collections
  • Use method references over lambdas when possible for better performance

Common Pitfalls to Avoidโ€‹

  1. Modifying source while streaming
  2. Using forEach for accumulation (use reduce or collect instead)
  3. Ignoring null values without filtering
  4. Not handling empty streams properly
  5. Overusing parallel streams for small datasets
  6. Creating unnecessary intermediate collections
  7. Using peek() for business logic (it's for debugging only)

Interview Tipsโ€‹

  • Always consider edge cases (empty lists, null values)
  • Explain time and space complexity
  • Mention alternatives (traditional loops vs streams)
  • Discuss when NOT to use streams (simple iterations, performance-critical code)
  • Be prepared to optimize your solution
  • Know the difference between intermediate and terminal operations
  • Understand lazy evaluation in streams