OCP Question 7, Explanation

Given the code fragments:

class OS {
    String name;
    OS (String name) {
        this.name = name;
    }
}

and

List<OS> list = Arrays.asList(
    new OS("Windows "),
    new OS("Solaris "),
    new OS("Linux ")
);
Stream<OS> creek = list.stream();
//line n1

Which should be inserted at line n1 to print Windows Solaris Linux ?

A. creek.forEach(System.out::print);
B. creek.map(a -> a.name).forEach(System.out::print);
C. creek.map(a -> a).forEachOrdered(System.out::print);
D. creek.forEachOrdered(System.out::print);

 

The correct answer is option B.

Hopefully, you do remember after reading Nailing 1Z0-808 that if available options don’t mention compilation failure explicitly, it doesn’t necessarily mean that each and every one of them compiles. In this particular case, however, none of them throws a comperr because:

  • Stream’s forEach() indeed accepts a Consumer, and the System.out::print metref is void;
  • the lambda in B accesses the instance var name that does exist in the OS class;
  • C’s lambda, apart from creating a new object out of every incoming element, doesn’t do anything meaningful – or harmful, for that matter;
  • forEachOrdered() is very similar to Stream’s forEach() but relies upon the encounter order;

In short, all options print out something, so the real question is how to choose among them. Well, since the OS class doesn’t define its own toString(), options A, C and D output just the names of list’s elements, that is, objects, which will look like garbage. Adding to the OS class something like

@Override
public String toString(){ return this.name;}

would make all given choices equally acceptable.

Leave Comment

Your email address will not be published. Required fields are marked *