Chapter 23 Advanced 60 Questions

Practice Questions — Lambda Expressions and Streams API

← Back to Notes
8 Easy
10 Medium
7 Hard

Topic-Specific Questions

Question 1
Easy
What is the output?
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4));
System.out.println(isEven.test(7));
Predicate.test() returns a boolean.
true
false
Question 2
Easy
What is the output?
Function<String, Integer> len = s -> s.length();
System.out.println(len.apply("Hello"));
System.out.println(len.apply(""));
Function.apply() takes input and returns a result.
5
0
Question 3
Easy
What is the output?
List<Integer> nums = List.of(1, 2, 3, 4, 5);
long count = nums.stream().filter(n -> n > 3).count();
System.out.println(count);
filter keeps elements where the predicate returns true.
2
Question 4
Easy
What is the output?
List<String> names = List.of("arjun", "priya");
names.stream()
    .map(String::toUpperCase)
    .forEach(System.out::println);
map transforms each element. toUpperCase converts to uppercase.
ARJUN
PRIYA
Question 5
Easy
What is the output?
List<Integer> nums = List.of(3, 1, 4, 1, 5);
int sum = nums.stream().reduce(0, Integer::sum);
System.out.println(sum);
reduce combines all elements. 0 is the identity for addition.
14
Question 6
Medium
What is the output?
List<String> names = List.of("Arjun", "Priya", "Arjun", "Vikram", "Priya");
long count = names.stream().distinct().count();
System.out.println(count);
distinct() removes duplicate elements.
3
Question 7
Medium
What is the output?
List<Integer> nums = List.of(5, 3, 8, 1, 9, 2);
List<Integer> result = nums.stream()
    .sorted()
    .limit(3)
    .collect(Collectors.toList());
System.out.println(result);
sorted() sorts in natural order. limit(3) takes the first 3.
[1, 2, 3]
Question 8
Medium
What is the output?
List<String> words = List.of("Java", "is", "fun");
String result = words.stream()
    .collect(Collectors.joining(" "));
System.out.println(result);
joining() concatenates elements with the given delimiter.
Java is fun
Question 9
Medium
What is the output?
Optional<String> opt = Optional.of("Hello");
System.out.println(opt.isPresent());
System.out.println(opt.orElse("World"));

Optional<String> empty = Optional.empty();
System.out.println(empty.isPresent());
System.out.println(empty.orElse("World"));
orElse returns the contained value if present, otherwise the default.
true
Hello
false
World
Question 10
Medium
What is the output?
List<List<Integer>> nested = List.of(
    List.of(1, 2),
    List.of(3, 4),
    List.of(5)
);

List<Integer> flat = nested.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList());
System.out.println(flat);
flatMap flattens each inner list into a single stream.
[1, 2, 3, 4, 5]
Question 11
Hard
What is the output?
List<String> names = List.of("Arjun", "Priya", "Avi", "Sneha", "Arun");
Map<Character, List<String>> grouped = names.stream()
    .collect(Collectors.groupingBy(n -> n.charAt(0)));
System.out.println(grouped);
groupingBy groups elements by the first character.
{A=[Arjun, Avi, Arun], P=[Priya], S=[Sneha]}
Question 12
Hard
What is the output?
List<Integer> nums = List.of(1, 2, 3, 4, 5);
Optional<Integer> result = nums.stream()
    .filter(n -> n > 10)
    .findFirst();
System.out.println(result.isPresent());
System.out.println(result.orElse(-1));
No element is greater than 10.
false
-1
Question 13
Hard
What is the output?
List<Integer> nums = List.of(1, 2, 3, 4, 5);
boolean allEven = nums.stream().allMatch(n -> n % 2 == 0);
boolean anyEven = nums.stream().anyMatch(n -> n % 2 == 0);
boolean noneNeg = nums.stream().noneMatch(n -> n < 0);
System.out.println(allEven + " " + anyEven + " " + noneNeg);
allMatch: all must pass. anyMatch: at least one. noneMatch: none should pass.
false true true
Question 14
Medium
What is the difference between map() and flatMap() in streams?
Think about what happens when each element maps to a collection.
map() transforms each element into exactly one element (one-to-one). flatMap() transforms each element into zero or more elements by flattening nested streams (one-to-many). If you map a list of students to their courses and each student has multiple courses, map() gives a Stream<List<String>> while flatMap() gives a Stream<String>.
Question 15
Hard
What does it mean that streams are 'lazy'? How does this affect performance?
Think about when intermediate operations actually execute.
Intermediate operations (filter, map, sorted) are not executed when they are called. They are only executed when a terminal operation (collect, forEach, count) is invoked. This enables short-circuit optimization: with findFirst(), the stream processes elements one by one and stops as soon as a match is found, without processing the entire collection. Laziness also allows the JVM to optimize the pipeline by fusing operations.

