OCP Question 56, Explanation

Given the definition of the ExamTaker class:

public class ExamTaker {
    private String name;
    private Integer score;
    ExamTaker(String name, Integer score) {
        this.name = name;
        this.score = score;
    public String getName() {return name;}
    public Integer getScore() {return score;}

and code fragment:

List<ExamTaker> list = Arrays.asList(
    new ExamTaker("Alice", 98),
    new ExamTaker("Bob", 64),
    new ExamTaker("Chris", 72));
Predicate<ExamTaker> passed = e -> e.getScore() >= 65;              // line n1
list = list.stream().filter(passed).collect(Collectors.toList());
Stream<String> names = list.stream().map(ExamTaker::getName);       // line n2
names.forEach(x -> System.out.print(x + " "));

What is the result?

A. Alice Bob Chris
B. Alice Chris
C. A compilation error occurs at line n1
D. A compilation error occurs at line n2


The correct answer is B.


There’s no reason for a comperr as line n1 is a classic form of a filter’s predicate, and as for line n2, it is also built correctly: map() needs a Function, which is exactly what the ExamTaker::getName unbound metref provides. (It’s unbound because we reference it via a class name rather that an object’s name).

filter() passes through only those elements who meet the specified criterion (element’s score must be at least 65), then collect() builds a List out of them. Let’s note in passing that although the source list was structurally immutable, the code won’t throw an UnsupportedOperationException because collect() doesn’t add anything to the initial list: it first builds an entirely new List, then assigns it to the reference variable.

Line n2 first turns this new List into a stream of filtered out ExamTakers and then map() extracts name from each element of this stream.

Leave Comment

Your email address will not be published.