11.4. Case Study - Object-Oriented Design

 
[Page 356 ( continued )]

10.5. Processing Primitive Data Type Values as Objects

Primitive data types are not used as objects in Java due to performance considerations. Because of the overhead of processing objects, the language's performance would be adversely affected if primitive data types were treated as objects. However, many Java methods require the use of objects as arguments. For example, the add(object) method in the ArrayList class adds an object to an ArrayList . Java offers a convenient way to incorporate , or wrap, a primitive data type into an object (e.g., wrapping int into the Integer class, and wrapping double into the Double class). The corresponding class is called a wrapper class . By using a wrapper object instead of a primitive data type variable, you can take advantage of generic programming.

Java provides Boolean , Character , Double , Float , Byte , Short , Integer , and Long wrapper classes for primitive data types. These classes are grouped in the java.lang package. Their inheritance hierarchy is shown in Figure 10.7.

Figure 10.7. The Number class is an abstract superclass for Double , Float , Long , Integer , Short , and Byte .
(This item is displayed on page 357 in the print version)

Note

The wrapper class name for a primitive type is the same as the primitive data type name with the first letter capitalized. The exceptions are Integer and Character .


Each numeric wrapper class extends the abstract Number class, which contains the methods doubleValue() , floatValue() , intValue() , longValue() , shortValue() , and byteValue() . These methods "convert" objects into primitive type values. The methods doubleValue() , floatValue() , intValue() , and longValue() are abstract. The methods byteValue() and shortValue() are not abstract; they simply return (byte)intValue() and (short)intValue() , respectively.


[Page 357]

Each wrapper class overrides the toString , equals , and hashCode methods defined in the Object class. Since all the numeric wrapper classes and the Character class implement the Comparable interface, the compareTo method is implemented in these classes.

Wrapper classes are very similar. The Character class was introduced in Chapter 8, "Strings and Text I/O." The Boolean class is rarely used. The following sections use Integer and Double as examples to introduce the numeric wrapper classes. The key features of Integer and Double are shown in Figure 10.8.

Figure 10.8. The wrapper classes provide constructors, constants, and conversion methods for manipulating various data types.


[Page 358]

10.5.1. Numeric Wrapper Class Constructors

You can construct a wrapper object either from a primitive data type value or from a string representing the numeric value. The constructors for Integer and Double are:

   public   Integer(   int   value)   public   Integer(String s)   public   Double(   double   value)   public   Double(String s) 

For example, you can construct a wrapper object for double value 5.0 using either

 Double doubleObject =   new   Double(   5.0   ); 

or

 Double doubleObject =   new   Double(   "5.0"   ); 

You can construct a wrapper object for int value 5 using either

 Integer integerObject =   new   Integer(   5   ); 

or

 Integer integerObject =   new   Integer(   "5"   ); 

Note

(1) The wrapper classes do not have no-arg constructors. (2) The instances of all wrapper classes are immutable ; this means that their internal values cannot be changed once the objects are created.


10.5.2. Numeric Wrapper Class Constants

Each numeric wrapper class has the constants MAX_VALUE and MIN_VALUE . MAX_VALUE represents the maximum value of the corresponding primitive data type. For Byte , Short , Integer , and Long , MIN_VALUE represents the minimum byte , short , int , and long values. For Float and Double , MIN_VALUE represents the minimum positive float and double values. The following statements display the maximum integer (2, 147, 483, 647), the minimum positive float (1.4E “45), and the maximum double floating-point number (1.79769313486231570e+308d):

 System.out.println(   "The maximum integer is "   + Integer.MAX_VALUE); System.out.println(   "The minimum positive float is "   + Float.MIN_VALUE); System.out.println(   "The maximum double precision floating-point number is "   + Double.MAX_VALUE); 

10.5.3. Conversion Methods

Each numeric wrapper class implements the abstract methods doubleValue , floatValue , intValue , longValue , and shortValue , which are defined in the Number class. These methods "convert" objects into primitive type values.

For example,

   long   l = doubleObject.longValue();  // Note it truncates  

