CODE WITH SIBIN

Solving Real Problems with Real Code


Top 25 Java 8 Stream Operations Interview Questions with Answers

1. What are Intermediate and Terminal Operations in Java Streams?

Answer:

  • Intermediate Operations (e.g., filter()map()sorted()) are lazy and return a new stream.
  • Terminal Operations (e.g., collect()forEach()reduce()) trigger processing and produce a result.

Example:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = numbers.stream()
    .filter(n -> n % 2 == 0)  // Intermediate
    .map(n -> n * 2)          // Intermediate
    .collect(Collectors.toList()); // Terminal
// Output: [4, 8]

2. Difference Between filter() and map()?

Answer:

  • filter() → Selects elements based on a condition (Predicate).
  • map() → Transforms each element (Function).

Example:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> lengths = names.stream()
    .filter(name -> name.length() > 3) // ["Alice", "Charlie"]
    .map(String::length)              // [5, 7]
    .collect(Collectors.toList());

3. What Does flatMap() Do?

Answer:

  • Flattens nested collections into a single stream.

Example:

List<List<String>> nestedList = Arrays.asList(
    Arrays.asList("A", "B"),
    Arrays.asList("C", "D")
);
List<String> flatList = nestedList.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList());
// Output: ["A", "B", "C", "D"]

4. How Does distinct() Work?

Answer:

  • Removes duplicates using equals().

Example:

List<Integer> nums = Arrays.asList(1, 2, 2, 3, 3, 3);
List<Integer> unique = nums.stream()
    .distinct()
    .collect(Collectors.toList());
// Output: [1, 2, 3]

5. Explain sorted() with Custom Comparator

Answer:

  • Sorts elements (natural order or custom Comparator).

Example:

List<String> names = Arrays.asList("Zack", "Anna", "Bob");
List<String> sorted = names.stream()
    .sorted(Comparator.reverseOrder())
    .collect(Collectors.toList());
// Output: ["Zack", "Bob", "Anna"]

6. What is peek() Used For?

Answer:

  • Debugging intermediate stream operations (does not modify elements).

Example:

List<Integer> nums = Arrays.asList(1, 2, 3);
List<Integer> result = nums.stream()
    .peek(n -> System.out.println("Before: " + n))
    .map(n -> n * 2)
    .peek(n -> System.out.println("After: " + n))
    .collect(Collectors.toList());

7. How Does limit() Work?

Answer:

  • Truncates the stream to a given size.

Example:

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> limited = nums.stream()
    .limit(3)
    .collect(Collectors.toList());
// Output: [1, 2, 3]

8. What is skip() in Streams?

Answer:

  • Skips the first n elements.

Example:

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skipped = nums.stream()
    .skip(2)
    .collect(Collectors.toList());
// Output: [3, 4, 5]

9. Terminal Operation: collect() vs toList() (Java 16+)

Answer:

  • collect(Collectors.toList()) (Java 8)
  • toList() (Java 16+, returns immutable list)

Example:

List<String> names = Arrays.asList("A", "B", "C");
List<String> list1 = names.stream().collect(Collectors.toList()); // Mutable
List<String> list2 = names.stream().toList(); // Immutable (Java 16+)

10. How Does reduce() Work?

Answer:

  • Combines elements into a single result.

Example:

List<Integer> nums = Arrays.asList(1, 2, 3, 4);
int sum = nums.stream()
    .reduce(0, (a, b) -> a + b);
// Output: 10

11. Terminal Operation: forEach() vs forEachOrdered()

Answer:

  • forEach() → Order not guaranteed in parallel streams.
  • forEachOrdered() → Maintains order.

Example:

List<Integer> nums = Arrays.asList(1, 2, 3);
nums.stream().parallel().forEach(System.out::println); // Random order
nums.stream().parallel().forEachOrdered(System.out::println); // 1, 2, 3

12. What is anyMatch()allMatch()noneMatch()?

Answer:

  • anyMatch() → At least one element matches.
  • allMatch() → All elements match.
  • noneMatch() → No elements match.

Example:

List<Integer> nums = Arrays.asList(1, 2, 3, 4);
boolean hasEven = nums.stream().anyMatch(n -> n % 2 == 0); // true
boolean allEven = nums.stream().allMatch(n -> n % 2 == 0); // false
boolean noneNegative = nums.stream().noneMatch(n -> n < 0); // true

