Given the code fragment:
Path file = Paths.get("passwords.txt"); // line n1
Assume the passwords.txt is accessible. Which code fragment can be inserted at line n1 to enable the code to print the content of the passwords.txt file?
A. List<String> fc = Files.list(file); fc.stream().forEach(x -> System.out.println(x)); B. Stream<String> fc = Files.readAllLines(file); fc.forEach(x -> System.out.println(x)); C. List<String> fc = readAllLines(file); fc.stream().forEach(x -> System.out.println(x)); D. Stream<String> fc = Files.lines(file); fc.forEach(x -> System.out.println(x));
The correct answer is D.
The utility class Files contains a rich variety of methods that return bytes or entire lines from files; what’s more, the return type can be an array, List or Stream. Even thinking about memorizing all those signatures makes me shudder. Fortunately, for the exam it is more than sufficient to remember one simple mnemonic formula:
readAllLines() if chock-full of Ls, and thus hints heavily on a List rather than Stream
Now let’s see at which point this formula can be applied in our Problem. We’ll start with option A; it is syntactically invalid as the list() method returns a Stream of entries in the specified directory but we assign the result to a List. Even if we don’t remember what the method returns, its very name sounds suspicious as lists in the standard Java library typically refer to the content of a folder rather file.
No, the real question is how to choose among options B, C and D. Take a look at C: our mnemonic formula says that the assignment itself is correct as readAllLines() must return a List. The only problem with C is that the method invocation misses the type, it should’ve been
List<String> fc = Files.readAllLines(file);
Wait! I know, I know, we’ll discuss it at the end.
Now, the call itself in option B is correct but the assignment uses mismatched types. Therefore, what is left is just option D.
Okay, back to C. Yes, I do think the question is formulated ambiguously: after all, we weren’t provided with the entire content of the source file. What if it had an import static statement in it, eh? I mean, this one:
import static java.nio.file.Files.readAllLines;
Who says it’s impossible? No, no, no, quite the contrary. Look, do you remember those assumptions we are supposed to make on the exam? We’ve talked about them in Nailing 1Z0-808, page 42 (or go to the Oracle Univ.site, Review Exam Topics section):
Accordingly, it appears that the source code file might well contain the missing static import, in which case we’d have TWO correct options. However, the question clearly wants to test us on the use of NIO, so we make a leap of faith here…
Uhm… How did I know the import should’ve been static? Oh, it’s very simple: every standard Java lib class on our exams (yes, both OCA and OCP) that ends in “s” is an utility class: Files, Arrays, Collectors, Collections, etc, and utility classes are always made of static methods only… Sigh. Except for the methods inherited from Object. But then again, even javadoc for Files uses the phrase “This class consists exclusively of static methods that operate on files, directories, or other types of files” apparently forgetting about the inherited methods. But enough of splitting hairs…
With the advent of static interface methods in Java 8 there’s no need to write new utility classes anymore as everything needful and useful can be packed inside a single interface. Neat.