This converts doubleObject 's double value to a long variable l

   int   i = integerObject.intValue(); 


[Page 359]

This assigns the int value of integerObject to i

   double   d =   5.9   ; Double doubleObject =   new   Double(d); String s = doubleObject.toString(); 

This converts double d to a string s .

10.5.4. The Static valueOf Methods

The numeric wrapper classes have a useful class method, valueOf(String s) . This method creates a new object initialized to the value represented by the specified string. For example,

 Double doubleObject = Double.valueOf(   "12.4"   ); Integer integerObject = Integer.valueOf(   "12"   ); 

10.5.5. The Methods for Parsing Strings into Numbers

You have used the parseInt method in the Integer class to parse a numeric string into an int value and the parseDouble method in the Double class to parse a numeric string into a double value. Each numeric wrapper class has two overloaded parsing methods to parse a numeric string into an appropriate numeric value based on 10 (decimal) or any specified radix (e.g., 2 for binary, 8 for octal, and 16 for hexadecimal). These methods are shown below:

  // These two methods are in the Byte class    public static byte   parseByte(String s)   public static byte   parseByte(String s, int radix)  // These two methods are in the Short class    public static short   parseShort(String s)   public static short   parseShort(String s, int radix)  // These two methods are in the Integer class    public static int   parseInt(String s)   public static int   parseInt(String s, int radix)  // These two methods are in the Long class    public static long   parseLong(String s)   public static long   parseLong(String s, int radix)  // These two methods are in the Float class    public static float   parseFloat(String s)   public static float   parseFloat(String s, int radix)  // These two methods are in the Double class    public static double   parseDouble(String s)   public static double   parseDouble(String s, int radix) 

For example,

 Integer.parseInt(   "11"   ,   2   ) returns 3; Integer.parseInt(   "12"   ,   8   ) returns 10; Integer.parseInt(   "13"   ,   10   ) returns 13; Integer.parseInt(   "1A"   ,   16   ) returns 26; 

Integer.parseInt("12", 2) would raise a runtime exception because 12 is not a binary number.

10.5.6. (Optional) BigInteger and BigDecimal Classes

If you need to compute with very large numbers and high precision, you can use the BigInteger and BigDecimal classes in the java.math package. They are wrapper classes for integer and decimal values. Both are immutable . Both extend the Number class and implement the Comparable interface. The largest integer of the long type is 9223372036854775807 . An instance of BigInteger can represent an integer of any size . You can use new BigInteger(String) and new BigDecimal(String) to create an instance of BigInteger and BigDecimal and use the add , subtract , multiple , and divide methods to perform numeric operations. For example, the following code creates two BigInteger objects and multiplies them:


[Page 360]
 BigInteger a =   new   BigInteger(   "9223372036854775807"   ); BigInteger b =   new   BigInteger(   "10000000"   ); BigInteger c = a.multiply(b); System.out.println(c); 

The output is 92233720368547758070000000 .

There is no limit to the precision of a BigDecimal object. The divide method may throw an ArithmeticException if the result cannot be terminated . However, you can use the overloaded divide(BigDecimal d, int scale, int roundingMode) method to specify a scale and a rounding mode to avoid this exception. For example, the following code created two BigDecimal objects and performs division with scale 20 and rounding mode BigDecimal.ROUND_UP :

 BigDecimal a =   new   BigDecimal(   1.0   ); BigDecimal b =   new   BigDecimal(   3   ); BigDecimal c = a.divide(b,   20   , BigDecimal.ROUND_UP); System.out.println(c); 

The output is 0.33333333333333333334 .

10.5.7. Example: Sorting an Array of Objects

This example presents a static generic method for sorting an array of comparable objects. The objects are instances of the Comparable interface, and they are compared using the compareTo method. The method can be used to sort an array of any objects as long as their classes implement the Comparable interface.

To test the method, the program sorts an array of integers, an array of double numbers, an array of characters , and an array of strings. The program is shown in Listing 10.5. Figure 10.9 shows a sample run of the code.

Figure 10.9. The program uses a generic sort method to sort an array of comparable objects.


