Holding Your Objects
offer( ) is one of the Queue-specific methods; it inserts an element at the tail of the queue if it can, or returns false. Both peek( ) and element( ) return the head of the queue without removing it, but peek( ) returns null if the queue is empty and element( ) throws NoSuchElementException. Both poll( ) and remove( ) remove and return the head of the queue, but poll( ) returns null if the queue is empty, while remove( ) throws NoSuchElementException.
If you implement Collection, you also implement iterator( ), and just implementing iterator( ) alone requires only slight less effort than inheriting from AbstractCollection. However , if your class already inherits from another class, then you cannot also inherit from AbstractCollection.
Java SE5 introduced a new interface called Iterable which contains an iterator( ) method to produce and Iterator, and the Iterable interface is what foreach uses to move through a sequence. So if you create any class that implements Iterable, you can use it in a foreach statement.
public class ModifyingArraysAsList {
public static void main(String[] args) {
Random rand=new Random(47);
Integer[] ia={1,2,3,4,5,6,7,8,9,10};
List<Integer> list1=new ArrayList<Integer>(Arrays.asList(ia));
System.out.println("Before shuffling: "+list1);
Collections.shuffle(list1,rand);
System.out.println("After shuffling: "+list1);
System.out.println("array: "+Arrays.toString(ia));
List<Integer> list2=Arrays.asList(ia);
System.out.println("Before shuffling: "+list2);
Collections.shuffle(list2,rand);
System.out.println("After shuffling: "+list2);
System.out.println("array: "+Arrays.toString(ia));
}
}
outputs:
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [4, 6, 3, 1, 8, 7, 2, 5, 10, 9]
array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
array: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
You can see from the output that the Collections.shuffle( ) method doesn’t affect the original array, but only shuffles the references in shuffled. But if the List produced by Arrays.asList() is shuffled directly, it will modify the underlying array.
A Map is a way to associate not integral values, but objects with other objects. HashMaps are designed for rapid access, whereas a TreeMap keeps its keys in sorted order, and thus is not as fast as a HashMap. A LinkedHashMap keeps its elements in insertion order, but provides rapid access with hashing.
There is no need to use the legacy classes Vector, Hashtable, and Stack in new code.
Sets except TreeSet have exactly the same interface as Collection. List and Collection differ significantly, although List requires methods that are in Collection. On the other hand ,the methods in the Queue interface stand alone; the Collection methods are not required to create a functioning Queue implementation. Finally, the only intersection between Map and Collection is the fact that a Map can produce Collections using the entrySet( ) and values( ) methods.
Error Handling with Exceptions
You may want to send error output to the standard error stream by writing to System.err. This is usually a better place to send error information than System.out, which may be redirected. If you send output to System.err, it will not be redirected along with System.out so the user is more likely to notice it.
Rethrowing an exception causes it to go to the exception handlers in the next higher context. Any further catch clauses for the same try block are still ignored. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract all the information from that object.
If you simply rethrow the current exception, the information that you print about that exception in printStracTrace( ) will pertain to the exception’s origin, not the place where you rethrow it. If you want to install new stack trace information, you can do so by calling fillInStackTrace( ), which returns a Throwable object that it creates by stuffing the current stack information into the old exception object.
public class Rethrowing {
public static void f() throws Exception{
System.out.println("originating the exception in f( )");
throw new Exception("thrown from f( )");
}
public static void g() throws Exception{
try{
f();
}catch(Exception e){
System.out.println("Inside g(),e.printStackTrace()");
e.printStackTrace(System.out);
throw e;
}
}
public static void h() throws Exception{
try{
f();
}catch(Exception e){
System.out.println("Inside h(), e.printStackTrace()");
e.printStackTrace(System.out);
throw (Exception)e.fillInStackTrace();
}
}
public static void main(String[] args){
try {
g();
} catch (Exception e) {
System.out.println("main: printStackTrace()");
e.printStackTrace(System.out);
}
try {
h();
} catch (Exception e) {
System.out.println("main: printStackTrace()");
e.printStackTrace(System.out);
}
}
}
output:
originating the exception in f( )
Inside g(),e.printStackTrace()
java.lang.Exception: thrown from f( )
at errorhandling.Rethrowing.f(Rethrowing.java:18)
at errorhandling.Rethrowing.g(Rethrowing.java:23)
at errorhandling.Rethrowing.main(Rethrowing.java:43)
main: printStackTrace()
java.lang.Exception: thrown from f( )
at errorhandling.Rethrowing.f(Rethrowing.java:18)
at errorhandling.Rethrowing.g(Rethrowing.java:23)
at errorhandling.Rethrowing.main(Rethrowing.java:43)
originating the exception in f( )
Inside h(), e.printStackTrace()
java.lang.Exception: thrown from f( )
at errorhandling.Rethrowing.f(Rethrowing.java:18)
at errorhandling.Rethrowing.h(Rethrowing.java:33)
at errorhandling.Rethrowing.main(Rethrowing.java:49)
main: printStackTrace()
java.lang.Exception: thrown from f( )
at errorhandling.Rethrowing.h(Rethrowing.java:37)
at errorhandling.Rethrowing.main(Rethrowing.java:49)