Lambda Expressions and Functional Interfaces practice questions

From OCP Java SE 8 (1Z0-809) · 47 questions on this topic

Lambda Expressions and Functional Interfaces practice questions from OCP Java SE 8 (1Z0-809). This pack has 47 questions tagged Lambda Expressions and Functional Interfaces, drawn from its timed mock exams. 8 of them are worked through in full below — the question, every option, why each is right or wrong, and the explanation.

Worked examples for Lambda Expressions and Functional Interfaces

  1. Question 1

    What is the output of the following program? ```java import java.util.function.Function; public class Main { public static void main(String[] args) { Function<String, Integer> parser = s -> Integer.parseInt(s); try { System.out.println(parser.apply("abc")); } catch (NumberFormatException e) { System.out.println("error"); } } } ```

    1. A. abc

      "abc" is the input string; parsing it does not echo it back — it triggers an exception instead.

    2. B. errorCorrect answer

      `Integer.parseInt("abc")` throws the unchecked NumberFormatException, which propagates out of apply and is caught, so "error" prints; lambdas may throw unchecked exceptions freely (JLS §15.27.2).

    3. C. 0

      0 assumes a fallback value on parse failure, but Java supplies none — parseInt throws rather than returning a default.

    4. D. Compilation fails because lambdas cannot throw exceptions

      Lambdas can throw exceptions; only checked exceptions require the functional interface to declare them, and NumberFormatException is unchecked, so this compiles.

    Explanation

    A lambda may throw any unchecked (RuntimeException) type without the functional interface declaring it; only checked exceptions must appear in the interface method's `throws` clause (JLS §15.27.2, §11.2). Parsing a non-numeric string raises an unchecked exception that propagates out of the functional call and is handled by the surrounding try/catch.

  2. Question 2

    What is the output of the following program? ```java import java.util.function.Supplier; class Counter { int count = 0; int increment() { return ++count; } Supplier<Integer> ref() { return this::increment; } } public class Main { public static void main(String[] args) { Counter c = new Counter(); Supplier<Integer> s = c.ref(); System.out.print(s.get()); System.out.print(s.get()); System.out.print(s.get()); } } ```

    1. A. 000

      Assumes the reference never actually calls the method; each `get()` does invoke `increment()`, so zeros are not printed.

    2. B. 123Correct answer

      `this::increment` binds the `Counter` instance on which `ref()` was called, so each `s.get()` increments the same `count` to 1, then 2, then 3, printed back-to-back with no separators.

    3. C. 111

      Treats the receiver as if fresh state were captured per invocation; the same object is reused, so the count keeps rising rather than repeating 1.

    4. D. Compilation fails because this:: is not a valid method reference qualifier

      `this` is a valid primary expression and qualifies as the `Primary::Identifier` form of method reference, so the code compiles.

    Explanation

    A `this`-bound method reference captures the enclosing instance itself, and every invocation acts on that one shared object. Repeated calls mutate and observe the same field, so a counter advances cumulatively rather than resetting each time.

  3. Question 3

    What is the output of the following program? ```java import java.util.function.Consumer; public class Main { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); Consumer<String> c1 = sb::append; Consumer<String> c2 = s -> sb.append(s.toUpperCase()); c1.andThen(c2).accept("go"); System.out.println(sb); } } ```

    1. A. GOgo

      Reverses the chain order, assuming the second consumer runs first; andThen runs the receiver first, so "go" is appended before "GO".

    2. B. Compilation fails because Consumer has no andThen

      Assumes Consumer lacks composition; andThen is a default method on Consumer, so the code compiles.

    3. C. go

      Assumes only the first consumer runs; andThen invokes both consumers on the same input, so the second also appends its result.

    4. D. goGOCorrect answer

      andThen feeds the same input to both consumers in order: the bound-instance method reference appends "go", then the lambda appends the uppercased "GO".

    Explanation

    Consumer.andThen returns a composed consumer that passes the same input to the receiver first and then to the argument consumer, with no value handed between them. The method reference appends "go" and the lambda then appends "GO", producing goGO in chain order.

  4. Question 4

    What is the output of the following program? ```java import java.util.Arrays; import java.util.Comparator; public class Main { public static void main(String[] args) { String[] words = {"bb", "a", "ccc"}; Arrays.sort(words, (x, y) -> x.length() - y.length()); System.out.println(Arrays.toString(words)); } } ```

    1. A. [a, bb, ccc]Correct answer

      Comparator's `int compare(T, T)` returns negative when x is shorter, so `x.length() - y.length()` sorts by length ascending: "a"(1), "bb"(2), "ccc"(3).

    2. B. [bb, a, ccc]

      This is the original, unsorted input order; the comparator reorders the array by length.

    3. C. [ccc, bb, a]

      This descending-by-length order would require `y.length() - x.length()`, the reverse of the given lambda.

    4. D. Compilation fails

      Arrays.sort with a Comparator is a standard overload and the two-parameter lambda matches `int compare(T, T)`, so it compiles.

    Explanation

    A Comparator lambda returns a negative, zero, or positive int to order two elements, and subtracting the lengths makes shorter strings sort first. Sorting therefore arranges the array from the shortest string to the longest.

  5. Question 5

    What is the output of the following program? ```java import java.util.function.Function; public class Main { public static void main(String[] args) { Function<Integer, String> classify = n -> { if (n > 0) return "positive"; if (n < 0) return "negative"; return "zero"; }; System.out.println(classify.apply(-5)); } } ```

    1. A. positive

      "positive" is returned only when `n > 0`, which is false for -5.

    2. B. negativeCorrect answer

      For -5 the first test `n > 0` fails and `n < 0` succeeds, so `return "negative"` fires and the remaining statements are unreachable (JLS §15.27.2).

    3. C. zero

      "zero" is the final fall-through return, reached only when the input is neither positive nor negative.

    4. D. Compilation fails

      Every execution path returns a String, so the block body is value-compatible and compiles.

    Explanation

    A block-body lambda may contain several `return` statements as long as every reachable terminal point returns a value of the required type (JLS §15.27.2). For a negative input the first guard fails and the second succeeds, returning before any later branch runs.

  6. Question 6

    Which built-in functional interface takes no arguments and returns a value?

    1. A. Predicate<T>

      Predicate takes one argument and returns a boolean, so it neither takes no arguments nor returns an arbitrary value.

    2. B. Consumer<T>

      Consumer is the opposite shape: it takes one argument and returns nothing via accept, so it does not return a value.

    3. C. Supplier<T>Correct answer

      Supplier produces a value from nothing through get(), matching the take-no-arguments, return-a-value shape.

    4. D. Function<T, R>

      Function takes one argument and returns another via apply, so it requires an input rather than taking no arguments.

    Explanation

    Supplier produces from nothing (get()). Consumer is the opposite — takes and returns nothing (accept). Predicate takes one and returns boolean; Function takes one and returns another. Matching shapes to interfaces is a guaranteed exam mark.

  7. Question 7

    What is the output of the following program? ```java import java.util.function.Function; public class Main { public static void main(String[] args) { Function<Integer, Integer> dbl = x -> x * 2; Function<Integer, Integer> inc = x -> x + 1; System.out.println(dbl.andThen(inc).apply(5) + " " + dbl.compose(inc).apply(5)); } } ```

    1. A. 11 11

      Applies andThen's order to both calls; compose runs the argument function first (5+1=6, then *2 → 12), so the second result is 12, not 11.

    2. B. 12 11

      Swaps the two results by treating andThen as argument-first and compose as receiver-first; in fact andThen gives 11 (10 then +1) and compose gives 12 (6 then *2).

    3. C. 12 12

      Applies compose's argument-first order to both calls; andThen runs the receiver first (5*2=10, then +1 → 11), so the first result is 11, not 12.

    4. D. 11 12Correct answer

      andThen runs the receiver first (5*2=10, then +1 → 11) and compose runs the argument first (5+1=6, then *2 → 12), so the two mirror-image compositions print 11 and 12.

    Explanation

    andThen runs the receiver FIRST: 5*2=10, then +1 → 11. compose runs the ARGUMENT first: 5+1=6, then *2 → 12. The two are mirror images — mixing them up is the classic composition trap.

  8. Question 8

    What is the output of the following program? ```java import java.util.function.BiPredicate; public class Main { public static void main(String[] args) { BiPredicate<String, Integer> lenIs = (s, n) -> s.length() == n; System.out.println(lenIs.test("four", 4) + " " + lenIs.negate().test("four", 4)); } } ```

    1. A. false true

      Would require the direct test to be false; "four".length() == 4 is true, and its negation is false.

    2. B. true true

      Would require negate to return true; negate flips the true result to false.

    3. C. true falseCorrect answer

      "four".length() == 4 is true, and negate() flips that same test to false.

    4. D. Compilation fails because BiPredicate takes one type argument

      Misjudges its arity; BiPredicate<T, U> takes two independent type arguments for its two inputs, so it compiles.

    Explanation

    BiPredicate<T, U> tests two inputs of independent types and, like Predicate, provides negate as a default method. The length check on "four" against 4 is true, and negating the identical check yields false.

Practise all 47 Lambda Expressions and Functional Interfaces questions

OCP Java SE 8 has the full set, inside timed mock exams that mirror real exam conditions — every question with a worked explanation.

Open OCP Java SE 8

Other topics in this pack