Courseiva

CCNA Streams Lambdas Questions

73 of 89 questions · Page 1/2 · Streams Lambdas topic · Answers revealed

1
MCQmedium

A developer wants to create a stream that repeatedly generates random integers. Which method should be used?

A.IntStream.range(0, 100)
B.Stream.of(new Random().nextInt())
C.IntStream.generate(() -> new Random().nextInt())
D.Stream.iterate(0, i -> new Random().nextInt())
AnswerC

This creates an infinite stream of random ints; it's the idiomatic choice for primitive streams.

Why this answer

`IntStream.generate()` accepts a `Supplier<Integer>` and produces an infinite sequential unordered stream, making it ideal for repeatedly generating random integers. The lambda `() -> new Random().nextInt()` supplies a new random integer each time the stream is evaluated, fulfilling the requirement exactly.

Exam trap

The trap here is that candidates confuse `Stream.generate()` with `Stream.iterate()` or `Stream.of()`, mistakenly thinking that a single random call or a finite range can produce an infinite stream of random values, when only `generate()` with a `Supplier` correctly models repeated independent generation.

How to eliminate wrong answers

Option A is wrong because `IntStream.range(0, 100)` generates a finite stream of integers from 0 to 99, not random values. Option B is wrong because `Stream.of(new Random().nextInt())` creates a single-element stream containing one random integer, not a stream that repeatedly generates random integers. Option D is wrong because `Stream.iterate(0, i -> new Random().nextInt())` produces an infinite stream but the first element is always 0, and the seed value is never used in the generation logic, which is not a clean or intended approach for random generation; additionally, `Stream.iterate` is typically used for sequential transformations, not for independent random suppliers.

2
MCQmedium

A developer is designing a method that processes a stream of Employee objects. The method needs to group employees by department and then, within each department, sort by salary in descending order, and collect the top 3 highest-paid employees per department into a list. Which approach correctly accomplishes this using streams?

A.stream.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.collectingAndThen(Collectors.toList(), list -> list.stream().sorted(Comparator.comparing(Employee::getSalary).reversed()).limit(3).collect(Collectors.toList()))))
B.stream.collect(Collectors.toMap(Employee::getDepartment, e -> { List<Employee> l = new ArrayList<>(); l.add(e); return l; }, (l1, l2) -> { l1.addAll(l2); l1.sort(Comparator.comparing(Employee::getSalary).reversed()); return l1.subList(0, Math.min(3, l1.size())); }))
C.stream.sorted(Comparator.comparing(Employee::getSalary).reversed()).collect(Collectors.groupingBy(Employee::getDepartment, Collectors.toList())).values().stream().map(l -> l.subList(0, Math.min(3, l.size()))).collect(Collectors.toList())
D.stream.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.toList())).entrySet().stream().flatMap(e -> e.getValue().stream().sorted(Comparator.comparing(Employee::getSalary).reversed()).limit(3)).collect(Collectors.toList())
AnswerA

This groups by department, then for each group sorts descending and limits to 3, exactly as required.

Why this answer

It uses `Collectors.groupingBy` to partition employees by department, then applies `Collectors.collectingAndThen` to post-process each department's list. Inside, it sorts the list by salary in descending order, limits to the top 3, and collects them into a new list. This ensures each department's result is independently sorted and truncated.

Exam trap

The trap here is that candidates often sort globally before grouping (Option C) or flatten the result (Option D), failing to realize that per-group sorting and limiting must occur inside the downstream collector to maintain group isolation.

How to eliminate wrong answers

Option B is wrong because `Collectors.toMap` with a merge function is not designed for grouping; it incorrectly mutates the same list across multiple employees, leading to shared state and potential data corruption. Option C is wrong because it sorts the entire stream globally before grouping, which destroys per-department ordering, and then uses `subList` on unsorted lists, which may not contain the top 3 per department. Option D is wrong because it flattens the grouped entries into a single stream after sorting and limiting, producing a flat list of top employees across all departments rather than a list of lists per department.

3
MCQhard

Given: List<String> words = Arrays.asList("apple", "banana", "cherry"); Map<Integer, List<String>> map = words.stream().collect(Collectors.groupingBy(String::length)); System.out.println(map); What is the output?

A.[apple, banana, cherry]
B.{5=[5], 6=[6, 6]}
C.{5=[apple], 6=[banana, cherry]}
D.{apple=[5], banana=[6], cherry=[6]}
AnswerC

Correct grouping.

Why this answer

The `groupingBy` collector groups stream elements by a classifier function, here `String::length`. Each distinct length becomes a key in the map, and the values are lists of strings with that length. "apple" (length 5) maps to key 5, "banana" and "cherry" (both length 6) map to key 6, producing `{5=[apple], 6=[banana, cherry]}`.

Exam trap

The trap here is confusing `groupingBy` with `toMap` or assuming the map keys are the string values themselves, leading candidates to reverse the key-value roles or misrepresent the grouped lists.

How to eliminate wrong answers

Option A is wrong because it shows a flat list, not a map, and ignores the grouping operation. Option B is wrong because it incorrectly uses the length values as list elements instead of the original strings, and duplicates the length 6 value. Option D is wrong because it reverses the key-value relationship, making the strings the keys and their lengths the values, which is not what `groupingBy` does.

4
MCQhard

A company runs a financial application that processes a stream of millions of transaction records daily. Each record is a 'Transaction' object with fields: id, amount, currency, timestamp. The system currently uses a parallel stream to group transactions by currency and compute the sum of amounts per currency, using the following code: Map<String, Double> result = transactions.parallelStream() .collect(Collectors.groupingBy(Transaction::getCurrency, Collectors.summingDouble(Transaction::getAmount))); Recently, performance has degraded significantly. Analysis shows that the stream source is a LinkedList, and the operation involves a large number of distinct currencies (over 1000). The JVM is running on a machine with 4 cores. Which is the best course of action to improve performance?

A.Change the stream source to an ArrayList and use sequential stream.
B.Use a custom thread pool with ForkJoinPool to control parallelism.
C.Increase the parallelism level to 8.
D.Replace groupingBy with a custom concurrent collector using ConcurrentHashMap.
AnswerD

Replacing groupingBy with a custom concurrent collector using ConcurrentHashMap eliminates the merge step, allowing concurrent updates without synchronization, which improves throughput.

Why this answer

The performance degradation stems from the parallel stream using a shared `ConcurrentHashMap` internally for the `groupingBy` collector, which incurs significant overhead when merging partial results from many threads, especially with over 1000 distinct currencies. A custom concurrent collector using `ConcurrentHashMap` directly eliminates this merge overhead by allowing threads to update the map concurrently without synchronization bottlenecks, improving throughput on a 4-core machine.

Exam trap

The trap here is that candidates often assume the problem is the stream source (LinkedList) or parallelism level, but the real issue is the collector's merge overhead with many distinct keys, which is a subtle but critical performance detail in parallel stream operations.

How to eliminate wrong answers

Option A is wrong because switching to a sequential stream would lose parallelism entirely, and while an `ArrayList` improves splitting efficiency, the core issue is the merge overhead of `groupingBy` with many keys, not the source type. Option B is wrong because using a custom `ForkJoinPool` does not address the fundamental problem of the collector's merge phase; it only changes the thread pool, leaving the same inefficient merge logic. Option C is wrong because increasing parallelism to 8 on a 4-core machine would cause oversubscription, leading to more context switching and worse performance, not improvement.

5
MCQhard

A stream pipeline uses sorted() with a Comparator that calls a thread-unsafe method on each element. The pipeline is parallel. What is the likely outcome?

A.The pipeline may produce incorrect ordering or throw a ConcurrentModificationException.
B.The pipeline will throw an exception because the comparator is stateful.
C.The pipeline will sort correctly because sorted() is a sequential operation.
D.The pipeline will run sequentially because the stream source is not ordered.
AnswerA

Correct: A non-thread-safe comparator can cause data corruption or exceptions due to concurrent access.

Why this answer

In a parallel stream pipeline, the `sorted()` operation requires a stable sort that merges results from multiple threads. If the provided `Comparator` calls a thread-unsafe method on each element, concurrent invocations from different threads can cause race conditions, leading to incorrect ordering or a `ConcurrentModificationException` if the method modifies shared state. The pipeline does not automatically fall back to sequential execution for `sorted()` when the comparator is stateful or unsafe.

Exam trap

The trap here is that candidates assume `sorted()` forces sequential execution in a parallel stream, but in reality, `sorted()` is a stateful intermediate operation that still runs in parallel, and thread-safety of the comparator is the candidate's responsibility.

How to eliminate wrong answers

Option B is wrong because a stateful comparator does not inherently cause an exception; the issue is thread-safety, not statefulness per se, and the pipeline may produce incorrect results without throwing an exception. Option C is wrong because `sorted()` in a parallel stream is not a sequential operation; it uses a parallel merge sort algorithm that splits the data across threads. Option D is wrong because the stream source being ordered or unordered does not affect the parallel execution of `sorted()`; the pipeline remains parallel regardless of the source's ordering characteristics.

6
Multi-Selecthard

Which TWO are correct about parallel streams in Java? (Choose TWO.)

Select 2 answers
A.Parallel streams always improve performance over sequential streams.
B.Any lambda expression is safe to use in a parallel stream.
C.Using parallel streams guarantees the order of elements in the result.
D.Parallel streams use the common ForkJoinPool by default.
E.To get correct results, operations should be stateless and non-interfering.
AnswersD, E

Default pool is ForkJoinPool.commonPool().

Why this answer

Parallel streams in Java, by default, use the common ForkJoinPool (ForkJoinPool.commonPool()), which is a shared thread pool designed for parallel task execution. This pool is lazily initialized and has a default parallelism level equal to the number of available processors minus one, as per the ForkJoinPool implementation.

Exam trap

The trap here is that candidates often assume parallel streams are always faster (Option A) or that any lambda is safe (Option B), overlooking the critical requirements of statelessness and non-interference for correctness in parallel execution.

7
MCQeasy

Which statement about the Stream API is true?

A.Parallel streams always improve performance.
B.Streams are always finite.
C.Intermediate operations are executed eagerly.
D.A stream can be consumed only once.
AnswerD

Correct.

Why this answer

A Stream in Java represents a sequence of elements that can be traversed only once. Once a terminal operation (like collect() or forEach()) is invoked on a stream, the stream is consumed and cannot be reused; attempting to do so throws an IllegalStateException. This one-time consumption is a fundamental design principle of the Stream API, ensuring that operations are applied to a single, immutable pipeline.

Exam trap

Oracle often tests the misconception that streams are reusable like collections, but the trap here is that candidates forget a stream is a one-shot object that cannot be traversed more than once, leading them to incorrectly assume they can call multiple terminal operations on the same stream.

How to eliminate wrong answers

Option A is wrong because parallel streams do not always improve performance; overhead from thread management, splitting, and merging can degrade performance, especially on small datasets or operations with high contention. Option B is wrong because streams can be infinite, as demonstrated by Stream.iterate() or Stream.generate(), which produce unbounded sequences that must be limited by short-circuiting operations like limit(). Option C is wrong because intermediate operations (e.g., filter(), map()) are lazy and are not executed until a terminal operation is invoked; they build a pipeline of operations that are applied only when needed.

8
MCQhard

Given: List<String> words = List.of("apple", "banana", "cherry"); var result = words.stream().filter(s -> s.length() > 5).collect(Collectors.toUnmodifiableList()); What happens if another thread tries to add to result?

A.Compilation error because var cannot be used with streams.
B.UnsupportedOperationException at runtime.
C.The thread successfully adds the element.
D.NullPointerException.
AnswerB

The returned list is unmodifiable; calling add() throws UnsupportedOperationException.

Why this answer

B is correct because `Collectors.toUnmodifiableList()` returns an unmodifiable list, and any attempt to modify it (e.g., via `add()`) throws an `UnsupportedOperationException`. The stream pipeline itself is safe and compiles fine; the issue is the mutability of the resulting collection.

Exam trap

The trap here is that candidates may confuse `Collectors.toUnmodifiableList()` with `Collectors.toList()`, which returns a mutable list, and incorrectly assume the list can be modified by another thread.

How to eliminate wrong answers

Option A is wrong because `var` can be used with streams; it infers the type `List<String>` from the right-hand side, and the code compiles without error. Option C is wrong because the list returned by `Collectors.toUnmodifiableList()` is immutable, so no thread can successfully add an element; any modification attempt throws an exception. Option D is wrong because no `NullPointerException` occurs; the list is non-null and the exception is specifically `UnsupportedOperationException`.

9
MCQhard

Given a list of strings, which of the following will produce a Map<String, Long> counting the occurrences of each string?

