Java interview questions on streams

Core Concepts

  1. What is a Stream?
    A sequence of elements that supports sequential or parallel operations. Streams do not store data; they operate on a source (e.g., collection) and support functional-style operations such as filter, map, and reduce.

  2. Stream vs. Collection

    • Collections store data, while streams process it on demand.
    • Streams are lazy, meaning operations execute only when a terminal operation is invoked.
  3. Intermediate vs. Terminal Operations

    • Intermediate operations: filter, map, sorted (return a new stream, lazy).
    • Terminal operations: collect, forEach, reduce (produce a result or side effect, eager).

Common Operations

  1. Filter vs. Map

    • filter(Predicate): Selects elements matching a condition.
    • map(Function): Transforms elements into another shape, such as extracting a field.
  2. Reduce
    Combines elements into a single result, such as the sum of numbers:

    int sum = numbers.stream().reduce(0, (a, b) -> a + b);
    
  3. FlatMap
    Flattens nested collections (e.g., List<List> to List):

    List<Integer> flatList = nestedList.stream().flatMap(List::stream).toList();
    

Advanced Concepts

  1. Parallel Streams

    • Allow processing to occur in multiple threads using parallelStream().
    • Thread safety: Ensure the lambda expression is stateless or non-interfering.
  2. Stateful vs. Stateless Operations

    • Stateless: filter, map (do not depend on other elements).
    • Stateful: distinct, sorted (must keep everything in memory).
  3. Short-Circuiting Operations
    These operations end processing early, such as findFirst, limit, and anyMatch.

Collectors

  1. Collectors.toList
    Collects the values of a stream into a list:

    List<String> names = people.stream().map(Person::getName).toList();
    
  2. GroupingBy
    Groups elements by a classifier, such as grouping people by age:

    Map<Integer, List<Person>> peopleByAge = people.stream()
        .collect(Collectors.groupingBy(Person::getAge));
    
  3. PartitioningBy
    Splits elements into two groups (true/false) based on a predicate:

    Map<Boolean, List<Person>> partitioned = people.stream()
        .collect(Collectors.partitioningBy(p -> p.getAge() >= 18));
    

Coding Problems

  1. Find distinct elements in a list:

    List<Integer> distinct = numbers.stream().distinct().toList();
    
  2. Sum all even numbers:

    int sum = numbers.stream().filter(n -> n % 2 == 0).mapToInt(n -> n).sum();
    
  3. Convert a list of strings to uppercase:

    List<String> upper = strings.stream().map(String::toUpperCase).toList();
    
  4. Find the longest string in a list:

    Optional<String> longest = strings.stream()
        .max(Comparator.comparingInt(String::length));
    
  5. Concatenate two streams:

    Stream<String> combined = Stream.concat(stream1, stream2);
    

Best Practices & Pitfalls

  1. Avoid Side Effects
    Stream operations should be stateless; avoid modifying external variables in lambdas.

  2. Primitive Streams
    Performance can be improved using IntStream, LongStream, or DoubleStream for primitive types.

  3. Reusing Streams
    Streams are one-time use only; create new ones if needed.

  4. ForEach vs. For-Loops
    Prefer forEach for clarity, but avoid it for complex mutations or state modifications.

Scenario-Based Interview programming Questions On Java Streams

  1. How to handle exceptions in streams?
    Wrap checked exceptions in a lambda with try-catch or use utility methods like Unchecked:

    List<String> result = files.stream().map(file -> { 
        try { 
            return readFile(file); 
        } catch (IOException e) { 
            throw new UncheckedIOException(e); 
        } 
    }).toList();
    
  2. When to use parallel streams?
    Use for large volumes of data and CPU-bound tasks but avoid for I/O operations or small datasets.

  3. Why does peek exist?
    Used for debugging/logging intermediate stream states, such as peek(System.out::println).

Advanced Coding Challenges

  1. Find the second-largest number in a list:

    OptionalInt secondLargest = numbers.stream()
        .distinct()
        .sorted()
        .skip(numbers.size() - 2)
        .findFirst();
    
  2. Merge two lists of objects into a map (ID → Object):

    Map<Integer, Person> idToPerson = people.stream()
        .collect(Collectors.toMap(Person::getId, Function.identity()));
    
  3. Count occurrences of every word in a list:

    Map<String, Long> wordCount = words.stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    

These questions cover fundamental programming concepts, best practices, and optimization strategies. Senior developers may also focus on parallel stream effectiveness and custom collectors.

Instance Of Java

We will help you in learning.Please leave your comments and suggestions in comment section. if you any doubts please use search box provided right side. Search there for answers thank you.
«
Next
Newer Post
»
Previous
Older Post

No comments

Leave a Reply

Select Menu