Mixed & Application Questions

Question 1
Easy
What is the output?
Consumer<String> greet = name -> System.out.println("Hello, " + name);
greet.accept("Arjun");
Consumer.accept() takes an argument and returns nothing.
Hello, Arjun
Question 2
Easy
What is the output?
Supplier<String> greeting = () -> "Hello, World";
System.out.println(greeting.get());
Supplier.get() takes no arguments and returns a value.
Hello, World
Question 3
Medium
What is the output?
List<Integer> nums = List.of(10, 20, 30, 40, 50);
List<Integer> result = nums.stream()
    .skip(2)
    .limit(2)
    .collect(Collectors.toList());
System.out.println(result);
skip(2) skips the first two. limit(2) takes the next two.
[30, 40]
Question 4
Medium
What is the output?
List<String> names = List.of("Arjun", "Priya", "Vikram");
Map<String, Integer> map = names.stream()
    .collect(Collectors.toMap(n -> n, String::length));
System.out.println(map);
toMap takes a key function and a value function.
{Arjun=5, Priya=5, Vikram=6}
Question 5
Medium
What is the output?
Function<Integer, Integer> doubleIt = n -> n * 2;
Function<Integer, Integer> addThree = n -> n + 3;
Function<Integer, Integer> combined = doubleIt.andThen(addThree);
System.out.println(combined.apply(5));
andThen applies doubleIt first, then addThree to the result.
13
Question 6
Hard
What is the output?
List<String> names = List.of("Arjun", "Priya", "Sneha", "Vikram", "Kavya");
Map<Boolean, List<String>> partitioned = names.stream()
    .collect(Collectors.partitioningBy(n -> n.length() > 5));
System.out.println("Long: " + partitioned.get(true));
System.out.println("Short: " + partitioned.get(false));
partitioningBy splits into true and false groups based on the predicate.
Long: [Vikram]
Short: [Arjun, Priya, Sneha, Kavya]
Question 7
Hard
What is the output?
List<Integer> nums = List.of(1, 2, 3, 4, 5);
String result = nums.stream()
    .map(n -> n * n)
    .map(String::valueOf)
    .collect(Collectors.joining(", "));
System.out.println(result);
First map squares the number. Second map converts to String. joining concatenates.
1, 4, 9, 16, 25
Question 8
Hard
What is the output?
List<Integer> nums = List.of(5, 3, 8, 1, 9, 2, 7);
Optional<Integer> secondLargest = nums.stream()
    .sorted(Comparator.reverseOrder())
    .skip(1)
    .findFirst();
System.out.println(secondLargest.orElse(-1));
Sort in descending order, skip the first (largest), take the next.
8
Question 9
Easy
What is a functional interface in Java?
Think about how many abstract methods it has.
A functional interface is an interface with exactly one abstract method (SAM - Single Abstract Method). It can have any number of default and static methods. The @FunctionalInterface annotation enforces this constraint. Lambda expressions can only be assigned to functional interface types. Examples: Runnable, Predicate, Function, Consumer, Supplier.
Question 10
Medium
What is the difference between stream() and parallelStream()?
Think about how elements are processed.
stream() processes elements sequentially on a single thread. parallelStream() splits the data into chunks and processes them concurrently using the ForkJoinPool. Parallel streams can improve performance for CPU-intensive operations on large datasets, but they add overhead and can cause issues with non-thread-safe operations or shared mutable state.

Multiple Choice Questions

MCQ 1
What is a lambda expression in Java?
  • A. A new data type
  • B. A concise way to represent an anonymous function
  • C. A loop structure
  • D. A design pattern