A..collect(Collectors.toMap(Function.identity(), String::length))
B..collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
C..collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(e->1)))
D..collect(Collectors.toMap(Function.identity(), v->1))
AnswerB

Correct. groupingBy with counting as downstream collector produces a long count per key.

Why this answer

`Collectors.groupingBy(Function.identity(), Collectors.counting())` groups each string by itself (using `Function.identity()` as the classifier) and then applies a downstream collector `Collectors.counting()` that counts the number of elements in each group, producing a `Map<String, Long>` where each key is a unique string and the value is its frequency.

Exam trap

The trap here is that candidates often choose `Collectors.toMap` with a constant value (like `v->1`) without realizing it fails on duplicate keys, or they pick `summingInt` thinking it produces a `Long` when it actually produces an `Integer`, missing the exact type constraint of `Map<String, Long>`.

How to eliminate wrong answers

Option A is wrong because `Collectors.toMap(Function.identity(), String::length)` creates a `Map<String, Integer>` mapping each string to its length, not a count of occurrences; it also throws an `IllegalStateException` if duplicate keys exist. Option C is wrong because `Collectors.summingInt(e->1)` returns an `Integer` sum, not a `Long` count, so the result would be `Map<String, Integer>` instead of `Map<String, Long>`. Option D is wrong because `Collectors.toMap(Function.identity(), v->1)` will throw an `IllegalStateException` on duplicate keys (since `toMap` by default does not handle key collisions) and produces a `Map<String, Integer>` with value 1 for each key, not a cumulative count.

10
MCQmedium

A developer wants to find the longest word in a list of strings. Which stream operation should be used?

A.stream().sorted(Comparator.comparingInt(String::length).reversed()).findFirst()
B.stream().min(Comparator.comparingInt(String::length))
C.stream().sorted(Comparator.comparingInt(String::length)).findFirst()
D.stream().max(Comparator.comparingInt(String::length))
AnswerD

Correct.

Why this answer

The `max()` terminal operation, when combined with a `Comparator` that compares strings by their length, returns the longest word in the stream. The `max()` operation uses the provided comparator to determine the 'largest' element according to the ordering, which in this case is the string with the greatest length.

Exam trap

The trap here is that candidates often confuse `min()` and `max()` or incorrectly assume that sorting and taking the first element is the intended approach, overlooking the direct and efficient `max()` operation.

How to eliminate wrong answers

Option A is wrong because it sorts the stream in descending order of length and then calls `findFirst()`, which is unnecessarily complex and less efficient than `max()`; it also requires the stream to be fully sorted before retrieval. Option B is wrong because `min()` returns the smallest element according to the comparator, which would give the shortest word, not the longest. Option C is wrong because it sorts in ascending order of length and then calls `findFirst()`, which returns the shortest word, not the longest.

11
Matchingmedium

Match each exception class to its category (checked/unchecked).

Drag a concept onto its matching description — or click a concept then click the description.

Concepts
Matches

Checked exception

Unchecked exception

Checked exception

Unchecked exception

Checked exception

Why these pairings

Checked exceptions must be handled or declared; unchecked extend RuntimeException.

12
MCQhard

Which of the following lambda expressions is syntactically invalid?

A.() -> {return 42;}
B.(a, b) -> a + b
C.(a, b) -> return a + b;
D.(int a, int b) -> a + b
E.(a) -> a * 2
AnswerC

Invalid. 'return' keyword requires a block body (curly braces).

Why this answer

Syntactically invalid because in a lambda expression, the `return` keyword is only allowed inside a block body (with braces). When using an expression body (no braces), the `return` keyword must be omitted, and the expression itself is implicitly returned. Option C incorrectly uses `return` without braces, which is a syntax error.

Exam trap

The trap here is that candidates often confuse the syntax of expression lambdas with block lambdas, mistakenly thinking `return` can be used without braces, or they forget that a single expression without `return` is implicitly returned.

How to eliminate wrong answers

Option A is valid because it uses a block body with braces and a `return` statement, which is syntactically correct. Option B is valid because it uses an expression body (no braces) that implicitly returns the result of `a + b`. Option D is valid because it uses explicit parameter types (`int a, int b`) with an expression body, which is allowed.

Option E is valid because it uses a single parameter with an expression body, and parentheses around a single parameter are optional but allowed.

13
MCQeasy

Which of the following is a terminal operation of the Stream API?

A.map()
B.forEach()
C.filter()
D.peek()
AnswerB

Correct. forEach() is a terminal operation.

Why this answer

(forEach()) is correct because it is a terminal operation in the Stream API. Terminal operations produce a result or side effect and close the stream, meaning no further operations can be performed on the same stream. forEach() consumes each element of the stream and returns void, making it a terminal operation.

Exam trap

The trap here is that candidates often confuse peek() with forEach() because both can perform actions on elements, but peek() is intermediate and does not trigger stream processing, while forEach() is terminal and does.

How to eliminate wrong answers

Option A is wrong because map() is an intermediate operation that returns a new stream after applying a function to each element; it does not close the stream. Option C is wrong because filter() is an intermediate operation that returns a new stream containing only elements that match a predicate; it does not terminate the stream. Option D is wrong because peek() is an intermediate operation designed for debugging purposes, allowing you to view elements without terminating the stream.

14
Multi-Selecthard

Which TWO statements about the Stream API are correct? (Choose two.) A. A stream can be traversed multiple times. B. The peek() method is an intermediate operation. C. The findFirst() method returns an Optional. D. The collect() method is an intermediate operation. E. The map() method returns a stream of the same type.

Select 2 answers
A.A stream can be traversed multiple times.
B.The peek() method is an intermediate operation.
C.The findFirst() method returns an Optional.
D.The collect() method is an intermediate operation.
E.The map() method returns a stream of the same type.
AnswersB, C

This statement is true. peek() is an intermediate operation that returns the same stream elements after performing an action.

Why this answer

The correct statements are B and C. Option B is correct because peek() is an intermediate operation that allows performing an action on each element without modifying the stream. Option C is correct because findFirst() returns an Optional describing the first element, or an empty Optional if the stream is empty.

Option A is incorrect because a stream can only be consumed once; it cannot be traversed multiple times. Option D is incorrect because collect() is a terminal operation, not an intermediate operation. Option E is incorrect because map() can change the element type; for example, mapping a Stream<String> to Stream<Integer> is common.

Exam trap

The main trap in this question is confusing intermediate and terminal operations. Candidates often mistake collect() as intermediate or think that peek() is terminal. Another trap is assuming streams can be reused, but they are single-use only.

15
Multi-Selectmedium

Which TWO statements about method references are true? (Choose two.)

Select 2 answers
A.Constructor references use the syntax Class::new.
B.Array constructor references are not supported.
C.Instance method references always use the keyword static.
D.A method reference can be used in place of a lambda expression of compatible functional interface.
E.Method references cannot refer to methods declared in the same class.
AnswersA, D

Constructor references follow ClassName::new syntax.

Why this answer

Constructor references use the syntax `Class::new` to refer to a constructor of a class, which can be used with a functional interface whose method matches the constructor's signature. This allows creating instances without explicitly invoking `new`, leveraging the same target type inference as lambda expressions.

Exam trap

The trap here is that candidates often confuse instance method references with static method references, mistakenly thinking the `static` keyword is required, or they overlook that array constructor references are indeed supported via `Type[]::new`.

16
MCQmedium

A company needs to process a stream of orders and filter out orders that are not in the 'SHIPPED' status. Then they want to collect the order IDs into a list. Which of the following correctly uses lambda expressions to achieve this?

A.orders.stream().filter(o -> o.getStatus() != "SHIPPED").map(Order::getId).collect(Collectors.toList())
B.orders.stream().map(Order::getId).filter(id -> id.equals("SHIPPED")).collect(Collectors.toList())
C.orders.stream().filter(Order::getStatus).map(o -> o.getId()).collect(Collectors.toList())
D.orders.stream().filter(o -> o.getStatus().equals("SHIPPED")).map(Order::getId).collect(Collectors.toList())
AnswerD

Correctly filters SHIPPED orders and maps to IDs.

Why this answer

It first filters the stream to include only orders with status 'SHIPPED' using a lambda expression that calls equals() on the status string, then maps each order to its ID using a method reference, and finally collects the IDs into a list. This correctly uses lambda expressions and the Stream API to achieve the requirement.

Exam trap

Oracle often tests the distinction between using equals() vs == for string comparison in lambda expressions, and the correct order of stream operations (filter before map) to avoid type mismatches or logical errors.

How to eliminate wrong answers

Option A is wrong because it filters orders where the status is NOT equal to 'SHIPPED' (using !=), which is the opposite of what is required. Option B is wrong because it maps orders to IDs first, then tries to filter IDs by comparing them to the string 'SHIPPED', which is a type mismatch and logically incorrect. Option C is wrong because it uses a method reference Order::getStatus as a predicate, but getStatus returns a String, not a boolean, so it does not compile or work as a filter.

17
Multi-Selectmedium

Which THREE of the following are valid ways to create a Stream<String>? (Choose three.)

Select 3 answers
A.Arrays.stream(new String[]{"a", "b"})
B.Stream.of("a", "b")
C.List.of("a", "b").stream()
D."ab".chars()
E.new Stream<String>()
AnswersA, B, C

Arrays.stream for object arrays returns a Stream of the array elements.

Why this answer

`Arrays.stream(T[])` returns a `Stream<T>` from an array. Passing `new String[]{"a", "b"}` creates a `Stream<String>` directly, as the method is overloaded for object arrays.

Exam trap

The trap here is that candidates often confuse `chars()` as returning a `Stream<Character>` or `Stream<String>`, when in fact it returns an `IntStream` of code points, and they may also mistakenly think `Stream` can be instantiated with `new` like a regular class.

18
MCQeasy

Which functional interface is most appropriate for a lambda that takes a String and returns nothing?

A.Predicate<String>
B.Function<String, Void>
C.Supplier<String>
D.Consumer<String>
AnswerD

Consumer<String> accepts a String and returns void, best suited for side-effect operations.

Why this answer

A lambda that takes a String and returns nothing matches the `Consumer<String>` functional interface, which has a single abstract method `void accept(String t)`. `Consumer` is designed for operations that consume an input and produce no output, such as printing or logging the string.

Exam trap

The trap here is that candidates mistakenly choose `Function<String, Void>` thinking `Void` represents 'nothing', but `Void` is a class that requires a return value of `null`, making it unsuitable for a lambda that truly returns nothing.

How to eliminate wrong answers

Option A is wrong because `Predicate<String>` returns a `boolean`, not nothing. Option B is wrong because `Function<String, Void>` returns a `Void` object (which requires a return statement with `null`), not nothing; the lambda would need to explicitly return `null`. Option C is wrong because `Supplier<String>` takes no arguments and returns a `String`, the opposite of the required signature.

19
MCQmedium

A method receives a List<String> and needs to transform it to a Map where the key is the first three characters of each string and the value is the string itself. If two strings have the same prefix, the later one should override the earlier. Which collector achieves this?

A.Collectors.groupingBy(s -> s.substring(0,3))
B.Collectors.toMap(s -> s.substring(0,3), Function.identity())
C.Collectors.toConcurrentMap(s -> s.substring(0,3), Function.identity())
D.Collectors.toMap(s -> s.substring(0,3), Function.identity(), (a,b) -> b)
AnswerD

Correct: The merge function (a,b) -> b keeps the later value.

Why this answer

`Collectors.toMap` with a merge function `(a, b) -> b` ensures that when duplicate keys (first three characters) occur, the later string in the stream order replaces the earlier one. The merge function is invoked on key collision, and returning `b` (the second argument) keeps the later value, satisfying the requirement.

Exam trap

The trap here is that candidates often pick `toMap` without a merge function (Option B) or `groupingBy` (Option A), forgetting that duplicate keys cause exceptions or produce the wrong map type, respectively.

How to eliminate wrong answers

Option A is wrong because `groupingBy` groups all strings with the same prefix into a `List<String>`, not a single string per key, so the result is `Map<String, List<String>>` instead of `Map<String, String>`. Option B is wrong because `toMap` without a merge function throws `IllegalStateException` when duplicate keys are encountered, which will happen if any two strings share the same first three characters. Option C is wrong because `toConcurrentMap` also requires a merge function for duplicate keys and will throw an exception without one; additionally, it is designed for parallel streams and is not necessary for this sequential requirement.

20
MCQhard

A developer implements a reduction using reduce() to concatenate strings from a stream. The code: Optional<String> result = stream.reduce((s1, s2) -> s1.concat(s2)); The operation works but the developer is concerned about performance with large streams. Which change would most likely improve performance?

A.Use StringBuffer with collect() instead.
B.Use a sequential stream.
C.Use parallelStream with reduce.
D.Use reduce with identity "".
AnswerA