13. Terminal Operation: count()

Answer:

  • Returns the number of elements.

Example:

long count = Stream.of(1, 2, 3, 4).count(); // 4

14. Terminal Operation: min() and max()

Answer:

  • Finds min/max using a Comparator.

Example:

Optional<Integer> min = Stream.of(5, 2, 8).min(Integer::compare); // 2
Optional<Integer> max = Stream.of(5, 2, 8).max(Integer::compare); // 8

15. Terminal Operation: findFirst() vs findAny()

Answer:

  • findFirst() → First element (order matters).
  • findAny() → Any element (faster in parallel).

Example:

Optional<Integer> first = Stream.of(1, 2, 3).findFirst(); // 1
Optional<Integer> any = Stream.of(1, 2, 3).parallel().findAny(); // Random

16. How to Convert Stream to Array?

Answer:

  • Using toArray().

Example:

String[] names = Stream.of("A", "B", "C").toArray(String[]::new);

17. Terminal Operation: joining() Collector

Answer:

  • Concatenates strings with optional delimiter.

Example:

String joined = Stream.of("A", "B", "C").collect(Collectors.joining(", "));
// Output: "A, B, C"

18. Terminal Operation: groupingBy() Collector

Answer:

  • Groups elements by a classifier.

Example:

Map<Integer, List<String>> grouped = Stream.of("A", "BB", "CC")
    .collect(Collectors.groupingBy(String::length));
// Output: {1=["A"], 2=["BB", "CC"]}

19. Terminal Operation: partitioningBy() Collector

Answer:

  • Splits into true/false partitions.

Example:

Map<Boolean, List<Integer>> partitioned = Stream.of(1, 2, 3, 4)
    .collect(Collectors.partitioningBy(n -> n % 2 == 0));
// Output: {false=[1, 3], true=[2, 4]}

20. Terminal Operation: summingInt()averagingDouble()

Answer:

  • Aggregates numeric values.

Example:

double avg = Stream.of(1, 2, 3)
    .collect(Collectors.averagingInt(n -> n)); // 2.0

21. What is Stream.concat()?

Answer:

  • Merges two streams.

Example:

Stream<String> s1 = Stream.of("A", "B");
Stream<String> s2 = Stream.of("C", "D");
Stream<String> merged = Stream.concat(s1, s2);
// Output: ["A", "B", "C", "D"]

22. How to Handle Null in Streams?

Answer:

  • Use filter(Objects::nonNull).

Example:

List<String> names = Arrays.asList("A", null, "B");
List<String> nonNull = names.stream()
    .filter(Objects::nonNull)
    .collect(Collectors.toList());
// Output: ["A", "B"]

23. What is Stream.iterate()?

Answer:

  • Generates infinite streams.

Example:

Stream.iterate(0, n -> n + 2)
    .limit(5)
    .forEach(System.out::println); // 0, 2, 4, 6, 8

24. What is Stream.generate()?

Answer:

  • Creates streams from a Supplier.

Example:

Stream.generate(() -> Math.random())
    .limit(3)
    .forEach(System.out::println); // Random numbers

25. How to Parallelize a Stream?

Answer:

  • Use .parallel() or parallelStream().

Example:

List<Integer> nums = Arrays.asList(1, 2, 3, 4);
int sum = nums.parallelStream()
    .reduce(0, Integer::sum);
// Output: 10 (processed in parallel)

Summary Table

OperationTypeExample
filter()Intermediate.filter(x -> x > 5)
map()Intermediate.map(String::length)
flatMap()Intermediate.flatMap(List::stream)
distinct()Intermediate.distinct()
sorted()Intermediate.sorted(Comparator.reverseOrder())
peek()Intermediate.peek(System.out::println)
limit()Intermediate.limit(3)
skip()Intermediate.skip(2)
collect()Terminal.collect(Collectors.toList())
reduce()Terminal.reduce(0, Integer::sum)
forEach()Terminal.forEach(System.out::println)
anyMatch()Terminal.anyMatch(x -> x > 5)

Key Takeaways

✅ Intermediate ops (filtermapsorted) are lazy.
✅ Terminal ops (collectreduceforEach) trigger processing.
✅ flatMap() flattens nested collections.
✅ reduce() combines elements into a single result.
✅ parallelStream() improves performance for large datasets.

Leave a Reply

Your email address will not be published. Required fields are marked *