Answer: B
B is correct. A lambda expression is a short way to define a function without a name. It was introduced in Java 8 and is used with functional interfaces.
MCQ 2
Which functional interface takes an argument and returns a boolean?
  • A. Function<T,R>
  • B. Consumer<T>
  • C. Predicate<T>
  • D. Supplier<T>
Answer: C
C is correct. Predicate<T> has a test(T t) method that returns boolean. Function returns R, Consumer returns void, Supplier takes no argument.
MCQ 3
What does stream().filter() do?
  • A. Removes all elements
  • B. Keeps elements that match the given predicate
  • C. Transforms each element
  • D. Sorts the elements
Answer: B
B is correct. filter() takes a Predicate and returns a stream containing only the elements for which the predicate returns true.
MCQ 4
What is String::toUpperCase an example of?
  • A. Static method call
  • B. Lambda expression
  • C. Method reference
  • D. Constructor call
Answer: C
C is correct. String::toUpperCase is a method reference -- shorthand for s -> s.toUpperCase(). It references the toUpperCase instance method of the String class.
MCQ 5
What type of operation is forEach() in streams?
  • A. Intermediate operation
  • B. Terminal operation
  • C. Source operation
  • D. Lazy operation
Answer: B
B is correct. forEach() is a terminal operation that triggers the stream pipeline and consumes the stream. After forEach, the stream cannot be reused.
MCQ 6
What does Collectors.groupingBy() return?
  • A. List<T>
  • B. Set<T>
  • C. Map<K, List<T>>
  • D. Optional<T>
Answer: C
C is correct. groupingBy() groups stream elements by a classifier function and returns a Map where keys are the group values and values are Lists of elements in each group.
MCQ 7
What does Optional.orElse(defaultValue) do?
  • A. Always returns the default value
  • B. Returns the contained value if present, otherwise returns defaultValue
  • C. Throws an exception if the value is present
  • D. Sets the contained value to defaultValue
Answer: B
B is correct. orElse() returns the wrapped value if present, or the provided default value if the Optional is empty.
MCQ 8
Why are streams considered lazy?
  • A. They run on background threads
  • B. Intermediate operations are not executed until a terminal operation is called
  • C. They process elements slowly
  • D. They always use parallel processing
Answer: B
B is correct. Intermediate operations (filter, map, sorted) just build a pipeline. They execute only when a terminal operation (collect, forEach, count) triggers the pipeline.
MCQ 9
What does flatMap do in streams?
  • A. Filters and maps simultaneously
  • B. Maps each element to a stream and flattens them into a single stream
  • C. Creates a flat data structure
  • D. Maps elements in parallel
Answer: B
B is correct. flatMap maps each element to a stream and then flattens all resulting streams into one. It is used when each element maps to multiple values.
MCQ 10
Which is NOT an intermediate stream operation?
  • A. filter()
  • B. map()
  • C. collect()
  • D. sorted()
Answer: C
C is correct. collect() is a terminal operation that triggers the pipeline and gathers results. filter, map, and sorted are intermediate operations.
MCQ 11
What is the difference between Predicate.and() and Predicate.or()?
  • A. and() combines predicates with logical AND; or() combines with logical OR
  • B. They are identical
  • C. and() is for numbers; or() is for strings
  • D. and() creates a new predicate; or() modifies the existing one
Answer: A
A is correct. and() returns a composed Predicate that is true only if both predicates are true. or() returns true if either predicate is true. Both return new Predicate instances.
MCQ 12
What happens if you call Optional.of(null)?
  • A. Returns an empty Optional
  • B. Returns an Optional containing null
  • C. Throws NullPointerException
  • D. Returns null
Answer: C
C is correct. Optional.of(null) throws NullPointerException. Use Optional.ofNullable(null) if the value might be null -- it returns an empty Optional for null.
MCQ 13
What does reduce(identity, accumulator) return when the stream is empty?
  • A. null
  • B. The identity value
  • C. An empty Optional
  • D. Throws NoSuchElementException