StringBuilder (or StringBuffer) as a mutable reduction with collect() reduces intermediate allocations.

Why this answer

`StringBuffer` is mutable and thread-safe, making it efficient for accumulating strings in a parallel or sequential stream via `collect()`. The `reduce()` operation with `concat()` creates a new `String` object for each pair, leading to O(n) string copying and quadratic time complexity. Using `collect()` with `StringBuffer` avoids this overhead by reusing a mutable buffer.

Exam trap

The trap here is that candidates assume `reduce()` with an identity or parallel streams will fix performance, but the core issue is the immutable nature of `String` concatenation, which `collect()` with a mutable container like `StringBuffer` or `StringBuilder` resolves.

How to eliminate wrong answers

Option B is wrong because using a sequential stream does not address the fundamental inefficiency of `reduce()` with `concat()`, which still creates many intermediate `String` objects. Option C is wrong because `parallelStream` with `reduce()` would introduce thread-safety issues and still suffer from string copying overhead, potentially degrading performance further. Option D is wrong because providing an identity `""` to `reduce()` does not change the underlying concatenation mechanism; it still creates new `String` objects per reduction step.

21
Multi-Selectmedium

Which three are terminal operations of the Stream interface? (Choose three.)

Select 3 answers
A.filter
B.map
C.reduce
D.forEach
E.collect
AnswersC, D, E

The `reduce` operation is a terminal operation because it processes all elements in the stream to produce a single, aggregated result (e.g., a sum or concatenation), thereby consuming the stream and preventing any further chaining of intermediate operations. This satisfies the constraint that a terminal operation must trigger the stream pipeline's execution and close the stream.

Why this answer

(reduce) is correct because it is a terminal operation that processes all elements of a stream to produce a single result (e.g., sum, concatenation). Terminal operations trigger the stream pipeline execution and close the stream, after which no further operations can be performed.

Exam trap

In the OCP Java 17 exam, this question tests the distinction between intermediate and terminal operations. The trap is that candidates may confuse intermediate operations like filter and map (which are lazy and return streams) with terminal operations that produce a result or side effect and close the stream.

22
MCQeasy

A stream pipeline uses the peek method for debugging. Which statement about peek is correct?

A.peek is a terminal operation that prints elements.
B.peek can only be used with parallel streams.
C.peek is an intermediate operation used for debugging; it is not suitable for production side effects.
D.peek is an intermediate operation, and it is guaranteed to be executed for each element.
AnswerC

Correct: Peek is intended for debugging and should not be used for production side effects because its execution is not guaranteed.

Why this answer

The `peek` method is an intermediate operation in the Stream API, designed primarily for debugging to observe elements as they flow through the pipeline. It is not intended for production side effects because its execution is not guaranteed for every element (e.g., due to short-circuiting or optimization), and relying on it for stateful operations can lead to unpredictable behavior.

Exam trap

The trap here is that candidates assume `peek` is a terminal operation or that it always executes for every element, confusing it with `forEach` or ignoring the Stream API's lazy evaluation and optimization guarantees.

How to eliminate wrong answers

Option A is wrong because `peek` is an intermediate operation, not a terminal operation; it returns a new stream and does not trigger pipeline execution. Option B is wrong because `peek` can be used with both sequential and parallel streams; it is not restricted to parallel streams. Option D is wrong because `peek` is not guaranteed to be executed for each element; the Stream API may skip `peek` calls due to optimizations like short-circuiting (e.g., with `limit()`) or lazy evaluation, making it unreliable for side effects.

23
MCQmedium

Refer to the exhibit. What is the output?

A.apple, banana, cherry
B.banana, cherry
C.apple, banana, cherry,
D.apple, banana, cherry, date
AnswerA

Filter with length > 4 keeps 'apple' (5), 'banana' (6), 'cherry' (6). 'date' (4) is filtered out. Joined with ', '.

Why this answer

The code uses `Collectors.joining(", ")` which concatenates the stream elements into a single string separated by ", ". The stream contains three elements: "apple", "banana", and "cherry". The joining collector does not add a trailing delimiter, so the output is exactly "apple, banana, cherry".

Exam trap

The trap here is that candidates may mistakenly think `joining(", ")` adds a trailing delimiter after the last element, similar to how some other languages handle string joins, or they may forget that the stream contains exactly the elements listed and not an extra "date".

How to eliminate wrong answers

Option B is wrong because it omits "apple", which would only happen if the stream started from index 1 or if an element was filtered out; the stream processes all three elements. Option C is wrong because `Collectors.joining(", ")` does not append a trailing comma or space after the last element; a trailing delimiter would only appear if using `joining(", ", "", ",")` with a suffix. Option D is wrong because "date" is not present in the stream; the stream contains exactly three elements: "apple", "banana", and "cherry".

24
MCQeasy

A developer is converting legacy for loops to streams. The legacy code: List<Integer> list = new ArrayList<>(); for (String s : strings) { if (s.length() > 5) { list.add(s.length()); } } They write: List<Integer> list = strings.stream() .filter(s -> s.length() > 5) .map(s -> s.length()) .collect(Collectors.toList()); But it doesn't compile. The error is: 'cannot find symbol: method collect(Collector<Object,?,List<Object>>)'. What is the likely issue?

A.The lambda in filter is incorrectly written; it should be s.length > 5.
B.The map operation returns an IntStream, which does not have a collect method. Use map(s -> s.length()).boxed().collect(...) or mapToInt(...).boxed().
C.The stream should be made unordered to allow the collector to function.
D.Use parallelStream() to enable the collect method.
AnswerB

s.length() returns int, so map produces an IntStream. To collect to List<Integer>, you need to box to Stream<Integer>.

Why this answer

The issue is that `map(s -> s.length())` on a `Stream<String>` returns an `IntStream`, not a `Stream<Integer>`. The `IntStream` interface does not have a `collect(Collector)` method; it only has `collect(Supplier, BiConsumer, BiConsumer)`. To use `Collectors.toList()`, you must convert the `IntStream` back to a `Stream<Integer>` via `.boxed()`, or use `mapToInt(...).boxed()`, or use `map(s -> (Integer) s.length())` to keep a `Stream<Integer>`.

Exam trap

The trap here is that candidates overlook the automatic specialization of `map` to `IntStream` when the lambda returns a primitive `int`, and assume `collect(Collectors.toList())` is always available on any stream, leading them to focus on unrelated options like parallelism or ordering.

How to eliminate wrong answers

Option A is wrong because `s.length > 5` is invalid Java syntax; the correct method call is `s.length() > 5`, and the lambda syntax `s -> s.length() > 5` is already correct. Option C is wrong because making the stream unordered does not affect the availability of the `collect` method; `unordered()` is a performance hint for parallel streams and does not resolve the type mismatch. Option D is wrong because `parallelStream()` would still produce an `IntStream` after `map(s -> s.length())`, and the `collect` method would still be missing; parallelism does not change the stream type.

25
MCQmedium

Refer to the exhibit. What is the output?

A.10
B.null
C.-1
D.Optional.empty
AnswerC

Correct.

Why this answer

The filter n > 100 yields an empty stream. findFirst returns an empty Optional. orElse(-1) returns -1.

26
MCQeasy

The code fails to compile. What is the reason?

A.The collect method is not applicable for a Stream<Character>.
B.The method reference String::chars is not a valid method reference.
C.The chars() method returns a Stream<Character>, but flatMap requires a function that returns a Stream<Integer>.
D.The flatMap method requires a function that returns a Stream, but String::chars returns an IntStream.
AnswerD

flatMap expects a Function returning a Stream<? extends R>, but chars() returns IntStream, which is not a Stream.

Why this answer

The `chars()` method on `String` returns an `IntStream`, not a `Stream<Character>`. The `flatMap` method on a `Stream<String>` expects a function that returns a `Stream<?>`, but `String::chars` returns an `IntStream`, which is a primitive stream and not a subtype of `Stream<?>`. This type mismatch causes a compilation error.

Exam trap

The trap here is that candidates often assume `String::chars` returns a `Stream<Character>` because it deals with characters, but it actually returns an `IntStream`, leading to a type mismatch when used with `flatMap`.

How to eliminate wrong answers

Option A is wrong because `collect` is applicable to `Stream<Character>`; the issue is not with `collect` but with the intermediate `flatMap` operation. Option B is wrong because `String::chars` is a valid method reference; it refers to the `chars()` method of `String`, which returns an `IntStream`. Option C is wrong because `chars()` returns an `IntStream`, not a `Stream<Character>`, and `flatMap` requires a function that returns a `Stream`, but the mismatch is that `IntStream` is not a `Stream<Integer>`.

27
MCQmedium

Refer to the exhibit. What is the output?

A.30
B.0
C.12
D.20
AnswerC

Correct. (2*2)+(4*2)=4+8=12.

Why this answer

(12). The exhibit shows a stream reduction with identity value 1 and elements 2, 3, 2. The reduce operation multiplies each element with the accumulated result: 1 * 2 = 2, 2 * 3 = 6, 6 * 2 = 12.

The identity is the starting accumulator, not a stream element.

Exam trap

Candidates often misunderstand the identity value in reduce operations. A common mistake is to think the identity is an additional stream element, or to use the wrong identity (e.g., 0 for multiplication), which would yield 0. In this example, the identity 1 and multiplication accumulate the elements 2, 3, 2 to 12.

How to eliminate wrong answers

Option A is wrong because 30 would result from using an identity of 0 and summing the elements (0+2+3+2=7, not 30) or from a different operation; it does not match the multiplication reduction with identity 1. Option B is wrong because 0 would result from using an identity of 0 in a multiplication reduction (0 * any element = 0), but the identity here is 1, not 0. Option D is wrong because 20 would result from multiplying 2*3*2=12 and then adding 8 or some other incorrect operation; it does not correspond to the sequential multiplication with identity 1.

28
MCQeasy

Which code will successfully produce an Optional<Integer> that contains the maximum value from a list of integers?

A.B and D both produce Optional<Integer>.
B.list.stream().collect(Collectors.maxBy(Integer::compareTo))
C.list.stream().max()
D.list.stream().max(Integer::compareTo)
AnswerA

Both B and C compile and produce an Optional<Integer> with the maximum element.

Why this answer

Option A is correct because it states that options B and D both produce Optional<Integer>. Option B uses list.stream().collect(Collectors.maxBy(Integer::compareTo)), which returns an Optional<Integer> containing the maximum element. Option D uses list.stream().max(Integer::compareTo), which also returns an Optional<Integer> with the maximum element.

Option C, list.stream().max() without arguments, fails to compile because the Stream.max() method requires a Comparator. Therefore, A is the correct choice.

Exam trap

Oracle tests that Stream.max(Comparator) and Collectors.maxBy(Comparator) both return Optional<T>. Also, calling max() without a Comparator on a Stream<T> does not compile; this is distinct from IntStream.max().

How to eliminate wrong answers

Option B is correct because Collectors.maxBy(Integer::compareTo) returns an Optional<Integer> containing the maximum element. Option C is correct because list.stream().max() on a Stream<Integer> uses natural ordering (Integer implements Comparable) and returns Optional<Integer>. Option D is wrong because list.stream().max(Integer::compareTo) is syntactically invalid; max() expects a Comparator argument, but Integer::compareTo is a method reference that returns an int, not a Comparator—the correct form would be max(Integer::compareTo) if Integer::compareTo were a Comparator, but it is not; the proper comparator is Comparator.naturalOrder() or Comparator.comparingInt(Integer::intValue).

29
MCQmedium

A developer wants to collect elements from a stream into an immutable List. Which collector should be used?

A.Collectors.toList()
B.Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)
C.Collectors.toList().stream().collect(Collectors.toUnmodifiableList())
D.Collectors.toUnmodifiableList()
AnswerD

Correct: Returns an unmodifiable list.

Why this answer

`Collectors.toUnmodifiableList()` directly returns a collector that accumulates elements into an immutable `List`. This was introduced in Java 10 and guarantees that the resulting list cannot be modified, throwing `UnsupportedOperationException` on any mutation attempt.

Exam trap

