Chapter 1. What's New?
1.1 Working with Arrays
String[] s1 =  { "1", "2", "3" };
{ "1", "2", "3" };
System.out.println(Arrays.toString(s1));
String[][] s2 =  {
{  { "1", "2", "3" },
{ "1", "2", "3" },  { "4", "5", "6" } };
{ "4", "5", "6" } };
System.out.println(Arrays.deepToString(s2));
String[][] s3 =  {
{  { "1", "2", "3" },
{ "1", "2", "3" },  { "4", "5", "6" } };
{ "4", "5", "6" } };
System.out.println(Arrays.deepEquals(s2, s3)); /* --- console output --- */
 [1, 2, 3]
[1, 2, 3]
 [[1, 2, 3], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6]]
 true
trueThe first method to take note of, 
at least for Tiger fans, is 
toString( ). This handles the rather annoying task of printing arrays for you. While this is trivial to write on your own, it's still nice that Sun takes care of it for you now. 
Another similar, but also new, 
method is 
deepToString( ). This method takes in an object array, and prints out its contents, including the contents of any arrays that it might contain.
Finally, 
Arrays provides a 
deepEquals( ) method 
that compares multidimensional arrays.
1.2 Using Queues Another cool collection 
addition is the 
java.util.Queue class, for all those occasions when you need FIFO (first-in, first-out) action.
 Queue q = new LinkedList();
Queue q = new LinkedList();
 q.offer("First");
q.offer("First");
 q.offer("Second");
q.offer("Second");
 q.offer("Third");
q.offer("Third");
 Object o;
 Object o;
 while ((o = q.poll()) != null)
 while ((o = q.poll()) != null)
 System.out.println(o);
         System.out.println(o);Use offer(), poll() instead of add(), remove() respectivelly. If you want the head without removing it, ues element() or peek().
In Tiger, LinkedList has been retrofitted to implement the Queue interface. While you can use it like any other List implementation, it can also be used as a Queue implementation. 
1.3 Ordering Queues Using Comparators
PriorityQueue, a Queue with Comparator. If you don't specify a Comparator, natural ordering occurs.
 import java.util.Comparator;
import java.util.Comparator;
 import java.util.PriorityQueue;
import java.util.PriorityQueue;
 import java.util.Queue;
import java.util.Queue;


 public class PriorityQueueTester
public class PriorityQueueTester  {
{

 public static void main(String[] args)
    public static void main(String[] args)  {
{
 Queue<Integer> pq = new PriorityQueue<Integer>(20,
        Queue<Integer> pq = new PriorityQueue<Integer>(20,

 new Comparator<Integer>()
                new Comparator<Integer>()  {
{

 public int compare(Integer i, Integer j)
                    public int compare(Integer i, Integer j)  {
{
 int result = i % 2 - j % 2;
                        int result = i % 2 - j % 2;
 if (result == 0)
                        if (result == 0)
 result = i - j;
                            result = i - j;
 return result;
                        return result;
 }
                    }
 });
                });
 // Fill up with data, in an odd order
        // Fill up with data, in an odd order

 for (int i = 0; i < 20; i++)
        for (int i = 0; i < 20; i++)  {
{
 pq.offer(20 - i);
            pq.offer(20 - i);
 }
        }
 // Print out and check ordering
        // Print out and check ordering

 for (int i = 0; i < 20; i++)
        for (int i = 0; i < 20; i++)  {
{
 System.out.print(pq.poll() + " ");
            System.out.print(pq.poll() + " ");
 }
        }
 }
    }
 }
}/* --- console output --- */
 2 4 6 8 10 12 14 16 18 20 1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20 1 3 5 7 9 11 13 15 17 19 1.4 Overriding Return Types 

 class Point2D
class Point2D  {
{
 protected int x, y;
    protected int x, y;


 public Point2D()
    public Point2D()  {
{
 this.x = 0;
        this.x = 0;
 this.y = 0;
        this.y = 0;
 }
    }


 public Point2D(int x, int y)
    public Point2D(int x, int y)  {
{
 this.x = x;
        this.x = x;
 this.y = y;
        this.y = y;
 }
    }
 }
}


 class Point3D extends Point2D
class Point3D extends Point2D  {
{
 protected int z;
    protected int z;


 public Point3D(int x, int y)
    public Point3D(int x, int y)  {
{
 this(x, y, 0);
        this(x, y, 0);
 }
    }


 public Point3D(int x, int y, int z)
    public Point3D(int x, int y, int z)  {
{
 this.x = x;
        this.x = x;
 this.y = y;
        this.y = y;
 this.z = z;
        this.z = z;
 }
    }
 }
}


 class Position2D
class Position2D  {
{
 Point2D location;
    Point2D location;


 public Position2D()
    public Position2D()  {
{
 this.location = new Point2D();
        this.location = new Point2D();
 }
    }


 public Position2D(int x, int y)
    public Position2D(int x, int y)  {
{
 this.location = new Point2D(x, y);
        this.location = new Point2D(x, y);
 }
    }


 public Point2D getLocation()
    public Point2D getLocation()  {
{
 return location;
        return location;
 }
    }

 }
}


 class Position3D extends Position2D
class Position3D extends Position2D  {
{
 Point3D location;
    Point3D location;


 public Position3D(int x, int y, int z)
    public Position3D(int x, int y, int z)  {
{
 this.location = new Point3D(x, y, z);
        this.location = new Point3D(x, y, z);
 }
    }


 public Point3D getLocation()
    public Point3D getLocation()  {
{
 return location;
        return location;
 }
    }
 }
}The key is the line public Point3D getLocation( ), which probably looks pretty odd to you, but get used to it. This is called a covariant return, and is only allowed if the return type of the subclass is an extension of the return type of the superclass. 
1.5 Taking Advantage of Better Unicode
In Tiger, Java has moved to support Unicode 4.0, which defines several characters that don't fit into 16 bits. This means that they won't fit into a char, and that has some far-reaching consequences. You'll have to use int to represent these characters, and as a result methods like Character.isUpperCase( ) and Character.isWhitespace( ) now have variants that accept int arguments. So if you're needing values in Unicode 3.0 that are not available in Unicode 3.0, you'll need to use these new methods..
Most of the new characters in Unicode 4.0 are Han ideographs.
1.6 Adding StringBuilder to the Mix 
Replace all your StringBuffer code with StringBuilder code. Really—it's as simple as that. If you're working in a single-thread environment, or in a piece of code where you aren't worried about multiple threads accessing the code, or synchronization, it's best to use StringBuilder instead of StringBuffer.