Wednesday, April 26, 2023

Quiz yourself: Unmodifiable Map objects created from Java’s Map.of methods

Oracle Java, Oracle Java Tutorial and Materials, Java Career, Java Jobs, Java Tutorial and Materials


Given the following map

var m = Map.of(1,2,3,4);

Which code fragment is guaranteed to print 37 to the console? Choose one.

A. m.forEach((x, y) -> System.out.print(x + y));
 
B. for (var v : m) {
System.out.print(v.getKey() + v.getValue());
}
 
C. for (var v : m.keySet()) {
System.out.print(v + m.get(v));
}
 
D. for (var t : m.entrySet()) {
System.out.print(t.getKey() + t.getValue());
}
 
E. None of the above
 
Answer. This question investigates concepts related to the Map interface and the unmodifiable Map objects created from the Map.of methods.

Look at the effect of the Map.of(1,2,3,4) method call. It creates a Map<Integer, Integer> with two key-value pairs. The keys for these pairs are 1 and 3, and the corresponding values are 2 and 4. Note that the Map.of methods that take arguments in this form treat those arguments as a key, a value, a key, a value, and so on. The keys and values, of course, will be autoboxed to provide Integer objects.

Since you have two pairs in this Map—1-2 and 3-4—it’s a simple observation of arithmetic that adding the key-value pairs will give the results 3 and 7, which seems at least promising for producing the desired output.

Now, look at the code of each option in turn.

Option A has a call to m.forEach. Java 8 added a forEach method to many types from the Collections API (for example, java.util.Map or java.util.List). The method allows you to perform some action on each element or entry from the collection. The map.forEach method in this case accepts a BiConsumer<Integer, Integer> as its argument, and the accept method of that argument will be called with a key and value pair from each key-value pair. So, you can see that code potentially can print 37. Hold on to that thought.

Option B attempts to use the Map in an enhanced for loop. However, this will fail because java.util.Map itself does not implement the Iterable interface required for this usage. From this, you can determine that option B will not compile and is therefore incorrect.

Option C extracts a keySet from the Map, which gives you a set of the keys. A Set does implement the Iterable interface; therefore, you can use it in an enhanced for loop. The body of the loop extracts the matching value, adds that value to the key, and prints it. Again, you can see that this code might print 37. Hold on to this thought too. Option D iterates over a Set of Map.Entry objects. This is also valid and given that the code prints the sum of the key and the value each time through the loop, it also might print 37 to the console. Yes; hold this thought as well.

At this point, you might have noticed that options A, C, and D were described as might being able to print 37, but the question asks for a single answer. When you work on questions for an exam of this kind, it’s important to pick the correct number of options. In the Java exam software, if a question asks for a single answer, you will be presented with radio buttons, and it’s impossible to select more than one. This tells you to look a bit harder.

In fact, options A, C, and D are all incorrect, and they all have the same problem: The iteration of a Map in Java does not provide a predictable order. This means that you cannot be certain that the code will process the 1-2 pair first and the 3-4 pair second. Consequently, any of these three options might equally print 37 or 73. Because this does not satisfy the question’s query, you can see that option E is correct.

To make this official, the documentation for the unmodifiable maps produced by the Map.of() factory methods explains that “The iteration order of mappings is unspecified and is subject to change.”

As a final observation, it’s interesting that the TreeMap method sorts its keys. This can be done by the keys’ natural order or by using a supplied Comparator. If the question’s code used a map that guarantees order in that way, then options A, C, and D would be correct. To make this change, declare and initialize the Map using the following:

var m = new TreeMap<>(Map.of(1,2,3,4));

Finally, you should always assume exam-style questions are based on behavior that you can rely on, as specified in the documentation. If you test this question’s code using most reasonably recent versions of Java, you will find that options A, C, and D will print 37—but that’s luck. Professional-grade programmers don’t depend on luck!

Conclusion. The correct answer is option E.

Source: oracle.com

Related Posts

0 comments:

Post a Comment