The trap here is that candidates may think `Collectors.toList()` returns an immutable list (since it's often used in read-only contexts), or they may overcomplicate the solution by chaining collectors when a direct method exists.

How to eliminate wrong answers

Option A is wrong because `Collectors.toList()` returns a mutable `List` (typically an `ArrayList`), not an immutable one. Option B is wrong because although `Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)` does produce an unmodifiable list, it is unnecessarily verbose and less efficient than the direct `toUnmodifiableList()` method; it also wraps a mutable list rather than creating a truly immutable list from the start. Option C is wrong because `Collectors.toList().stream().collect(Collectors.toUnmodifiableList())` is syntactically invalid — `Collectors.toList()` returns a `Collector`, not a `Stream`, so calling `.stream()` on it is a compile-time error.

30
MCQeasy

What does the following code print? List<Integer> list = List.of(1, 2, 3, 4, 5); list.stream().filter(i -> i % 2 == 0).forEach(System.out::print);

A.No output
B.12345
C.135
D.24
AnswerD

Correct.

Why this answer

The stream filters only even numbers (i % 2 == 0) from the list, producing 2 and 4, which are then printed sequentially via forEach. The filter operation retains elements where the predicate is true, so only 2 and 4 satisfy the condition.

Exam trap

The trap here is that candidates often confuse the filter predicate (i % 2 == 0) with selecting odd numbers, or they forget that filter retains matching elements rather than removing them, leading to selection of option C or B.

How to eliminate wrong answers

Option A is wrong because the stream pipeline does produce output; the filter does not eliminate all elements, so there is output. Option B is wrong because it prints all numbers (1,2,3,4,5), which would occur if no filter were applied, but the filter removes odd numbers. Option C is wrong because it prints odd numbers (1,3,5), which is the opposite of the filter condition (i % 2 == 0 selects even numbers).

31
Multi-Selecteasy

Which TWO of the following are characteristics of a well-designed lambda expression? (Choose two.)

Select 2 answers
A.Is stateless
B.Throws exceptions that are not declared in the functional interface's abstract method
C.Uses the same variable name as a parameter in the enclosing scope (shadowing)
D.Uses only effectively final variables from the enclosing scope
E.Modifies local variables of the enclosing method
AnswersA, D

Stateless lambdas are safer, especially in parallel streams, as they avoid race conditions.

Why this answer

A well-designed lambda expression should be stateless, meaning it does not depend on or modify mutable state from the enclosing scope. This ensures that the lambda can be safely executed in parallel streams without race conditions or side effects, aligning with the functional programming paradigm promoted by Java streams.

Exam trap

Oracle often tests the misconception that shadowing or modifying local variables is acceptable in lambdas, but the exam specifically requires understanding that only effectively final variables can be captured and that stateful lambdas are discouraged in well-designed code.

32
MCQhard

Assuming the code runs in a multithreaded environment, which statement best describes the behavior?

A.The code will compile but throw an exception at runtime because of the use of parallel stream with stateful lambda.
B.It prints the doubled numbers in order (2, 4, 6, 8) and results contains [1,2,3,4] in that order.
C.It may produce a ConcurrentModificationException because results is modified while iterating.
D.It prints the doubled numbers in a non-deterministic order and results may contain missing or duplicate entries.
AnswerD

Correct: Parallel stream processes elements concurrently, so the order of map execution is non-deterministic. The shared results list is not thread-safe, leading to data corruption.

Why this answer

Using a parallel stream with a stateful lambda (e.g., modifying an external `results` list inside `peek` or `forEach`) introduces data races and non-deterministic behavior. The `peek` operation is not synchronized, so the order of printed doubled numbers is unpredictable, and concurrent modifications to the shared `results` list can cause missing or duplicate entries due to race conditions.

Exam trap

Oracle often tests the misconception that ConcurrentModificationException is the only risk when modifying a collection from multiple threads, but the actual trap here is that parallel streams with stateful lambdas cause data races leading to missing or duplicate entries, not necessarily an exception.

How to eliminate wrong answers

Option A is wrong because the code compiles and does not throw an exception solely due to using a parallel stream with a stateful lambda; the issue is data corruption, not an exception. Option B is wrong because parallel streams do not guarantee encounter order for non-terminal operations like `peek`, and the `results` list is not thread-safe, so neither the printed numbers nor the list order is deterministic. Option C is wrong because `ConcurrentModificationException` is typically thrown when a collection is structurally modified while being iterated via its own iterator, but here the modification occurs via `add` on a separate thread, which may cause race conditions but not necessarily that specific exception; the primary risk is missing or duplicate entries, not a guaranteed exception.

33
MCQhard

A company runs a Java 17 microservice that processes real-time financial transactions. The application receives a large number of transactions per second, each with a timestamp, amount, and type. The current implementation uses a sequential stream to filter and aggregate transactions into a Map<TransactionType, DoubleSummaryStatistics>. The team observes high latency and CPU spikes during peak loads. They suspect the stream pipeline is inefficient. The pipeline code is: Map<TransactionType, DoubleSummaryStatistics> stats = transactions.stream() .filter(t -> t.getTimestamp().isAfter(Instant.now().minusSeconds(60))) .collect(Collectors.groupingBy(Transaction::getType, Collectors.summarizingDouble(Transaction::getAmount))); The transactions list is an ArrayList that is frequently modified by other threads (adding new transactions). The system has multiple CPU cores available. Which of the following changes is the MOST effective way to improve performance while maintaining correctness?

A.Use .stream().parallel() with a custom thread pool and ensure the stream source is not modified during operation.
B.Use .parallelStream() on a snapshot (new ArrayList<>(transactions)) and keep the same collector.
C.Replace ArrayList with CopyOnWriteArrayList and use .parallelStream() with the same collector.
D.Replace the collector with Collectors.groupingByConcurrent() and use .parallelStream() directly on the original list.
AnswerB

Correct. The snapshot eliminates concurrent modification issues, and parallel processing improves throughput.

Why this answer

Taking a snapshot via new ArrayList<>(transactions) provides a consistent, immutable view for the stream, reducing contention and allowing parallelStream to leverage multiple cores. However, the copy operation itself is not thread-safe and can throw ConcurrentModificationException if the list is being modified simultaneously. Despite this risk, option B is the most effective among the choices because it attempts to isolate the stream from concurrent modifications and uses a parallel-friendly collector.

To guarantee correctness, additional synchronization would be required, but none of the other options offer a better combination of performance and safety.

34
MCQmedium

A team implements a stream pipeline that processes a large dataset in parallel. They use a stateful lambda expression inside the map operation to maintain a count. What is the most likely outcome?

A.The pipeline will produce correct results if the stateful lambda is synchronized.
B.The pipeline will produce non-deterministic results due to race conditions.
C.The pipeline will throw a ConcurrentModificationException.
D.The pipeline will always produce the same result regardless of parallelism.
AnswerB

Stateful lambdas in parallel streams are discouraged because they introduce shared mutable state that leads to race conditions and unpredictable results.

Why this answer

Using a stateful lambda (one that mutates shared mutable state) inside a parallel stream's map operation introduces race conditions. The map operation is intended to be stateless and non-interfering; when multiple threads concurrently update a shared counter without proper synchronization, the result becomes non-deterministic and unpredictable.

Exam trap

The trap here is that candidates assume synchronization or thread-safety fixes the issue, but the Streams API's contract requires stateless lambdas for correctness in parallel pipelines, and synchronization does not restore deterministic behavior or guarantee correct results.

How to eliminate wrong answers

Option A is wrong because even if the stateful lambda is synchronized, the synchronization will cause severe contention and may still produce incorrect results if the lambda is not properly thread-safe or if the ordering of updates is not guaranteed; the Java Streams API explicitly discourages stateful lambdas in parallel pipelines. Option C is wrong because ConcurrentModificationException is thrown when a collection is structurally modified while being iterated, not from a stateful lambda in a map operation that merely updates a counter. Option D is wrong because the pipeline will not always produce the same result; the non-determinism arises from the unpredictable interleaving of thread updates to the shared mutable state.

35
MCQhard

A team is developing a real-time data processing pipeline that reads sensor data from a message queue. The pipeline uses a flatMap operation that calls an external geocoding service for each sensor reading. The external service has a rate limit of 10 requests per second and is slow (150ms average response time). The current code: sensorStream.parallelStream() .flatMap(reading -> getGeocode(reading).stream()) .forEach(system.out::println); The application is overloaded because parallel stream fires many concurrent requests, exceeding the rate limit and causing failures. They need to process all sensor data but must respect the rate limit. Which approach should they use?

A.Use a sequential stream with a custom rate limiter (e.g., a semaphore) that blocks when the limit is reached.
B.Reduce the parallelism level by using a custom thread pool with a fixed number of threads.
C.Use filter to drop some sensor readings to reduce the load.
D.Use a sequential stream and hope the processing completes within the time window.
AnswerA

A sequential stream combined with a rate limiter ensures requests are sent at a controlled pace, respecting the external service limits.

Why this answer

Using a sequential stream with a custom rate limiter (e.g., a Semaphore configured to allow only 10 permits per second) ensures that the external geocoding service is called at a controlled rate, preventing rate-limit violations. The sequential stream processes elements one at a time, and the rate limiter blocks the thread when the limit is reached, naturally throttling requests to stay within the 10 requests/second limit while still processing all data.

Exam trap

The trap here is that candidates often assume that reducing parallelism (Option B) is sufficient to control request rates, but they overlook that even a small fixed thread pool can still exceed a low rate limit if requests are made too quickly, and that a rate limiter with temporal control is required to precisely throttle requests per second.

How to eliminate wrong answers

Option B is wrong because reducing parallelism with a fixed thread pool still allows concurrent requests (up to the pool size), which can exceed the 10 requests/second rate limit if the pool size is greater than 1 and requests are made faster than the rate limit allows; it does not provide fine-grained temporal control over request timing. Option C is wrong because using filter to drop some sensor readings would lose data, which violates the requirement to process all sensor data. Option D is wrong because using a sequential stream without any rate-limiting mechanism does not guarantee that the processing rate will stay within the 10 requests/second limit; the stream may still process requests faster than the limit allows, leading to rate-limit failures.

36
MCQeasy

A lambda expression that takes two integers and returns a boolean indicating whether the first is greater than the second is best represented by which functional interface?

A.BiFunction<Integer, Integer, Boolean>
B.Predicate<Integer>
C.BinaryOperator<Boolean>
D.BiPredicate<Integer, Integer>
AnswerD

Correct. BiPredicate<Integer, Integer> is the functional interface for two input arguments returning a boolean.

Why this answer

BiPredicate<Integer, Integer> is a functional interface that takes two arguments (both Integer) and returns a boolean, which exactly matches the lambda expression's signature (int, int) -> boolean. The lambda can be written as (a, b) -> a > b, and BiPredicate is the standard interface for such two-argument boolean-valued operations.

Exam trap

The trap here is that candidates often confuse BiPredicate with BiFunction or Predicate, mistakenly thinking a two-argument boolean operation can be represented by a single-argument Predicate or by a BiFunction that returns a Boolean, but the exam tests the precise functional interface that matches the lambda's signature and return type without unnecessary boxing.

How to eliminate wrong answers

Option A is wrong because BiFunction<Integer, Integer, Boolean> takes two Integer arguments and returns a Boolean object, but it is not the best representation; it requires boxing/unboxing and is less idiomatic than BiPredicate, which directly returns a primitive boolean. Option B is wrong because Predicate<Integer> takes only one Integer argument and returns a boolean, but the lambda requires two integers, so it cannot represent the operation. Option C is wrong because BinaryOperator<Boolean> takes two Boolean arguments and returns a Boolean, but the lambda takes two integers, not Booleans, and returns a boolean; it is semantically incorrect for comparing integers.

37
MCQmedium

Refer to the exhibit. What is the output?

A.[one, two, three, four]
B.[two]
C.[two, three]
D.[one, four]
AnswerC

Filter with startsWith("t") keeps 'two' and 'three'.

Why this answer

The code uses `dropWhile` on a stream of strings, which drops elements from the stream as long as the predicate (string length < 5) is true. Once the predicate becomes false (for "three", length 5), it stops dropping and includes all remaining elements. The stream then skips the first element with `skip(1)`, resulting in ["two", "three"].

Exam trap

The trap here is confusing `dropWhile` with `filter` — candidates often think `dropWhile` removes all elements matching the predicate, but it only removes the leading prefix until the first non-match, then includes everything after.

How to eliminate wrong answers

Option A is wrong because it assumes the stream processes all elements and collects them unchanged, ignoring the `dropWhile` and `skip` operations. Option B is wrong because it incorrectly thinks `dropWhile` removes all elements that match the predicate, leaving only "two" (which does not match), but `dropWhile` stops dropping after the first non-matching element. Option D is wrong because it mistakenly believes `dropWhile` removes all matching elements and then `skip(1)` removes the first remaining, but the actual behavior preserves "two" and "three".

38
MCQmedium

A developer uses a parallel stream to process a large collection and wants to collect results into a List while preserving encounter order. Which of the following collectors will guarantee order preservation?

A.collect(Collectors.toUnmodifiableList())
B.collect(Collectors.toList())
C.collect(Collectors.toMap(Function.identity(), v->v))
D.collect(ArrayList::new, List::add, List::addAll)
E.collect(Collectors.toCollection(TreeSet::new))
AnswerD

This custom collector preserves encounter order because it adds elements sequentially in the accumulator and merges lists in order.

Why this answer

The custom collector using `ArrayList::new`, `List::add`, and `List::addAll` explicitly specifies an insertion-ordered collection (`ArrayList`) and uses the combiner `List::addAll`, which preserves the encounter order when merging partial results from parallel streams. The `Collectors.toList()` and `Collectors.toUnmodifiableList()` do not guarantee order preservation in parallel streams, as their internal implementations may use non-ordered structures like `HashSet` during accumulation.

Exam trap

The trap here is that candidates assume `Collectors.toList()` always preserves encounter order, but the Java specification explicitly states it does not guarantee order in parallel streams, and the exam tests this subtle distinction.

How to eliminate wrong answers

Option A is wrong because `Collectors.toUnmodifiableList()` does not guarantee encounter order preservation in parallel streams; its internal implementation may use a non-ordered intermediate structure. Option B is wrong because `Collectors.toList()` makes no ordering guarantees in parallel streams; the specification explicitly states that it does not preserve encounter order. Option C is wrong because `Collectors.toMap()` uses a `HashMap` by default, which does not maintain insertion order, and the merge function is not provided, causing an `IllegalStateException` on duplicate keys.

Option E is wrong because `TreeSet` sorts elements by their natural order or a comparator, not by encounter order, thus destroying the original stream order.

39
Multi-Selecthard

Which TWO statements are true about the Stream API and lambda expressions in Java 17?

Select 2 answers
A.The Stream API does not modify the original data source.
B.Lambda expressions can capture variables that are effectively final.
C.A stream can be consumed by multiple terminal operations sequentially.
D.Intermediate operations on a stream are executed eagerly.
E.Lambda expressions introduce a new level of scope, similar to an anonymous inner class.
AnswersA, B

Streams operate on a view of the data; they do not modify the underlying collection or array.

Why this answer

The Stream API is designed to work on a view of the data, not the data itself. Operations like filter, map, and collect produce new streams or results without altering the original collection, array, or I/O source. This non-interference guarantee is a core principle of the Stream API, ensuring safe parallel execution and functional programming style.

Exam trap

The trap here is that candidates often confuse the lazy evaluation of intermediate operations with eager execution, or mistakenly believe a stream can be reused after a terminal operation, leading them to select options C or D.

40
Multi-Selecthard

Which THREE of the following are valid ways to create an infinite stream? (Choose three.)

Select 3 answers
A.IntStream.generate(() -> 0)
B.Stream.iterate(1, n -> n+1)
C.IntStream.range(0, Integer.MAX_VALUE)
D.Stream.generate(Math::random)
E.Stream.of(1,2,3)
AnswersA, B, D

Generates an infinite IntStream of zeros.

Why this answer

`IntStream.generate(() -> 0)` uses a supplier that always returns 0, producing an infinite stream of zeros. The `generate` method creates an unordered infinite stream by repeatedly invoking the supplier, with no termination condition.

Exam trap

The trap here is that candidates mistakenly think `IntStream.range(0, Integer.MAX_VALUE)` is infinite because the upper bound is large, but it is actually a finite stream that terminates after producing Integer.MAX_VALUE elements.

41
MCQmedium

A developer is refactoring a legacy codebase to use streams. The original code iterates over a list of 'Order' objects, filters orders with status 'PENDING', sorts them by date, and collects the order IDs into a set. Which stream pipeline correctly replaces this logic?

A.orders.stream().filter(o->o.getStatus().equals("PENDING")).sorted(Comparator.comparing(Order::getDate)).collect(Collectors.toSet())
B.orders.stream().filter(o->o.getStatus().equals("PENDING")).map(Order::getId).sorted().collect(Collectors.toSet())
C.orders.stream().sorted(Comparator.comparing(Order::getDate)).filter(o->o.getStatus().equals("PENDING")).map(Order::getId).collect(Collectors.toSet())
D.orders.stream().filter(o->o.getStatus().equals("PENDING")).sorted(Comparator.comparing(Order::getDate)).map(Order::getId).collect(Collectors.toSet())
AnswerD

Ly filters by status 'PENDING', sorts by date using a Comparator, maps to order IDs, and collects into a Set, matching the original logic.

Why this answer

It first filters orders with status 'PENDING', then sorts them by date using a Comparator, then maps each Order to its ID, and finally collects the IDs into a Set. This preserves the original logic: filter before sorting (to reduce the number of elements to sort), and map after sorting (since sorting requires Order objects, not IDs). Collecting into a Set automatically deduplicates IDs, matching the original intent.

Exam trap

The exam often tests the order of stream operations, specifically that sorting must occur before mapping when the sort key is a property of the original object, and that filtering early improves efficiency.

How to eliminate wrong answers

Option A is wrong because it collects Order objects into a Set without mapping to IDs, so it returns a Set<Order> instead of a Set<ID>. Option B is wrong because it sorts the IDs (after mapping) rather than sorting the Order objects by date, which changes the sorting semantics. Option C is wrong because it sorts before filtering, which is less efficient and could produce different results if the sorting comparator depends on filtered-out elements (though not an issue here, it violates the intended order of operations).

42
Multi-Selectmedium

Which TWO are valid lambda expressions? (Choose two.) A. (int a, int b) -> a + b B. a, b -> a + b C. (a, b) -> a + b D. (a, b) -> { a + b; } E. (int a, b) -> a + b

Select 2 answers
A.(int a, int b) -> a + b
B.a, b -> a + b
C.(a, b) -> a + b
D.(a, b) -> { a + b; }
E.(int a, b) -> a + b
AnswersA, C

Valid: explicit types are allowed in lambda parameter lists.

Why this answer

Options A and C are valid lambda expressions. Option A uses explicit parameter types, which is allowed in lambda expressions. Option C uses inferred types with parentheses, also valid.

Option B is invalid because multiple lambda parameters require parentheses. Option D is invalid because the block body does not contain a return statement, and the expression statement a + b; is not a valid return statement. Option E is invalid because it mixes explicit and inferred parameter types; if one parameter has an explicit type, all must have explicit types.

Exam trap

A common trap is assuming that parentheses can be omitted for multiple parameters. In Java, lambda expressions with multiple parameters always require parentheses around the parameter list.

43
MCQeasy

A developer needs to concatenate two Stream<String> into one. Which approach is most idiomatic?

A.stream1.flatMap(s -> stream2)
B.new StreamBuilder().add(stream1).add(stream2).build()
C.Stream.concat(stream1, stream2)
D.stream1.merge(stream2)
AnswerC

Correct: Static method that returns a concatenated stream.

Why this answer

`Stream.concat(stream1, stream2)` is the idiomatic, built-in static method in the Java Stream API for concatenating two streams into a single sequential stream. It creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream, preserving encounter order.

Exam trap

The trap here is that candidates may confuse `flatMap` with concatenation or assume a non-existent `merge` method exists, because they recall similar operations from other APIs like `Map.merge()` or reactive streams, but the Java Stream API specifically provides `concat()` for this purpose.

How to eliminate wrong answers

Option A is wrong because `stream1.flatMap(s -> stream2)` does not concatenate the streams; it attempts to replace each element of stream1 with the entire stream2, which would produce a stream of streams (or cause a compilation error if stream2 is not a stream of the same type). Option B is wrong because `StreamBuilder` is not a standard Java class; the correct builder is `Stream.builder()`, and even then it does not accept streams as arguments—only individual elements. Option D is wrong because `merge` is not a method defined in the `Stream` interface; it is a method in other contexts like `Map.merge()` or reactive libraries, but not in the standard Java Stream API.

44
MCQeasy

A developer writes the following code using the Stream API: List<String> list = List.of("a", "b", "c"); String result = list.stream().reduce("", (s1, s2) -> s1 + s2); System.out.println(result); What is the output?

A.abc
B.a
C.Optional[abc]
D.cba
AnswerA

Correct concatenation.

Why this answer

The `reduce` method with an identity value (`""`) and a binary operator (`(s1, s2) -> s1 + s2`) accumulates the stream elements in encounter order. Starting from the identity, it concatenates each element: `"" + "a" = "a"`, then `"a" + "b" = "ab"`, then `"ab" + "c" = "abc"`. The result is a `String`, not an `Optional`, because an identity is provided.

Exam trap

The trap here is that candidates often confuse the `reduce` overloads, mistakenly thinking that all `reduce` operations return an `Optional`, or they forget that the identity value is included in the accumulation, leading them to expect an `Optional` wrapper or a reversed order.

How to eliminate wrong answers

Option B is wrong because it suggests only the first element is output, but `reduce` with a binary operator processes all elements sequentially, not just the first. Option C is wrong because when an identity value is supplied to `reduce`, the return type is the same as the identity type (`String`), not `Optional<String>`; `Optional` is only returned when using the overloaded `reduce` without an identity. Option D is wrong because the stream's encounter order is preserved from the list `["a", "b", "c"]`, and the accumulator concatenates in that order, not reversed; reversing would require a different operation like `sorted(Comparator.reverseOrder())`.

45
MCQhard

What is the output of the following code? ```java System.out.println(Stream.of(1, 2).map(i -> i * 2.0).count()); ```

A.2.0
B.1
C.2
D.Compilation error
AnswerC

6/3 = 2, printed as 2.

Why this answer

The code is:

```java

System.out.println(Stream.of(1, 2).map(i -> i * 2.0).count());

```

This creates a stream of integers 1 and 2, maps each to a Double (2.0 and 4.0), and then calls count() which returns the number of elements in the stream, which is 2. count() returns a long, but when printed, it outputs 2 (not 2.0). Option C is correct because the stream has two elements.

Exam trap

The trap here is that candidates may mistakenly think the `map` operation changes the return type of `count()` or that the output would be a floating-point number (2.0) because the mapping produces `Double` values, but `count()` always returns a `long` regardless of the stream's element type.

How to eliminate wrong answers

Option A is wrong because it suggests the output is 2.0, but `count()` returns a `long` (not a `Double`), and the result is printed as an integer 2, not a floating-point number. Option B is wrong because it suggests the output is 1, but the stream contains two elements (1 and 2), so the count is 2, not 1. Option D is wrong because there is no compilation error: the `map` operation returns a `Stream<Double>`, and `count()` is a valid terminal operation on any stream, returning a `long` that can be assigned to `int` without explicit cast due to implicit narrowing conversion (though a cast would be required for `long` to `int` in general, here the literal value 2 fits within `int` range, so no error).

46
MCQmedium

What is the result of executing this code?

A.An exception is thrown at runtime.
B.bbc
C.Compilation error
D.baaabc
AnswerA

IllegalStateException is thrown when a terminal operation is called on an already-consumed stream.

Why this answer

The code attempts to call `findFirst()` on a `Stream<String>` that has already been consumed by a previous terminal operation (`forEach`). In Java, streams are single-use; after a terminal operation is executed, the stream is closed and cannot be reused. Any attempt to perform another terminal operation on the same stream throws an `IllegalStateException` at runtime.

Exam trap

The trap here is that candidates often forget that streams are single-use and incorrectly assume that chaining multiple terminal operations on the same stream is allowed, leading them to pick a concatenated output like 'baaabc' instead of recognizing the runtime exception.

How to eliminate wrong answers

Option B is wrong because it assumes the stream can be reused and that `findFirst()` would return 'b', but the stream is already closed after `forEach`. Option C is wrong because the code compiles successfully; the error occurs only at runtime. Option D is wrong because it incorrectly concatenates the results of both terminal operations, which is impossible since the second operation never executes.

47
MCQhard

A team is implementing a parallel stream to process a large dataset. They notice that the operation is slower than expected. Which change is most likely to improve performance?

A.Use a sequential stream.
B.Use a custom Collector instead of reduce.
C.Increase the parallelism level by setting -Djava.util.concurrent.ForkJoinPool.common.parallelism=100.
D.Ensure the stream source is an ArrayList and the operation is stateless and associative.
AnswerD

D is correct: ArrayList splits well, and stateless/associative operations reduce merge cost.

Why this answer

Parallel stream performance depends on the stream source being efficiently splittable (like an ArrayList, which has O(1) random access and can be split evenly) and the operation being stateless and associative to avoid synchronization overhead and ensure correct results. A poorly splittable source (e.g., LinkedList) or stateful operations can cause contention and reduce parallelism gains.

Exam trap

The trap here is that candidates often assume more threads (Option C) or switching to sequential (Option A) will fix performance, overlooking that the root cause is usually an inefficiently splittable source or non-associative/stateful operations, which are the key factors the exam tests for parallel stream optimization.

How to eliminate wrong answers

Option A is wrong because switching to a sequential stream would eliminate parallelism entirely, likely making the operation slower for a large dataset, not faster. Option B is wrong because using a custom Collector instead of reduce does not inherently improve parallel performance; both can be parallelized if designed correctly, and the issue is more about the stream source and operation properties. Option C is wrong because increasing the parallelism level beyond the number of available CPU cores (e.g., setting to 100) can lead to thread contention, overhead from context switching, and diminishing returns, often degrading performance rather than improving it.

48
MCQhard

A developer writes a stream pipeline that uses flatMap and filter but notices that the intermediate streams created by flatMap are never garbage-collected early, causing memory pressure. What is the most effective optimization to reduce memory usage?

A.Move the filter operation before the flatMap operation.
B.Replace flatMap with map and collect into a list.
C.Use a terminal operation like collect with a custom collector to process elements eagerly.
D.Use a parallel stream to process elements concurrently.
AnswerA

Filtering early reduces the number of elements fed into flatMap, thereby reducing the number of intermediate streams created.

Why this answer

Moving the filter operation before flatMap reduces the number of elements passed to flatMap, thereby reducing the number of intermediate streams created and their memory footprint. Streams are lazy, so filter applied early discards unwanted elements before flatMap ever sees them, which directly lowers memory pressure from intermediate stream objects.

Exam trap

The trap here is that candidates often assume filter order doesn't matter because streams are lazy, but they overlook that intermediate stream objects from flatMap are not garbage-collected until the pipeline completes, making early filtering critical for memory efficiency.

How to eliminate wrong answers

Option B is wrong because replacing flatMap with map and collect into a list would eagerly materialize all elements into a collection, increasing memory usage rather than reducing it. Option C is wrong because using a terminal operation like collect with a custom collector does not change the lazy nature of intermediate streams; it still processes all elements and cannot force early garbage collection of intermediate stream objects. Option D is wrong because using a parallel stream does not reduce memory usage from intermediate streams; it may even increase memory overhead due to thread coordination and splitting overhead.

49
MCQeasy

A lambda that takes a String and returns its length is assigned to which functional interface?

A.UnaryOperator<String>
B.Consumer<String>
C.Predicate<String>
D.Supplier<Integer>
E.Function<String, Integer>
AnswerE

Correct. This functional interface accepts a String and returns an Integer.

Why this answer

The lambda `(String s) -> s.length()` takes a `String` input and returns an `Integer` (the length). This matches the `Function<T, R>` functional interface, which defines the abstract method `R apply(T t)`. Option E is correct because `Function<String, Integer>` exactly represents a function that accepts a `String` and produces an `Integer`.

Exam trap

The trap here is that candidates often confuse `UnaryOperator` (which requires same input/output type) with `Function` (which allows different types), leading them to pick A instead of E.

How to eliminate wrong answers

Option A is wrong because `UnaryOperator<String>` extends `Function<String, String>`, meaning it must return the same type as its input (String), not an Integer. Option B is wrong because `Consumer<String>` accepts a String but returns void (via `void accept(T t)`), so it cannot return a length. Option C is wrong because `Predicate<String>` returns a `boolean` (via `boolean test(T t)`), not an Integer.

Option D is wrong because `Supplier<Integer>` takes no input and returns an Integer (via `T get()`), but the lambda requires a String parameter.

50
MCQmedium

A developer writes: List<Integer> list = List.of(1, 2, 3); Optional<Integer> opt = list.stream().reduce((a, b) -> a + b); System.out.println(opt.get()); What is the result?

A.6
B.Optional[6]
C.Optional.empty
D.NoSuchElementException
AnswerA

Correct output.

Why this answer

The `reduce` method with a single argument (a `BinaryOperator`) returns an `Optional` because the stream might be empty. Here, the stream contains three integers, so the reduction computes `1 + 2 = 3`, then `3 + 3 = 6`, yielding `Optional[6]`. Calling `get()` on a non-empty `Optional` returns the contained value `6`, which is printed.

Exam trap

The trap here is that candidates may forget that `reduce` with one argument returns an `Optional` and incorrectly assume the output is `Optional[6]` or that `get()` throws an exception, overlooking that the stream is non-empty.

How to eliminate wrong answers

Option B is wrong because `opt.get()` extracts the value from the `Optional`, so the output is `6`, not `Optional[6]`. Option C is wrong because the stream is not empty; it has three elements, so the `Optional` is not empty. Option D is wrong because `NoSuchElementException` would only be thrown if `get()` were called on an empty `Optional`, which does not occur here.

51
MCQmedium

A company uses a large dataset of customer orders. They want to compute statistics: total orders, average amount, and maximum amount per city. They write: Map<String, IntSummaryStatistics> stats = orders.stream() .collect(Collectors.groupingBy(Order::getCity, Collectors.summarizingInt(Order::getAmount))); The code works but is slower than expected when run on a large dataset. They suspect the grouping operation is not taking advantage of parallelism. They want to improve performance by making the collector concurrent. Which change is correct?

A.Use Collectors.groupingByConcurrent(Order::getCity, Collectors.summarizingInt(Order::getAmount)).
B.Use parallelStream() instead of stream().
C.Keep the code but supply a ConcurrentHashMap as the map supplier to groupingBy.
D.Replace collect with forEach and manually update a ConcurrentHashMap.
AnswerA

Correct. `Collectors.groupingByConcurrent` performs a concurrent reduction, using a `ConcurrentHashMap` internally, which allows efficient parallel processing with `parallelStream()`, reducing contention.

Why this answer

`Collectors.groupingByConcurrent` performs an unordered, concurrent reduction that can leverage a `ConcurrentHashMap` internally, allowing the collector to work efficiently with a parallel stream. This reduces contention and improves performance on large datasets compared to the sequential `groupingBy`.

Exam trap

The trap here is that candidates think `parallelStream()` alone is sufficient for concurrent grouping, but they overlook that the collector itself must be designed for concurrent accumulation to avoid contention and ensure thread safety.

How to eliminate wrong answers

Option B is wrong because simply calling `parallelStream()` without changing the collector does not make the grouping operation concurrent; `groupingBy` still uses a sequential `Map` and can cause thread contention. Option C is wrong because supplying a `ConcurrentHashMap` as the map supplier to `groupingBy` does not make the collector itself concurrent; the downstream collector `summarizingInt` is still applied sequentially, and the overall reduction is not thread-safe. Option D is wrong because manually updating a `ConcurrentHashMap` inside a `forEach` with a parallel stream can lead to race conditions on the `IntSummaryStatistics` objects, which are not thread-safe, and it bypasses the optimized concurrent reduction logic.

52
MCQeasy

A method returns an Optional<String>. The developer wants to transform the value inside the Optional to uppercase and print it, but only if present. Which best-practice approach uses streams?

A.opt.map(String::toUpperCase).ifPresent(System.out::println);
B.opt.ifPresent(s -> System.out.println(s.toUpperCase()));
C.opt.stream().map(String::toUpperCase).forEach(System.out::println);
D.Stream.of(opt).map(o -> o.get().toUpperCase()).forEach(System.out::println);
AnswerC

This converts Optional to a stream of one or zero elements, applies transformation, and prints. It is a stream-based best practice.

Why this answer

It converts the Optional to a Stream using opt.stream(), then applies map(String::toUpperCase) to transform the value, and finally uses forEach(System.out::println) to print it only if present. This approach leverages the Stream API's lazy evaluation and functional pipeline, which is the best practice for integrating Optional with streams.

Exam trap

The trap here is that candidates may overlook the 'uses streams' constraint and pick A or B, which are valid Optional operations but not stream-based, or pick D which misuses Stream.of to wrap the Optional instead of converting it.

How to eliminate wrong answers

Option A is wrong because opt.map(String::toUpperCase).ifPresent(System.out::println) uses Optional's map and ifPresent, not streams; the question explicitly asks for a 'streams' approach. Option B is wrong because opt.ifPresent(s -> System.out.println(s.toUpperCase())) is a direct Optional consumer, not a stream-based solution. Option D is wrong because Stream.of(opt) creates a stream of Optional, not the contained value, and calling o.get() is unsafe (throws NoSuchElementException if empty) and violates the 'only if present' requirement.

53
MCQhard

Given a list of integers, a developer wants to compute the sum of squares of numbers greater than 10. The following code is written: int sum = list.stream().filter(i -> i>10).mapToInt(i->i*i).sum(); But the sum is incorrect. What is the most likely reason?

A.The mapToInt operation is not allowed after filter.
B.The stream is not sorted.
C.The list might contain nulls causing NullPointerException.
D.The filter should be before mapToInt, but it is after.
E.The sum() method returns an OptionalInt and must be orElse(0).
AnswerC

If any element is null, unboxing in i > 10 throws NPE, making the result incorrect if caught or halting execution.

Why this answer

If the list contains null elements, the lambda expression `i -> i > 10` will attempt to unbox a null `Integer` to an `int`, causing a `NullPointerException` at runtime. The stream pipeline itself is syntactically valid, but the presence of nulls in the source list is a common pitfall when using primitive-specialized operations like `mapToInt` after a filter that does not guard against nulls.

Exam trap

Oracle often tests the misconception that `sum()` returns an `OptionalInt` (like `reduce` does) or that the order of `filter` and `mapToInt` is reversed, but the real trap is the silent NullPointerException from unboxing nulls in a lambda.

How to eliminate wrong answers

Option A is wrong because `mapToInt` is perfectly allowed after `filter`; the filter returns a `Stream<Integer>`, and `mapToInt` can be called on any `Stream` of objects to produce an `IntStream`. Option B is wrong because sorting is irrelevant to computing the sum of squares; the stream does not need to be sorted for any of the operations used. Option D is wrong because the order of `filter` before `mapToInt` is correct; filtering first reduces the number of elements to square, which is efficient and logically sound.

Option E is wrong because `sum()` on an `IntStream` returns a primitive `int`, not an `OptionalInt`; `OptionalInt` is returned only by reduction operations like `reduce()` or terminal operations like `findFirst()` on an `IntStream`.

54
Multi-Selecteasy

Which two statements are true about the peek method of the Stream API? (Choose two.)

Select 2 answers
A.It is primarily used for debugging purposes.
B.It is an intermediate operation.
C.It can be used to modify the elements of the stream.
D.It is a terminal operation.
E.It can be used to transform the elements into a new value.
AnswersA, B

peek is intended to aid in debugging by allowing observation of elements as they pass through the pipeline.

Why this answer

The `peek` method is designed as a debugging aid to observe elements as they flow through a stream pipeline. It performs the provided action on each element without modifying them, making it ideal for logging or printing intermediate states.

Exam trap

The trap here is that candidates confuse `peek` with `map`, thinking `peek` can modify or transform elements, when in fact `peek` only observes and returns the same elements unchanged.

55
MCQhard

Refer to the exhibit. What is the output?

A.88.0
B.88.33333333333333
C.85.0
D.85.75
AnswerB

Correct. The average of 85, 92, and 88 is (85+92+88)/3 = 265/3 = 88.33333333333333.

Why this answer

The code creates an IntStream with values 85, 92, and 88, then calls average() to compute the arithmetic mean. This returns an OptionalDouble, and orElse(0.0) extracts the value. The sum 85+92+88 = 265, divided by 3 gives 88.33333333333333, which matches option B exactly.

No integer division occurs because average() always returns a double.

Exam trap

The trap here is that candidates might mistakenly think integer division applies (e.g., 265/3 = 88 with truncation) or misread the output format, but the stream's `average()` method always returns a `double` with full precision.

How to eliminate wrong answers

Option A is wrong because it duplicates the correct output but is listed as a separate option; the question marks B as correct, so A is not the intended answer. Option C is wrong because 85.0 would result from averaging only the first number (85) or from integer division without casting, but the stream correctly sums all three integers and divides by 3.0. Option D is wrong because 85.75 would require a different set of numbers (e.g., 85, 86, 86) or a miscalculation of the sum (265/3 = 88.333..., not 85.75).

56
MCQmedium

A company processes financial transactions. Each transaction is represented by a Transaction object with fields: amount (double), currency (String), and type (String). The requirement is to compute the total amount of all transactions of type 'SALE' in USD. The transactions are stored in a List<Transaction>. Which code correctly accomplishes this using streams?

A.transactions.stream().mapToDouble(Transaction::amount).filter(t -> t.type().equals("SALE")).sum()
B.transactions.stream().filter(t -> t.type().equals("SALE")).filter(t -> t.currency().equals("USD")).mapToDouble(Transaction::amount).sum()
C.transactions.stream().map(Transaction::amount).reduce(0.0, (a, b) -> a + b)
D.transactions.stream().filter(t -> t.type().equals("SALE") && t.currency().equals("USD")).mapToDouble(Transaction::amount).sum()
AnswerD

Correctly filters by type and currency, then sums amounts.

Why this answer

Ly filters transactions to only those with type 'SALE' and currency 'USD', then maps each to its amount as a double, and sums them using sum(). This satisfies the requirement exactly: total amount of 'SALE' transactions in USD.

Exam trap

Oracle often tests the order of stream operations — specifically that filter must come before mapToDouble when the filter condition depends on object fields, otherwise the stream loses access to the original object type.

How to eliminate wrong answers

Option A is wrong because it maps to double before filtering, so the filter cannot access the Transaction object's type field — it would attempt to filter on a double, causing a compilation error. Option B is wrong because it filters for both 'SALE' and 'USD', but the requirement only asks for 'SALE' transactions in USD — this is actually correct in logic but the filter order is inefficient; however, the real issue is that it is not the most direct answer and D is more concise. Option C is wrong because it maps all transactions to their amounts without any filtering, summing all amounts regardless of type or currency, which does not meet the requirement.

57
Multi-Selecthard

Which TWO statements about lambda expressions are true? (Choose two.) A. A lambda expression can be assigned to a functional interface variable. B. A lambda expression can access final or effectively final local variables. C. A lambda expression can throw any checked exception. D. A lambda expression can be used to create an instance of an abstract class. E. A lambda expression can be used to implement multiple abstract methods.

Select 2 answers
A.A lambda expression can throw any checked exception.
B.A lambda expression can be assigned to a functional interface variable.
C.A lambda expression can access final or effectively final local variables.
D.A lambda expression can be used to implement multiple abstract methods.
E.A lambda expression can be used to create an instance of an abstract class.
AnswersB, C

True: A lambda can be assigned to a functional interface variable because it provides an implementation for the single abstract method.

Why this answer

False: A lambda expression can only throw checked exceptions that are declared in the functional interface's abstract method, not any checked exception. Options B and C are true: a lambda can be assigned to a functional interface variable, and it can access final or effectively final local variables. Option D is false: a lambda can only implement one abstract method (functional interface).

Option E is false: lambdas cannot instantiate abstract classes; they only implement functional interfaces.

Exam trap

The trap is that candidates think lambdas can implement multiple abstract methods or instantiate abstract classes, but they can only implement a single abstract method of a functional interface.

58
MCQmedium

Refer to the exhibit. What is the output? ```java import java.util.stream.IntStream; public class Example { public static void main(String[] args) { int sum = IntStream.rangeClosed(0, 5) .filter(i -> i >= 0) .sum(); System.out.println(sum); } } ```

A.0
B.15
C.10
D.5
AnswerB

Correct.

Why this answer

The stream pipeline starts with `IntStream.rangeClosed(0, 5)` producing the integers 0, 1, 2, 3, 4, 5. The filter passes all these values, and the map is an identity function (or absent). The reduction sums them: 0+1+2+3+4+5 = 15.

Therefore, the output is 15.

Exam trap

The trap here is that candidates often miscount the number of elements produced by `rangeClosed` versus `range`, leading to off-by-one errors in the sum.

How to eliminate wrong answers

Option A is wrong because 0 would only occur if the stream was empty or the identity was used exclusively, but the stream has elements 0 through 5. Option C is wrong because 10 is the sum of 0 through 4 (5 elements) but the stream includes 5 as well, making the sum 15. Option D is wrong because 5 is the count of elements from 0 to 4, not the sum; the sum of 0 through 5 is 15.

59
Multi-Selecteasy

Which two statements about the Stream API are true? (Choose two.)

Select 2 answers
A.The 'reduce()' operation can produce a result of a different type than the stream elements.
B.The 'flatMap()' operation is a terminal operation.
C.The 'findFirst()' operation is a short-circuiting terminal operation.
D.The 'collect()' operation is an intermediate operation.
E.Streams can be reused after a terminal operation.
AnswersA, C

The `reduce()` operation can produce a result of a different type than the stream elements. For example, `stream.reduce(0, (sum, i) -> sum + i, Integer::sum)` reduces an `IntStream` to an `Integer`.

Why this answer

The `reduce()` operation in the Stream API uses a combiner function that can transform the stream elements into an accumulated result of a different type. For example, `stream.reduce(0, (sum, i) -> sum + i, Integer::sum)` returns an `Integer` from an `IntStream`, or you can reduce a `Stream<String>` to a `StringBuilder`. This is explicitly allowed by the `reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)` signature.

Exam trap

Oracle Java certification exams often test the distinction between intermediate and terminal operations. The trap here is that candidates confuse `flatMap()` (intermediate) with a terminal operation or assume `collect()` is intermediate because it doesn't produce a single value like `reduce()`, but it is terminal because it consumes the stream.

60
MCQmedium

What is the output of the code above?

A.18
B.15
C.9
D.27
AnswerA

Correct: (2*3)+(4*3)=6+12=18.

Why this answer

The code creates a stream of lists containing numbers 1 through 9, flatMaps to a single stream of integers, filters for numbers divisible by 3 (leaving 3, 6, 9), and reduces them by summing. The sum is 3+6+9=18, making option A correct.

Exam trap

Oracle often tests the interaction between `flatMap`, `filter`, and `limit` or `skip`, where candidates forget that `limit` truncates the stream after the filter, leading to an incorrect sum based on the first few elements rather than all matching elements.

How to eliminate wrong answers

Option B (15) is wrong because it would result from summing 4+5+6 (the first three numbers after filtering) but incorrectly omitting the 7, 8, 9 or miscalculating the sum. Option C (9) is wrong because it represents the sum of 4+5, or a misunderstanding of the filtering or reduction step. Option D (27) is wrong because it might come from summing 4+5+6+7+8+9 = 39 and then subtracting 12, or from a different incorrect operation like multiplying instead of summing.

61
Multi-Selecthard

Which are valid method references in Java 17?

Select 4 answers
A.String::new
B.String::isEmpty
C.null::equals
D.Math::random
E.this::toString
AnswersA, B, D, E

Valid constructor reference, equivalent to () -> new String().

Why this answer

A is a constructor reference, a valid type of method reference. B is a reference to an instance method of an arbitrary object of type String. D is a reference to a static method.

E is a reference to an instance method of the current object, valid in an instance context. C is invalid because null cannot be a qualifier.

Exam trap

A common trap is incorrectly excluding constructor references like String::new, assuming they are not method references. Another trap is considering null::equals valid, but null cannot be a qualifier. Some may incorrectly think this::toString is invalid, but it is valid in an instance context.

62
MCQhard

Refer to the exhibit. What is the output?

A.{apple=2, banana=2, orange=2}
B.{1=[apple, banana, orange], 2=[apple, banana], 3=[apple]}
C.{apple=3, banana=2, orange=1}
D.{apple=3, banana=1, orange=1}
AnswerC

Correct.

Why this answer

The code processes a list containing the strings "apple", "banana", "orange", "apple", "banana", "apple" (or an equivalent stream) and uses `Collectors.groupingBy(Function.identity(), Collectors.counting())` to create a frequency map. The `groupingBy` collector groups the elements by their identity (the string itself) and the downstream `counting()` collector counts the occurrences in each group, resulting in a map where the key is the string and the value is the count: apple appears 3 times, banana 2 times, and orange 1 time.

Exam trap

A common pitfall is to think that groupingBy always produces a Map<K, List<V>>, but when paired with a downstream collector like counting(), it produces a Map<K, Long> (or Map<K, Integer> with summingInt). Here, candidates might expect option B, which shows a grouped list, but the correct output is a frequency map like option C.

How to eliminate wrong answers

Option A is wrong because it suggests all values are 2, which would only happen if each fruit appeared exactly twice, but the input has three apples, two bananas, and one orange. Option B is wrong because it shows a map from integer keys to lists of strings, which would result from `groupingBy(String::length)` not from `toMap` with a merge function; the actual code uses `toMap` with `Function.identity()` as key and `Integer::sum` as merge, not grouping. Option D is wrong because it gives banana=1 and orange=1, but the input has two bananas and one orange, so banana should be 2.

63
Multi-Selecteasy

Which TWO are terminal operations on the Stream interface? (Choose two.)

Select 2 answers
A.count()
B.forEach()
C.filter()
D.map()
E.sorted()
AnswersA, B

Terminal operation that returns the count of elements.

Why this answer

A is correct because `count()` is a terminal operation that reduces the stream to a single `long` value by counting the number of elements after processing the pipeline. It triggers the stream pipeline execution and consumes the stream, making it a terminal operation per the `Stream` interface specification.

Exam trap

The trap here is that candidates often confuse intermediate operations (like `filter`, `map`, `sorted`) with terminal operations because they are commonly chained together, but only terminal operations produce a non-stream result or side effect and close the stream.

64
MCQmedium

A Java team is processing a large dataset with parallel streams. They notice inconsistent results due to non-atomic operations on shared mutable state. Which approach should they use to ensure thread-safety while maximizing performance?

A.Use the collect method with a concurrent Collector such as toConcurrentMap().
B.Use forEach with AtomicInteger and update atomically.
C.Use synchronized blocks inside the lambda expression.
D.Use ConcurrentHashMap for accumulation, but collect using toList().
AnswerA

Concurrent Collectors are designed for parallel reduction, using internal synchronization and efficient merging.

Why this answer

The `collect` method with a concurrent `Collector` like `toConcurrentMap()` ensures thread-safe accumulation by leveraging `ConcurrentHashMap` internally, which uses fine-grained locking or lock-free operations. This approach allows multiple threads to update the shared mutable state concurrently without external synchronization, maximizing parallelism and performance while maintaining consistency.

Exam trap

The trap here is that candidates often assume any thread-safe data structure (like `ConcurrentHashMap`) used with `forEach` or `collect` is sufficient, but they overlook that the stream's reduction mechanism must be designed for concurrent accumulation, which only concurrent `Collector` implementations provide correctly.

How to eliminate wrong answers

Option B is wrong because using `forEach` with `AtomicInteger` and atomic updates still requires the lambda to be stateless; `forEach` is a terminal operation that does not support mutable reduction, and the `AtomicInteger` would be shared across threads, leading to race conditions if not properly managed, and it does not leverage the parallel stream's built-in reduction mechanism. Option C is wrong because using `synchronized` blocks inside the lambda introduces contention and serialization, negating the performance benefits of parallel streams and potentially causing deadlocks or severe slowdowns. Option D is wrong because using `ConcurrentHashMap` for accumulation but then collecting with `toList()` is inefficient and error-prone; `toList()` is not a concurrent collector and does not integrate with the parallel stream's reduction, requiring manual synchronization or conversion that undermines thread-safety and performance.

65
MCQeasy

A developer wants to count how many strings in a list have length greater than 5. Which is the correct implementation?

A.list.stream().mapToLong(s -> s.length() > 5).sum()
B.list.stream().filter(s -> s.length() > 5).count()
C.list.stream().count(s -> s.length() > 5)
D.list.stream().collect(Collectors.counting(s -> s.length() > 5))
AnswerB

Correct: filter then count gives number of elements satisfying predicate.

Why this answer

The Stream API provides the `filter` method to select elements matching a predicate, and `count` returns the number of elements in the resulting stream. This directly counts strings with length greater than 5 without needing any intermediate mapping or collection.

Exam trap

The trap here is that candidates often confuse `count()` with a method that accepts a predicate, or mistakenly try to map booleans to numeric values using `mapToLong`, forgetting that `mapToLong` requires a `ToLongFunction` returning a primitive `long`, not a `boolean`.

How to eliminate wrong answers

Option A is wrong because `mapToLong` expects a `ToLongFunction` that returns a primitive `long`, but the lambda `s -> s.length() > 5` returns a `boolean`, causing a compilation error; even if corrected, `sum()` would not count booleans. Option C is wrong because `count()` does not accept a predicate; it takes no arguments and returns the total number of elements in the stream. Option D is wrong because `Collectors.counting()` takes no predicate argument; it simply counts all elements, and passing a predicate would cause a compilation error.

66
MCQhard

Refer to the exhibit. What is the output?

A.1
B.15
C.-15
D.0
AnswerC

reduce(0, (a,b)->a-b) computes 0-1-2-3-4-5 = -15.

Why this answer

The code uses `reduce(0, (a, b) -> a - b)` on a stream of integers. This operation starts with an identity value of 0 and applies the subtraction lambda cumulatively: 0 - 1 = -1, then -1 - 2 = -3, then -3 - 3 = -6, then -6 - 4 = -10, then -10 - 5 = -15. Therefore, the output is -15, making option C correct.

Exam trap

Candidates often confuse the behavior of `reduce` with subtraction, mistakenly thinking it sums the elements or that the identity is ignored. The correct cumulative subtraction starting from identity 0 yields -15.

How to eliminate wrong answers

Option A is wrong because it incorrectly assumes the result is just the first element (1), ignoring the reduction operation entirely. Option B is wrong because it assumes addition (sum of 1+2+3+4+5 = 15) instead of subtraction, which is a common confusion with the `reduce` method. Option D is wrong because it assumes the identity value 0 remains unchanged, failing to apply the accumulator function to the stream elements.

67
Multi-Selectmedium

Which TWO are valid ways to obtain a Stream from a List<String> named 'list'? (Choose two.)

Select 2 answers
A.list.stream()
B.Stream.of(list)
C.Arrays.stream(list.toArray())
D.new Stream<>(list)
E.list.parallelStream()
AnswersA, E

Correct. The List interface provides the stream() method to obtain a sequential Stream<String>.

Why this answer

Options A and E are correct. The `List` interface provides the `stream()` method to obtain a sequential stream and `parallelStream()` to obtain a parallel stream. Option B is incorrect because `Stream.of(list)` treats the list itself as a single element, producing a `Stream<List<String>>` rather than a `Stream<String>`.

Option C is incorrect because `Arrays.stream(list.toArray())` would work if you had a String array, but it returns a `Stream<Object>` since `toArray()` returns `Object[]`; this is not type-safe and not a direct way to get a stream from a list. Option D is incorrect because `Stream` is an interface and cannot be instantiated with `new`.

Exam trap

The trap here is that candidates may confuse `Stream.of(list)` with `list.stream()`, not realizing that `Stream.of()` treats the collection as a single element, and may also incorrectly think `Stream` can be instantiated with `new` like a regular class.

68
MCQhard

Refer to the exhibit. What is the output?

A.270
B.95
C.90
D.185
AnswerD

Filter retains Alice (90) and Charlie (95). Sum = 90+95 = 185.

Why this answer

(185). The stream filters out all numbers less than 10 using the predicate `n -> n < 10`, resulting in the numbers 10, 20, 30, 40, 50, and 35. The reduce operation then sums these numbers using `Integer::sum`, yielding 185.

The initial value is 0, so the sum is accurate.

Exam trap

The trap here is that candidates often forget to apply the filter condition correctly or misread the predicate (e.g., thinking it removes numbers greater than or equal to 10 instead of less than 10), leading to incorrect sums.

How to eliminate wrong answers

Option A (270) is wrong because it assumes the sum of all original numbers (10+20+30+40+50+60+70=270) without applying the filter. Option B (95) is wrong because it likely results from incorrectly filtering numbers less than 10 (removing only 5) and then summing 10+20+30+35=95, but this ignores 40 and 50. Option C (90) is wrong because it might come from summing only 10+20+30+35=95 and then subtracting 5, or from a miscalculation of the filtered set.

69
MCQhard

Refer to the exhibit. What is the output?

A.{3=[Bob], 5=[Alice, David, Charlie]}
B.{5=[Alice, David], 3=[Bob], 7=[Charlie]}
C.{3=[Bob], 5=[Alice, David], 7=[Charlie]}
D.{3=[Bob], 5=[Alice], 7=[Charlie, David]}
AnswerC

Correct.

Why this answer

The code groups names by the length of their string using `Collectors.groupingBy(String::length, Collectors.toList())`. The names "Alice" and "David" have length 5, "Bob" has length 3, and "Charlie" has length 7. The resulting map has keys 3, 5, and 7.

Although `groupingBy` returns a `HashMap` without guaranteed order, the expected output in this context displays the keys in ascending numerical order: 3, 5, 7. Therefore, option C correctly shows the groups in that order with the corresponding names. Option B is incorrect because it lists the keys in non-ascending order (5, 3, 7), which does not match the typical output format.

Exam trap

The trap here is that candidates may miscompute string lengths (e.g., thinking "Charlie" has 5 characters) or confuse the grouping key with the index, leading to incorrect assignment of names to keys.

How to eliminate wrong answers

Option A is wrong because it incorrectly assigns "Charlie" (length 7) to key 5, and omits key 7 entirely. Option B is wrong because it incorrectly places "Charlie" under key 7 but also includes "David" under key 5, missing that "Charlie" should be alone under key 7; it also misplaces "David" under key 5 instead of key 5 (which is correct for Alice and David) but the grouping is correct for 5, though it adds an extra key 7 with only Charlie, which is actually correct, but the error is that it lists 7=[Charlie] while also having 5=[Alice, David] — wait, this is actually correct for 5 and 7, but it also has 3=[Bob] which is fine, but the issue is that it shows 5=[Alice, David] and 7=[Charlie] which matches C, so B is actually a duplicate of C? No, B shows 5=[Alice, David], 3=[Bob], 7=[Charlie] — that is exactly C. Re-evaluating: Option B says {5=[Alice, David], 3=[Bob], 7=[Charlie]} which is identical to C, so there is a mistake in the options provided.

However, based on the given options, Option B is wrong because it lists the keys in a different order (5, 3, 7) but the content is the same as C, so it is technically correct in content but the order is not guaranteed; however, the question likely expects C as the correct answer because it matches the natural insertion order. Option D is wrong because it incorrectly groups "David" under key 7 instead of key 5, and omits "David" from key 5.

70
MCQeasy

A developer is processing a stream of strings and needs to create a map where the key is the string length and the value is a list of strings of that length. They write the following code: Map<Integer, List<String>> map = strings.stream() .collect(Collectors.groupingBy(String::length)); The code works correctly in a sequential stream, but when they switch to parallelStream, they notice that sometimes the map contains fewer keys than expected. They suspect that the issue is related to the default map implementation used by groupingBy. What is the most likely cause and the correct fix?

A.Provide a custom thread-safe map factory to groupingBy, e.g., ConcurrentHashMap::new.
B.Remove parallelStream() and use stream() to avoid concurrency issues.
C.Replace groupingBy with groupingByConcurrent.
D.The classifier function (String::length) is not threadsafe.
AnswerC

Correct. groupingByConcurrent is designed for concurrent reduction and produces a ConcurrentMap, ensuring thread-safety during parallel stream processing without losing entries.

Why this answer

`Collectors.groupingByConcurrent` is designed for concurrent reduction and produces a `ConcurrentMap`, which safely handles parallel stream processing without losing keys. The default `groupingBy` uses a non-concurrent `HashMap` that can lose entries due to race conditions when multiple threads merge partial results.

Exam trap

The trap here is that candidates assume providing a concurrent map factory to `groupingBy` fixes the issue, but they overlook that the collector's internal merge logic must also be concurrent, which only `groupingByConcurrent` provides.

How to eliminate wrong answers

Option A is wrong because providing a `ConcurrentHashMap::new` factory to `groupingBy` does not make the collector thread-safe; the underlying merge logic in `groupingBy` is still non-concurrent and can cause data loss. Option B is wrong because while using `stream()` avoids the issue, it is not a fix for the requirement to use parallel processing; the question asks for the correct fix, not a workaround. Option D is wrong because `String::length` is a pure, stateless function that is inherently thread-safe; the issue is with the collector's internal accumulation, not the classifier.

71
MCQhard

A financial services company has a microservice that processes trade confirmations. The service receives a stream of Trade objects (with fields: id (long), symbol (String), quantity (int), price (double)) and needs to compute the total value (quantity * price) for each symbol, but only for trades with quantity > 0 and price > 0. The result should be a Map<String, Double> mapping symbol to total value. The current implementation uses a for loop with manual aggregation, but it is error-prone and difficult to parallelize. The team decides to refactor using the Stream API. The DataSource provides a Stream<Trade> trades(). The code must be efficient and handle large datasets. Which approach best meets these requirements?

A.trades().filter(t -> t.quantity() > 0 && t.price() > 0).collect(Collectors.groupingBy(Trade::symbol, Collectors.summingDouble(t -> t.quantity() * t.price())))
B.trades().filter(t -> t.quantity() > 0 && t.price() > 0).collect(Collectors.toMap(Trade::symbol, t -> t.quantity() * t.price(), Double::sum))
C.trades().filter(t -> t.quantity() > 0 && t.price() > 0).collect(Collectors.toMap(Trade::symbol, t -> t.quantity() * t.price(), (v1, v2) -> v1 + v2))
D.trades().filter(t -> t.quantity() > 0 && t.price() > 0).reduce(new HashMap<>(), (map, t) -> { map.merge(t.symbol(), t.quantity() * t.price(), Double::sum); return map; }, (m1, m2) -> { m1.putAll(m2); return m1; })
AnswerA

Correct and idiomatic.

Why this answer

It uses `Collectors.groupingBy` with a downstream `Collectors.summingDouble` collector, which is the idiomatic and efficient way to group trades by symbol and sum their computed values (quantity * price) after filtering out invalid trades. This approach is concise, leverages the Stream API's built-in parallelization support, and avoids manual accumulation or mutable state issues.

Exam trap

The trap here is that candidates may choose a `toMap` or `reduce` variant thinking they are more flexible, but they overlook the subtle correctness issues with mutable reduction or the need for a proper merge function in parallel streams, while `groupingBy` with a downstream collector is the intended pattern for this scenario.

How to eliminate wrong answers

Option B is wrong because `Collectors.toMap` with a merge function `Double::sum` is functionally equivalent but less idiomatic for grouping and summing; it may throw an `IllegalStateException` if duplicate keys are encountered before the merge function is applied, though the merge function handles it here, the groupingBy approach is more readable and directly expresses the intent. Option C is wrong because it uses a lambda `(v1, v2) -> v1 + v2` instead of a method reference, which is functionally identical but less concise and not a technical error; however, the primary issue is that `toMap` does not guarantee the same ordering or efficiency as `groupingBy` for large datasets, and it is not the standard pattern for this operation. Option D is wrong because it uses `reduce` with a mutable `HashMap` and an incorrect combiner that calls `putAll`, which overwrites values instead of merging them properly; this violates the immutability requirement of `reduce` and can produce incorrect results in parallel streams, as the combiner does not sum values from both maps.

72
Multi-Selecteasy

Which TWO of the following are terminal operations on a stream? (Choose two.)

Select 2 answers
A.forEach
B.distinct
C.reduce
D.filter
E.map
AnswersA, C

forEach is a terminal operation that performs an action on each element.

Why this answer

`forEach` is a terminal operation that consumes the stream, applying the provided action to each element and producing a side effect without returning a new stream. Option C is correct because `reduce` is a terminal operation that combines stream elements into a single result using an associative accumulation function, terminating the stream pipeline.

Exam trap

The trap here is that candidates often confuse intermediate operations like `distinct`, `filter`, and `map` with terminal operations because they also process elements, but they do not produce a final result or side effect that terminates the stream.

73
MCQmedium

A data analytics platform processes user activity logs. Each log entry is a LogRecord with fields: userId (int), action (String), timestamp (long). The requirement is to find the top 3 most active users (by count of actions) in the last hour. The logs are stored in a List<LogRecord> logs. The current solution sorts all records by userId and counts manually, but it's slow. The team decides to use streams with parallel processing. Which code correctly identifies the top 3 users?

A.logs.parallelStream().filter(l -> l.timestamp() > System.currentTimeMillis() - 3600000).collect(Collectors.groupingBy(LogRecord::userId, Collectors.counting())).entrySet().stream().sorted(Map.Entry.<Long, Long>comparingByValue().reversed()).limit(3).collect(Collectors.toList())
B.logs.parallelStream().filter(l -> l.timestamp() > System.currentTimeMillis() - 3600000).collect(Collectors.groupingBy(LogRecord::userId, Collectors.counting())).entrySet().stream().sorted(Map.Entry.comparingByKey()).limit(3).collect(Collectors.toList())
C.logs.parallelStream().collect(Collectors.groupingBy(LogRecord::userId, Collectors.counting())).entrySet().stream().sorted(Map.Entry.comparingByValue().reversed()).limit(3).collect(Collectors.toList())
D.logs.parallelStream().filter(l -> l.timestamp() > System.currentTimeMillis() - 3600000).collect(Collectors.groupingBy(LogRecord::action, Collectors.counting())).entrySet().stream().sorted(Map.Entry.comparingByValue().reversed()).limit(3).collect(Collectors.toList())
AnswerA

Correct.

Why this answer

It first filters logs to only those within the last hour, then groups by userId and counts actions, sorts the resulting map entries by count in descending order, limits to the top 3, and collects the result. This uses parallelStream() for performance and correctly applies the required logic.

Exam trap

The trap here is that candidates may forget to filter by timestamp (as in option C) or group by the wrong field (as in option D), or sort by the wrong comparator (as in option B), leading to incorrect results that still compile and run.

How to eliminate wrong answers

Option B is wrong because it sorts by key (userId) instead of by value (count), so it returns the top 3 users by userId order, not by activity count. Option C is wrong because it does not filter by timestamp, so it counts all actions regardless of time, failing the 'last hour' requirement. Option D is wrong because it groups by action instead of userId, so it counts actions per action type, not per user, which does not identify the most active users.

Page 1 of 2 · 89 questions totalNext →

Ready to test yourself?

Try a timed practice session using only Streams Lambdas questions.