Answer: B
B is correct. When the stream is empty, reduce(identity, accumulator) returns the identity value. For example, reduce(0, Integer::sum) returns 0 for an empty stream.
MCQ 14
What is the correct lambda syntax for a BiFunction that takes two integers and returns their sum?
  • A. BiFunction<Integer, Integer, Integer> f = a, b -> a + b
  • B. BiFunction<Integer, Integer, Integer> f = (a, b) -> a + b
  • C. BiFunction<Integer, Integer, Integer> f = (a, b) -> { return a + b }
  • D. BiFunction<Integer, Integer, Integer> f = (a, b) => a + b
Answer: B
B is correct. Multiple parameters must be in parentheses: (a, b) -> a + b. Option A is missing parentheses. Option C is missing a semicolon after return. Option D uses => which is JavaScript syntax, not Java.
MCQ 15
Can a stream be reused after a terminal operation?
  • A. Yes, streams are reusable
  • B. No, a stream can only be consumed once
  • C. Yes, if you call reset()
  • D. Only if it is a parallel stream
Answer: B
B is correct. After a terminal operation, the stream is closed and cannot be reused. Attempting to use it again throws IllegalStateException. Create a new stream from the source to reprocess.

Coding Challenges

Challenge 1: Custom Filter and Transform

Easy
Given a list of integers, use streams to filter out odd numbers, double each remaining number, and collect into a list. Print the result.
Sample Input
List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Sample Output
[4, 8, 12, 16, 20]
Use stream(), filter(), map(), and collect().
import java.util.List;
import java.util.stream.Collectors;

public class FilterAndTransform {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        List<Integer> result = nums.stream()
            .filter(n -> n % 2 == 0)
            .map(n -> n * 2)
            .collect(Collectors.toList());
        System.out.println(result);
    }
}

Challenge 2: Student Grade Report

Medium
Given a list of Student records (name, marks), use streams to: (1) Find students who scored above 80 (sorted by marks descending). (2) Calculate the class average. (3) Group students into PASS (>=40) and FAIL (<40).
Sample Input
Students: Arjun(85), Priya(92), Vikram(35), Sneha(78), Rohan(42)
Sample Output
Above 80: [Priya(92), Arjun(85)] Average: 66.4 PASS: [Arjun, Priya, Sneha, Rohan] FAIL: [Vikram]
Use stream operations: filter, sorted, mapToInt, average, partitioningBy.
import java.util.*;
import java.util.stream.Collectors;

public class GradeReport {
    record Student(String name, int marks) {}

    public static void main(String[] args) {
        List<Student> students = List.of(
            new Student("Arjun", 85),
            new Student("Priya", 92),
            new Student("Vikram", 35),
            new Student("Sneha", 78),
            new Student("Rohan", 42)
        );

        List<String> above80 = students.stream()
            .filter(s -> s.marks() > 80)
            .sorted(Comparator.comparingInt(Student::marks).reversed())
            .map(s -> s.name() + "(" + s.marks() + ")")
            .collect(Collectors.toList());
        System.out.println("Above 80: " + above80);

        double avg = students.stream()
            .mapToInt(Student::marks)
            .average().orElse(0);
        System.out.printf("Average: %.1f%n", avg);

        Map<Boolean, List<String>> passFailMap = students.stream()
            .collect(Collectors.partitioningBy(
                s -> s.marks() >= 40,
                Collectors.mapping(Student::name, Collectors.toList())
            ));
        System.out.println("PASS: " + passFailMap.get(true));
        System.out.println("FAIL: " + passFailMap.get(false));
    }
}

Challenge 3: Word Frequency Counter

Medium
Given a list of sentences, use streams to split each into words, count the frequency of each word (case-insensitive), and display the top 5 most frequent words.
Sample Input
"Java is great", "Java is powerful", "Java and Python are great"
Sample Output
java: 3 is: 2 great: 2 python: 1 and: 1
Use flatMap to split sentences into words. Use Collectors.groupingBy and Collectors.counting().
import java.util.*;
import java.util.stream.Collectors;

public class WordFrequency {
    public static void main(String[] args) {
        List<String> sentences = List.of(
            "Java is great",
            "Java is powerful",
            "Java and Python are great"
        );

        Map<String, Long> frequency = sentences.stream()
            .flatMap(s -> Arrays.stream(s.toLowerCase().split("\\s+")))
            .collect(Collectors.groupingBy(w -> w, Collectors.counting()));

        frequency.entrySet().stream()
            .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
            .limit(5)
            .forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));
    }
}

