But then the more you look at it, the more you realize:
1. You are doing your own type checking in the returnRental() method. You can't change the argument type of returnRental() to take a Car, since it's an override (not an overload) of the method from class Rental. (Overloading would take away your polymorphic flexibility with Rental).
2. You really don't want to make separate subclasses for every possible kind of rentable thing (cars, computers, bowling shoes, children, and so on).
But given your natural brilliance (heightened by this contrived scenario), you quickly realize that you can make the Rental class a generic type—a template for any kind of Rentable thing—and you're good to go.
(We did say contrived…since in reality, you might very well want to have different behaviors for different kinds of rentable things, but even that could be solved cleanly through some kind of behavior composition as opposed to inheritance (using the Strategy design pattern, for example). And no, design patterns aren't on the exam, but we still think you should read our design patterns book. Think of the kittens.) So here's your new and improved generic Rental class:
We get one error:
Now we have a Rental class that can be typed to whatever the programmer chooses, and the compiler will enforce it. In other words, it works just as the Collections classes do. Let's look at more examples of generic syntax you might find in the API or source code. Here's another simple class that uses the parameterized type of the class in several ways:
Obviously this is a ridiculous use of generics, and in fact you'll see generics only rarely outside of collections. But, you do need to understand the different kinds of generic syntax you might encounter, so We'll continue with these examples until we've covered them all.
You can use more than one parameterized type in a single class definition:
And you can use a form of wildcard notation in a class definition, to specify a range (called "bounds") for the type that can be used for the type parameter:
Until now, every example we've seen uses the class parameter type—the type declared with the class name. For example, in the UseTwo <T,X> declaration, we used the T and X placeholders throughout the code. But it's possible to define a parameterized type at a more granular level—a method.
Imagine you want to create a method that takes an instance of any type, instantiates an ArrayList of that type, and adds the instance to the ArrayList. The class itself doesn't need to be generic; basically we just want a utility method that we can pass a type to and that can use that type to construct a type safe collection. Using a generic method, we can declare the method without a specific type and then get the type information based on the type of the object passed to the method. For example:
In the preceding code, if you invoke the makeArrayList() method with a Dog instance, the method will behave as though it looked like this all along:
And of course if you invoke the method with an Integer, then the T is replaced by Integer (not in the bytecode, remember—we're describing how it appears to behave, not how it actually gets it done).
The strangest thing about generic methods is that you must declare the type variable BEFORE the return type of the method:
The <T> before void simply defines what T is before you use it as a type in the argument. You MUST declare the type like that unless the type is specified for the class. In CreateAnArrayList, the class is not generic, so there's no type parameter placeholder we can use.
You're also free to put boundaries on the type you declare, for example, if you want to restrict the makeArrayList() method to only Number or its subtypes (Integer, Float, and so on) you would say
|
It's tempting to forget that the method argument is NOT where you declare the type parameter variable T. In order to use a type variable like T, you must have declared it either as the class parameter type or in the method, before the return type. The following might look right, |
|
|
|
But the only way for this to be legal is if there is actually a class named T, in which case the argument is like any other type declaration for a variable. And what about constructor arguments? They, too, can be declared with a generic type, but then it looks even stranger since constructors have no return type at all: |
|
|
|
If you REALLY want to get ridiculous (or fired), you can declare a class with a name that is the same as the type parameter placeholder: |
|
|
|
Yes, this works. The X that is the constructor name has no relationship to the <X> type declaration, which has no relationship to the constructor argument identifier, which is also, of course, X. The compiler is able to parse this and treat each of the different uses of X independently. So there is no naming conflict between class names, type parameter placeholders, and variable identifiers. |
|
One of the most common mistakes programmers make when creating generic classes or methods is to use a <?> in the wildcard syntax rather than a type variable <T>, <E>, and so on. This code might look right, but isn't: |
|
|
|
While the question mark works when declaring a reference for a variable, it does NOT work for generic class and method declarations. This code is not legal: |
|
|
|
But if you replace the <?> with a legal identifier, you're good: |
|
|
98% of what you're likely to do with generics is simply declare and use type safe collections, including using (and passing) them as arguments. But now you know much more (but by no means everything) about the way generics works.
If this was clear and easy for you, that's excellent. If it was…painful…just know that adding generics to the Java language very nearly caused a revolt among some of the most experienced Java developers. Most of the outspoken critics are simply unhappy with the complexity, or aren't convinced that gaining type safe collections is worth the ten million little rules you have to learn now. It's true that with Java 5, learning Java just got harder. But trust us…we've never seen it take more than two days to "get" generics. That's 48 consecutive hours.
We began with a quick review of the toString() method. The toString() method is automatically called when you ask System.out.println() to print an object—you override it to return a String of meaningful data about your objects.
Next we reviewed the purpose of == (to see if two reference variables refer to the same object) and the equals() method (to see if two objects are meaningfully equivalent). You learned the downside of not overriding equals()—you may not be able to find the object in a collection. We discussed a little bit about how to write a good equals() method—don't forget to use instanceof and refer to the object's significant attributes. We reviewed the contracts for overriding equals() and hashCode(). We learned about the theory behind hashcodes, the difference between legal, appropriate, and efficient hashcoding. We also saw that even though wildly inefficient, it's legal for a hashCode() method to always return the same value.
Next we turned to collections, where we learned about Lists, Sets, and Maps, and the difference between ordered and sorted collections. We learned the key attributes of the common collection classes, and when to use which.
We covered the ins and outs of the Collections and Arrays classes: how to sort, and how to search. We learned about converting arrays to Lists and back again.
Finally we tackled generics. Generics let you enforce compile-time type-safety on collections or other classes. Generics help assure you that when you get an item from a collection it will be of the type you expect, with no casting required. You can mix legacy code with generics code, but this can cause exceptions. The rules for polymorphism change when you use generics, although by using wildcards you can still create polymorphic collections. Some generics declarations allow reading of a collection, but allow very limited updating of the collection.
All in all, one fascinating chapter.
Here are some of the key points from this chapter.
equals(), hashCode(), and toString() are public.
Override toString() so that System.out.println() or other methods can see something useful, like your object's state.
Use == to determine if two reference variables refer to the same object.
Use equals() to determine if two objects are meaningfully equivalent.
If you don't override equals(), your objects won't be useful hashing keys.
If you don't override equals(), different objects can't be considered equal.
Strings and wrappers override equals() and make good hashing keys.
When overriding equals(), use the instanceof operator to be sure you're evaluating an appropriate class.
When overriding equals(), compare the objects'significant attributes.
Highlights of the equals() contract:
Reflexive: x.equals(x) is true.
Symmetric: If x.equals(y) is true, then y.equals(x) must be true.
Transitive: If x.equals(y) is true, and y.equals(z) is true, then z.equals(x) is true.
Consistent: Multiple calls to x.equals(y) will return the same result.
Null: If x is not null, then x.equals(null) is false.
If x.equals(y) is true, then x.hashCode() == y.hashCode() is true.
If you override equals(), override hashCode().
HashMap, HashSet, Hashtable, LinkedHashMap, & LinkedHashSet use hashing.
An appropriate hashCode() override sticks to the hashCode() contract.
An efficient hashCode() override distributes keys evenly across its buckets.
An overridden equals() must be at least as precise as its hashCode() mate.
To reiterate: if two objects are equal, their hashcodes must be equal.
It's legal for a hashCode() method to return the same value for all instances (although in practice it's very inefficient).
Highlights of the hashCode() contract:
Consistent: multiple calls to x.hashCode() return the same integer.
If x.equals(y) is true, x.hashCode() == y.hashCode() is true.
If x.equals(y) is false, then x.hashCode() == y.hashCode() can be either true or false, but false will tend to create better efficiency.
transient variables aren't appropriate for equals() and hashCode().
Common collection activities include adding objects, removing objects, verifying object inclusion, retrieving objects, and iterating.
Three meanings for "collection" :
collection Represents the data structure in which objects are stored
Collection java.util interface from which Set and List extend.
Collections A class that holds static collection utility methods.
Four basic flavors of collections include Lists, Sets, Maps, Queues:.
Lists of things Ordered, duplicates allowed, with an index.
Sets of things May or may not be ordered and/or sorted; duplicates not allowed.
Maps of things with keys May or may not be ordered and/or sorted; duplicate keys are not allowed.
Queues of things to process Ordered by FIFO or by priority.
Four basic sub-flavors of collections Sorted, Unsorted, Ordered, Unordered.
Ordered Iterating through a collection in a specific, non-random order.
Sorted Iterating through a collection in a sorted order.
Sorting can be alphabetic, numeric, or programmer-defined.
ArrayList: Fast iteration and fast random access.
Vector: It's like a slower ArrayList, but it has synchronized methods.
LinkedList: Good for adding elements to the ends, i.e., stacks and queues.
HashSet: Fast access, assures no duplicates, provides no ordering.
LinkedHashSet: No duplicates; iterates by insertion order.
TreeSet: No duplicates; iterates in sorted order.
HashMap: Fastest updates (key/values); allows one null key, many null values.
Hashtable: Like a slower HashMap (as with Vector, due to its synchronized methods). No null values or null keys allowed.
LinkedHashMap: Faster iterations; iterates by insertion order or last accessed; allows one null key, many null values.
TreeMap: A sorted map.
PriorityQueue: A to-do list ordered by the elements' priority.
Collections hold only Objects, but primitives can be autoboxed.
Iterate with the enhanced for, or with an Iterator via hasNext() & next().
hasNext() determines if more elements exist; the Iterator does NOT move.
next() returns the next element AND moves the Iterator forward.
To work correctly, a Map's keys must override equals() and hashCode().
Queues use offer() to add an element, poll() to remove the head of the queue, and peek() to look at the head of a queue.
As of Java 6 TreeSets and TreeMaps have new navigation methods like floor() and higher().
You can create/extend "backed" sub-copies of TreeSets and TreeMaps.
Sorting can be in natural order, or via a Comparable or many Comparators.
Implement Comparable using compareTo(); provides only one sort order.
Create many Comparators to sort a class many ways; implement compare().
To be sorted and searched, a List's elements must be comparable.
To be searched, an array or List must first be sorted.
Both of these java.util classes provide.
A sort() method. Sort using a Comparator or sort using natural order.
A binarySearch() method. Search a pre-sorted array or List.
Arrays.asList() creates a List from an array and links them together.
Collections.reverse() reverses the order of elements in a List.
Collections.reverseOrder() returns a Comparator that sorts in reverse.
Lists and Sets have a toArray() method to create arrays.
Generics let you enforce compile-time type safety on Collections (or other classes and methods declared using generic type parameters).
An ArrayList <Animal> can accept references of type Dog, Cat, or any other subtype of Animal (subclass, or if Animal is an interface, implementation).
When using generic collections, a cast is not needed to get (declared type) elements out of the collection. With non-generic collections, a cast is required:
You can pass a generic collection into a method that takes a non-generic collection, but the results may be disastrous. The compiler can't stop the method from inserting the wrong type into the previously type safe collection.
If the compiler can recognize that non-type-safe code is potentially endangering something you originally declared as type-safe, you will get a compiler warning. For instance, if you pass a List <String> into a method declared as
You'll get a warning because add() is potentially "unsafe".
"Compiles without error" is not the same as "compiles without warnings." A compilation warning is not considered a compilation error or failure.
Generic type information does not exist at runtime—it is for compile-time safety only. Mixing generics with legacy code can create compiled code that may throw an exception at runtime.
Polymorphic assignments applies only to the base type, not the generic type parameter. You can say
You can't say
The polymorphic assignment rule applies everywhere an assignment can be made. The following are NOT allowed:
Wildcard syntax allows a generic method, accept subtypes (or supertypes) of the declared type of the method argument:
The wildcard keyword extends is used to mean either "extends" or "implements." So in <? extends Dog>, Dog can be a class or an interface.
When using a wildcard, List <? extends Dog>, the collection can be accessed but not modified.
When using a wildcard, List <?>, any generic type can be assigned to the reference, but for access only, no modifications.
List <Object> refers only to a List <Object>, while List <?> or List <? extends Object> can hold any type of object, but for access only.
Declaration conventions for generics use T for type and E for element:
The generics type identifier can be used in class, method, and variable declarations:
The compiler will substitute the actual type.
You can use more than one parameterized type in a declaration:
You can declare a generic method using a type not defined in the class:
is NOT using T as the return type. This method has a void return type, but to use T within the method's argument you must declare the <T>, which happens before the return type.
1. Given:
Which statements could be inserted at // INSERT DECLARATION HERE to allow this code to compile and run? (Choose all that apply.)
A. List <List <Integer> > table = new List <List <Integer> > ();
B. List <List <Integer> > table = new ArrayList <List <Integer> > ();
C. List <List <Integer> > table = new ArrayList <ArrayList <Integer> > ();
D. List <List, Integer> table = new List <List, Integer> ();
E. List <List, Integer> table = new ArrayList <List, Integer> ();
F. List <List, Integer> table = new ArrayList <ArrayList, Integer> ();
G. None of the above
2. Which statements are true about comparing two instances of the same class, given that the equals() and hashCode() methods have been properly overridden? (Choose all that apply.)
A. If the equals() method returns true, the hashCode() comparison == might return false
B. If the equals() method returns false, the hashCode() comparison == might return true
C. If the hashCode() comparison == returns true, the equals() method must return true
D. If the hashCode() comparison == returns true, the equals() method might return true
E. If the hashCode() comparison != returns true, the equals() method might return true
3. Given:
Which statements are true?
A. The before() method will print 1 2
B. The before() method will print 1 2 3
C. The before() method will print three numbers, but the order cannot be determined
D. The before() method will not compile
E. The before() method will throw an exception at runtime
4. Given:
Which is correct? (Choose all that apply.)
A. As the code stands it will not compile
B. As the code stands the output will be 2
C. As the code stands the output will be 3
D. If the hashCode() method is uncommented the output will be 2
E. If the hashCode() method is uncommented the output will be 3
F. If the hashCode() method is uncommented the code will not compile
5. Given:
This class is to be updated to make use of appropriate generic types, with no changes in behavior (for better or worse). Which of these steps could be performed? (Choose three.)
A. Replace line 13 with
B. Replace line 13 with
C. Replace line 13 with
D. Replace lines 17– 20 with
E. Replace lines 17– 20 with
F. Replace lines 17– 20 with
G. Replace line 24 with
H. Replace line 24 with
6. Given:
Which of the following changes (taken separately) would allow this code to compile? (Choose all that apply.)
A. Change the Carnivore interface to
B. Change the Herbivore interface to
C. Change the Sheep class to
D. Change the Sheep class to
E. Change the Wolf class to
F. No changes are necessary
7. Which collection class(es) allows you to grow or shrink its size and provides indexed access to its elements, but whose methods are not synchronized? (Choose all that apply.)
A. java.util.HashSet
B. java.util.LinkedHashSet
C. java.util.List
D. java.util.ArrayList
E. java.util.Vector
F. java.util.PriorityQueue
8. Given a method declared as
A programmer wants to use this method like this
Which pairs of declarations could be placed at // INSERT DECLARATIONS HERE to allow the code to compile? (Choose all that apply.)
A. ArrayList <Integer> input = null;
ArrayList <Integer> output = null;
B. ArrayList <Integer> input = null;
List <Integer> output = null;
C. ArrayList <Integer> input = null;
List <Number> output = null;
D. List <Number> input = null;
ArrayList <Integer> output = null;
E. List <Number> input = null;
List <Number> output = null;
F. List <Integer> input = null;
List <Integer> output = null;
G. None of the above
9. Given the proper import statement(s), and
What is the result?
A. 2 2 3 3
B. 2 2 3 4
C. 4 3 3 4
D. 2 2 3 3 3
E. 4 3 3 3 3
F. 2 2 3 3 4
G. Compilation fails
H. An exception is thrown at runtime
10. Given:
When fragments I, II, or III are inserted, independently, at line 7, which are true? (Choose all that apply.)
A. Fragment I compiles
B. Fragment II compiles
C. Fragment III compiles
D. Fragment I executes without exception
E. Fragment II executes without exception
F. Fragment III executes without exception
11. Given:
And these two fragments:
If fragment I or II is inserted, independently, at line 8, which are true? (Choose all that apply.)
A. If fragment I is inserted, the output is 2
B. If fragment I is inserted, the output is 3
C. If fragment II is inserted, the output is 2
D. If fragment II is inserted, the output is 3
E. If fragment I is inserted, compilation fails
F. If fragment II is inserted, compilation fails
12. Given the proper import statement(s), and:
Which are true? (Choose all that apply.)
A. The size of s is 4
B. The size of s is 5
C. The size of s is 7
D. The size of subs is 1
E. The size of subs is 2
F. The size of subs is 3
G. The size of subs is 4
H. An exception is thrown at runtime
13. Given:
Which of the System.out.println statements will produce the output 1st after mango: p? (Choose all that apply.)
A. sop 1
B. sop 2
C. sop 3
D. sop 4
E. None; compilation fails
F. None; an exception is thrown at runtime
14. Given:
Which, inserted independently at line 9, will compile? (Choose all that apply.)
A. return new ArrayList <Inn> ();
B. return new ArrayList <Hotel> ();
C. return new ArrayList <Object> ();
D. return new ArrayList <Business> ();
15. Given:
What is the result?
A. 1 2
B. 2 2
C. 2 3
D. 3 2
E. 3 3
F. Compilation fails
G. An exception is thrown at runtime
16. Given:
Which are true? (Choose all that apply.)
A. Compilation fails
B. The output will contain a 1
C. The output will contain a 2
D. The output will contain a – 1
E. An exception is thrown at runtime
F. The output will contain " key map marble pen"
G. The output will contain " pen marble map key"
1. Given:
Which statements could be inserted at // INSERT DECLARATION HERE to allow this code to compile and run? (Choose all that apply.)
A. List <List <Integer> > table = new List <List <Integer> > ();
B. List <List <Integer> > table = new ArrayList <List <Integer> > ();
C. List <List <Integer> > table = new ArrayList <ArrayList <Integer> > ();
D. List <List, Integer> table = new List <List, Integer> ();
E. List <List, Integer> table = new ArrayList <List, Integer> ();
F. List <List, Integer> table = new ArrayList <ArrayList, Integer> ();
G. None of the above
Answer: |
|
B is correct. |
|
A is incorrect because List is an interface, so you can't say new List() regardless of any generic types. D, E, and F are incorrect because List only takes one type parameter (a Map would take two, not a List). C is tempting, but incorrect. The type argument <List <Integer> > must be the same for both sides of the assignment, even though the constructor new ArrayList() on the right side is a subtype of the declared type List on the left. (Objective 6.4) |
2. Which statements are true about comparing two instances of the same class, given that the equals() and hashCode() methods have been properly overridden? (Choose all that apply.)
A. If the equals() method returns true, the hashCode() comparison == might return false
B. If the equals() method returns false, the hashCode() comparison == might return true
C. If the hashCode() comparison == returns true, the equals() method must return true
D. If the hashCode() comparison == returns true, the equals() method might return true
E. If the hashCode() comparison != returns true, the equals() method might return true
Answer: |
|
B and D. B is true because often two dissimilar objects can return the same hashcode value. D is true because if the hashCode() comparison returns ==, the two objects might or might not be equal. |
|
A, C, and E are incorrect. C is incorrect because the hashCode() method is very flexible in its return values, and often two dissimilar objects can return the same hash code value. A and E are a negation of the hashCode() and equals() contract. (Objective 6.2) |
3. Given:
Which statements are true?
A. The before() method will print 1 2
B. The before() method will print 1 2 3
C. The before() method will print three numbers, but the order cannot be determined
D. The before() method will not compile
E. The before() method will throw an exception at runtime
Answer: |
|
E is correct. You can't put both Strings and ints into the same TreeSet. Without generics, the compiler has no way of knowing what type is appropriate for this TreeSet, so it allows everything to compile. At runtime, the TreeSet will try to sort the elements as they're added, and when it tries to compare an Integer with a String it will throw a ClassCastException. Note that although the before() method does not use generics, it does use autoboxing. Watch out for code that uses some new features and some old features mixed together. |
|
A, B, C, and D are incorrect based on the above. (Objective 6.5) |
4. Given:
Which is correct? (Choose all that apply.)
A. As the code stands it will not compile
B. As the code stands the output will be 2
C. As the code stands the output will be 3
D. If the hashCode() method is uncommented the output will be 2
E. If the hashCode() method is uncommented the output will be 3
F. If the hashCode() method is uncommented the code will not compile
Answer: |
|
C and D are correct. If hashCode() is not overridden then every entry will go into its own bucket, and the overridden equals() method will have no effect on determining equivalency. If hashCode() is overridden, then the overridden equals() method will view t1 and t2 as duplicates. |
|
A, B, E, and F are incorrect based on the above. (Objective 6.2) |
5. Given:
This class is to be updated to make use of appropriate generic types, with no changes in behavior (for better or worse). Which of these steps could be performed? (Choose three.)
A. Replace line 13 with
B. Replace line 13 with
C. Replace line 13 with
D. Replace lines 17– 20 with
E. Replace lines 17– 20 with
F. Replace lines 17– 20 with
G. Replace line 24 with
H. Replace line 24 with
Answer: |
|
B, E, and G are correct. |
|
A is wrong because you can't use a primitive type as a type parameter. C is wrong because a Map takes two type parameters separated by a comma. D is wrong because an int can't autobox to a null, and F is wrong because a null can't unbox to 0. H is wrong because you can't autobox a primitive just by trying to invoke a method with it. (Objective 6.4) |
6. Given:
Which of the following changes (taken separately) would allow this code to compile? (Choose all that apply.)
A. Change the Carnivore interface to
B. Change the Herbivore interface to
C. Change the Sheep class to
D. Change the Sheep class to
E. Change the Wolf class to
F. No changes are necessary
Answer: |
|
B is correct. The problem with the original code is that Sheep tries to implement Herbivore <Sheep> and Herbivore declares that its type parameter E can be any type that extends Plant. Since a Sheep is not a Plant, Herbivore <Sheep> makes no sense—the type Sheep is outside the allowed range of Herbivore's parameter E. Only solutions that either alter the definition of a Sheep or alter the definition of Herbivore will be able to fix this. So A, E, and F are eliminated. B works, changing the definition of an Herbivore to allow it to eat Sheep solves the problem. C doesn't work because an Herbivore <Plant> must have a munch (Plant) method, not munch(Grass). And D doesn't work, because in D we made Sheep extend Plant, now the Wolf class breaks because its munch(Sheep) method no longer fulfills the contract of Carnivore. (Objective 6.4) |
7. Which collection class(es) allows you to grow or shrink its size and provides indexed access to its elements, but whose methods are not synchronized? (Choose all that apply.)
A. java.util.HashSet
B. java.util.LinkedHashSet
C. java.util.List
D. java.util.ArrayList
E. java.util.Vector
F. java.util.PriorityQueue
Answer: |
|
D is correct. All of the collection classes allow you to grow or shrink the size of your collection. ArrayList provides an index to its elements. The newer collection classes tend not to have synchronized methods. Vector is an older implementation of ArrayList functionality and has synchronized methods; it is slower than ArrayList. |
|
A, B, C, E, and F are incorrect based on the logic described above; Notes: C, List is an interface, and F, PriorityQueue does not offer access by index. (Objective 6.1) |
8. Given a method declared as
A programmer wants to use this method like this
Which pairs of declarations could be placed at // INSERT DECLARATIONS HERE to allow the code to compile? (Choose all that apply.)
A. ArrayList <Integer> input = null;
ArrayList <Integer> output = null;
B. ArrayList <Integer> input = null;
List <Integer> output = null;
C. ArrayList <Integer> input = null;
List <Number> output = null;
D. List <Number> input = null;
ArrayList <Integer> output = null;
E. List <Number> input = null;
List <Number> output = null;
F. List <Integer> input = null;
List <Integer> output = null;
G. None of the above
Answer: |
|
B, E, and F are correct. |
|
The return type of process is definitely declared as a List, not an ArrayList, so A and D are wrong. C is wrong because the return type evaluates to List <Integer>, and that can't be assigned to a variable of type List <Number>. Of course all these would probably cause a NullPointerException since the variables are still null—but the question only asked us to get the code to compile. (Objective 6.4) |
9. Given the proper import statement(s), and
A. 2 2 3 3
B. 2 2 3 4
C. 4 3 3 4
D. 2 2 3 3 3
E. 4 3 3 3 3
F. 2 2 3 3 4
G. Compilation fails
H. An exception is thrown at runtime
Answer: |
|
B is correct. For the sake of the exam, add() and offer() both add to (in this case), naturally sorted queues. The calls to poll() both return and then remove the first item from the queue, so the if test fails. |
|
A, C, D, E, F, G, and H are incorrect based on the above. (Objective 6.1) |
10. Given:
And these three fragments:
When fragments I, II, or III are inserted, independently, at line 7, which are true? (Choose all that apply.)
A. Fragment I compiles
B. Fragment II compiles
C. Fragment III compiles
D. Fragment I executes without exception
E. Fragment II executes without exception
F. Fragment III executes without exception
Answer: |
|
A, B, C, D, and F are all correct. |
|
Only E is incorrect. Elements of a TreeSet must in some way implement Comparable. (Objective 6.1) |
11. Given:
And these two fragments:
If fragment I or II is inserted, independently, at line 8, which are true? (Choose all that apply.)
A. If fragment I is inserted, the output is 2
B. If fragment I is inserted, the output is 3
C. If fragment II is inserted, the output is 2
D. If fragment II is inserted, the output is 3
E. If fragment I is inserted, compilation fails
F. If fragment II is inserted, compilation fails
Answer: |
|
A and D are correct. While fragment II wouldn't fulfill the hashCode() contract (as you can see by the results), it is legal Java. For the purpose of the exam, if you don't override hashCode(), every object will have a unique hashcode. |
|
B, C, E, and F are incorrect based on the above. (Objective 6.2) |
12. Given the proper import statement(s), and:
Which are true? (Choose all that apply.)
A. The size of s is 4
B. The size of s is 5
C. The size of s is 7
D. The size of subs is 1
E. The size of subs is 2
F. The size of subs is 3
G. The size of subs is 4
H. An exception is thrown at runtime
Answer: |
|
B and F are correct. After "g" is added, TreeSet s contains six elements and TreeSet subs contains three (b, c, d), because "g" is out of the range of subs. The first pollFirst() finds and removes only the "a". The second pollFirst() finds and removes the "b" from both TreeSets (remember they are backed). The final add() is in range of both TreeSets. The final contents are [c,c2,d,e,g] and [c,c2,d]. |
|
A, C, D, E, G, and H are incorrect based on the above. (Objective 6.3) |
13. Given:
Which of the System.out.println statements will produce the output 1st after mango: p? (Choose all that apply.)
A. sop 1
B. sop 2
C. sop 3
D. sop 4
E. None; compilation fails
F. None; an exception is thrown at runtime
Answer: |
|
A is correct. The ceilingKey() method's argument is inclusive. The floorKey() method would be used to find keys before the specified key. The firstKey() method's argument is also inclusive. |
|
B, C, D, E, and F are incorrect based on the above. (Objective 6.3) |
14. Given:
Which, inserted independently at line 9, will compile? (Choose all that apply.)
A. return new ArrayList <Inn> ();
B. return new ArrayList <Hotel> ();
C. return new ArrayList <Object> ();
D. return new ArrayList <Business> ();
Answer: |
|
B is correct. |
|
A is incorrect because polymorphic assignments don't apply to generic type parameters. C and D are incorrect because they don't follow basic polymorphism rules. (Objective 6.4) |
15. Given:
What is the result?
A. 1 2
B. 2 2
C. 2 3
D. 3 2
E. 3 3
F. Compilation fails
G. An exception is thrown at runtime
Answer: |
|
G is correct. Class Dog needs to implement Comparable in order for a TreeSet (which keeps its elements sorted) to be able to contain Dog objects. |
|
A, B, C, D, E, and F are incorrect based on the above. (Objective 6.5) |
16. Given:
Which are true? (Choose all that apply.)
A. Compilation fails
B. The output will contain a 1
C. The output will contain a 2
D. The output will contain a – 1
E. An exception is thrown at runtime
F. The output will contain " key map marble pen"
G. The output will contain " pen marble map key"
Answer: |
|
D and G are correct. First, the compareTo() method will reverse the normal sort. Second, the sort() is valid. Third, the binarySearch() gives – 1 because it needs to be invoked using the same Comparator (o), as was used to sort the array. Note that when the binarySearch() returns an "undefined result" it doesn't officially have to be a -1, but it usually is, so if you selected only G, you get full credit! |
|
A, B, C, E, and F are incorrect based on the above. (Objective 6.5) |
3.14.144.108