Oracle Certified Professional Java Se 11 Developer · Free Practice Question Hard
Question 104
Question ID: UKOCP89501
Given code:
- package com.udayankhattry.ocp;
- import java.util.stream.Stream;
- public class Test {
- public static void main(String[] args) {
- var str1 = Stream.iterate(1, k -> k <= 10, i -> i + 1)
- .reduce("", (i, s) -> i + s, (s1, s2) -> s1 + s2);
- var str2 = Stream.iterate(1, k -> k <= 10, i -> i + 1)
- .parallel()
- .reduce("", (i, s) -> i + s, (s1, s2) -> s1 + s2);
- System.out.println(str1.equals(str2));
- }
- }
What is the result?
- A It will always print true
- B It will always print false
- C Output cannot be predicted
Reveal correct answer
Correct answer: A
Explanation
UKOCP89501:
Variables 'str1' and 'str2' infer to String type.
public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) {...}
According to Javadoc:
This method returns a sequential ordered Stream produced by iterative application of the given next function to an initial element, conditioned on satisfying the given hasNext predicate. The stream terminates as soon as the hasNext predicate returns false.
Stream.iterate(1, k -> k <= 10, i -> i + 1) => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
reduce method in Stream class is declared as: <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
By checking the reduce method 'reduce("", (i, s) -> i + s, (s1, s2) -> s1 + s2)', we can say that:
Identity is String type, accumulator is BiFunction<String, ? super Integer, String> type, combiner is BinaryOperator<String> type.
To get consistent output, there are requirements for reduce method arguments:
1. The identity value must be an identity for the combiner function. This means that for all u, combiner(identity, u) is equal to u.
As u is of String type, let's say u = "X", combiner("", "X") = "X". Hence, u is equal to combiner("", "X"). First rule is obeyed.
2. The combiner function must be compatible with the accumulator function; for all u and t, the following must hold:
combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t).
Let's consider, u = "Y", t is element of Stream, say t = 1, identity = "".
combiner.apply(u, accumulator.apply(identity, t))
= combiner.apply("Y", accumulator.apply("", 1))
= combiner.apply("Y", "1")
= "Y1"
and
accumulator.apply(u, t)
= accumulator.apply("Y", 1)
= "Y1"
Hence, combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t). 2nd rule is also followed.
3. The accumulator operator must be associative and stateless. Operator + is associative and lambda expression is stateless. 3rd rule is followed.
4. The combiner operator must be associative and stateless. Operator + is associative and lambda expression is stateless. 4th rule is followed.
As all the rules are followed in this case, hence str1 refers to "12345678910" and str2 refers to "12345678910"
Discussion
Think the marked answer is wrong, or have a better explanation? Share it below — comments appear after review.