Listing 10.5. GenericSort.java
(This item is displayed on pages 360 - 361 in the print version)
 1   public class   GenericSort { 2   public static void   main(String[] args) { 3  // Create an Integer array  4 Integer[] intArray = {   new   Integer(   2   ),   new   Integer(   4   ), 5   new   Integer(   3   )}; 6 

[Page 361]
 7  // Create a Double array  8 Double[] doubleArray = {   new   Double(   3   .   4   ),   new   Double(   1   .   3   ), 9   new   Double(   -22   .   1   )}; 10 11  // Create a Character array  12 Character[] charArray = {   new   Character(   'a'   ), 13   new   Character(   'J'   ),   new   Character(   'r'   )}; 14 15  // Create a String array  16 String[] stringArray = {   "Tom"   ,   "John"   ,   "Fred"   }; 17 18  // Sort the arrays  19  sort(intArray);  20  sort(doubleArray);  21  sort(charArray);  22  sort(stringArray);  23 24  // Display the sorted arrays  25 System.out.print(   "Sorted Integer objects: "   ); 26 printList(intArray); 27 System.out.print(   "Sorted Double objects: "   ); 28 printList(doubleArray); 29 System.out.print(   "Sorted Character objects: "   ); 30 printList(charArray); 31 System.out.print(   "Sorted String objects: "   ); 32 printList(stringArray); 33 } 34 35  /** Sort an array of comparable objects */  36    public static void   sort(Object[] list)  { 37 Object currentMax; 38   int   currentMaxIndex; 39 40   for   (   int   i = list.length -   1   ; i >=   1   ; i ” ”) { 41  // Find the maximum in the list[0..i]  42 currentMax = list[i]; 43 currentMaxIndex = i; 44 45   for   (   int   j = i -   1   ; j >=     ; j ” ”) { 46    if   (((Comparable)currentMax).compareTo(list[j]) <     )  { 47 currentMax = list[j]; 48 currentMaxIndex = j; 49 } 50 } 51 52  // Swap list[i] with list[currentMaxIndex] if necessary;  53   if   (currentMaxIndex != i) { 54 list[currentMaxIndex] = list[i]; 55 list[i] = currentMax; 56 } 57 } 58 } 59 60  /** Print an array of objects */  61   public static void   printList(Object[] list) { 62   for   (   int   i =     ; i < list.length; i++) 63 System.out.print(list[i] +   " "   ); 64 System.out.println(); 65 } 66 } 


[Page 362]

The algorithm for the sort method is the same as in §6.8.1, "Selection Sort." The sort method in §6.8.1 sorts an array of double values. The sort method in this example can sort an array of any object type, provided that the objects are also instances of the Comparable interface. This is another example of generic programming , a subject discussed in §9.7, "Polymorphism, Dynamic Binding, and Generic Programming." Generic programming enables a method to operate on arguments of generic types, making it reusable with multiple types.

Integer , Double , Character , and String implement Comparable , so the objects of these classes can be compared using the compareTo method. The sort method uses the compareTo method to determine the order of the objects in the array.

Tip

Java provides a static sort method for sorting an array of any object type in the java.util.Arrays class, provided that the elements in the array are comparable. Thus you can use the following code to sort arrays in this example:

  java.util.Arrays.sort(intArray);   java.util.Arrays.sort(doubleArray);   java.util.Arrays.sort(charArray);   java.util.Arrays.sort(stringArray);  


Note

Arrays are objects. An array is an instance of the Object class. Furthermore, if A is a subtype of B , every instance of A[] is an instance of B[] . Therefore, the following statements are all true:

   new   int[   10   ]   instanceof   Object   new   Integer[   10   ]   instanceof   Object   new   Integer[   10   ]   instanceof   Comparable[]   new   Integer[   10   ]   instanceof   Number[]   new   Number[   10   ]   instanceof   Object[] 


Caution

Although an int value can be assigned to a double type variable, int[] and double[] are two incompatible types. Therefore, you cannot assign an int[] array to a variable of double[] or Object[] type.


 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net