Challenge 4: Employee Analytics Dashboard

Hard
Given a list of Employee records (name, department, salary), use streams to: (1) Find the highest-paid employee per department. (2) Calculate total salary expense per department. (3) Find employees earning above the company average. (4) Create a comma-separated string of all employee names sorted alphabetically.
Sample Input
Multiple employees across Engineering, Marketing, and HR departments
Sample Output
Highest paid per dept: {Engineering=Sneha(95000), ...} Total per dept: {Engineering=272000, ...} Above average: [Arjun, Priya, Sneha] All names: Arjun, Kavya, Priya, Rohan, Sneha, Vikram
Use groupingBy with downstream collectors, Collectors.maxBy, Collectors.summingInt, and Collectors.joining.
import java.util.*;
import java.util.stream.Collectors;

public class EmployeeAnalytics {
    record Employee(String name, String dept, int salary) {}

    public static void main(String[] args) {
        List<Employee> employees = List.of(
            new Employee("Arjun", "Engineering", 85000),
            new Employee("Priya", "Engineering", 92000),
            new Employee("Vikram", "Marketing", 78000),
            new Employee("Sneha", "Engineering", 95000),
            new Employee("Rohan", "Marketing", 72000),
            new Employee("Kavya", "HR", 68000)
        );

        // Highest paid per department
        Map<String, Optional<Employee>> topPerDept = employees.stream()
            .collect(Collectors.groupingBy(
                Employee::dept,
                Collectors.maxBy(Comparator.comparingInt(Employee::salary))
            ));
        topPerDept.forEach((dept, emp) ->
            emp.ifPresent(e -> System.out.println(dept + ": " + e.name() + "(" + e.salary() + ")")));

        // Total salary per dept
        Map<String, Integer> totalPerDept = employees.stream()
            .collect(Collectors.groupingBy(Employee::dept, Collectors.summingInt(Employee::salary)));
        System.out.println("Total per dept: " + totalPerDept);

        // Above company average
        double avg = employees.stream().mapToInt(Employee::salary).average().orElse(0);
        List<String> aboveAvg = employees.stream()
            .filter(e -> e.salary() > avg)
            .map(Employee::name)
            .collect(Collectors.toList());
        System.out.printf("Company avg: %.0f, Above: %s%n", avg, aboveAvg);

        // Sorted names
        String allNames = employees.stream()
            .map(Employee::name)
            .sorted()
            .collect(Collectors.joining(", "));
        System.out.println("All names: " + allNames);
    }
}

Challenge 5: Custom Optional Chain

Hard
Create a chain of Optional operations: given a user ID, find the user, get their address, get the city, and convert to uppercase. If any step returns null/empty, return 'UNKNOWN'. Demonstrate with found and not-found cases.
Sample Input
User ID: 1 (exists), User ID: 99 (does not exist)
Sample Output
User 1 city: DELHI User 99 city: UNKNOWN
Use Optional.ofNullable, map, flatMap, and orElse. Do not use any null checks (if statements).
import java.util.*;

public class OptionalChain {
    record Address(String city, String state) {}
    record User(int id, String name, Address address) {}

    static Map<Integer, User> database = Map.of(
        1, new User(1, "Arjun", new Address("Delhi", "Delhi")),
        2, new User(2, "Priya", new Address("Mumbai", "Maharashtra")),
        3, new User(3, "Vikram", null) // no address
    );

    static Optional<User> findUser(int id) {
        return Optional.ofNullable(database.get(id));
    }

    static String getCityUpperCase(int userId) {
        return findUser(userId)
            .map(User::address)
            .map(Address::city)
            .map(String::toUpperCase)
            .orElse("UNKNOWN");
    }

    public static void main(String[] args) {
        System.out.println("User 1 city: " + getCityUpperCase(1));
        System.out.println("User 2 city: " + getCityUpperCase(2));
        System.out.println("User 3 city: " + getCityUpperCase(3));
        System.out.println("User 99 city: " + getCityUpperCase(99));
    }
}

Need to Review the Concepts?

Go back to the detailed notes for this chapter.

Read Chapter Notes

Want to learn Java with a live mentor?

Explore our Java Masterclass