23.11. Programming Exercises

 
[Page 705 ( continued )]

21.9. (Optional) Case Study: Generic Matrix Class

This supplement presents a case study on designing classes for matrix operations using generic types. The addition and multiplication operations for all matrices are similar except that their element types differ . Therefore, you can design a superclass that describes the common operations shared by matrices of all types regardless of their element types, and you can create subclasses tailored to specific types of matrices. This case study gives implementations for two types: int and Rational . For the int type, the wrapper class Integer should be used to wrap an int value into an object, so that the object is passed in the methods for operations.

The class diagram is shown in Figure 21.7. The methods addMatrix and multiplyMatrix add and multiply two matrices of a generic type E[][] . The static method printResult displays the matrices, the operations, and their result. The methods add , multiply , and zero are abstract methods because their implementations are dependent on the specific type of the array elements. For example, the zero() method returns for the Integer type and 0/1 for the Rational type. These methods will be implemented in the subclasses in which the matrix element type is specified.


[Page 706]
Figure 21.7. The GenericMatrix class is an abstract superclass for IntegerMatrix and RationalMatrix .

IntegerMatrix and RationalMatrix are concrete subclasses of GenericMatrix . These two classes implement the add , multiply , and zero methods defined in the GenericMatrix class.

Listing 21.11 implements the GenericMatrix class. <E extends Number> in line 1 specifies that the generic type is a subtype of Number . Three abstract methods ” add , multiply , and zero ”are defined in lines 3, 6, and 9. These methods are abstract because they cannot be implemented without knowing the exact type of the elements. The addMaxtrix (lines 12 “30) and multiplyMatrix (lines 33 “56) methods implement the methods for adding and multiplying two matrices. All these methods must be non-static because they use generic type E . The printResult method (lines 59 “83) is static because it is not tied to specific instances.

The matrix element type is generic. This enables you to use an object of any class as long as you can implement the abstract add , multiply , and zero methods in subclasses.

The addMatrix and multiplyMatrix methods (lines 12 “57) are concrete methods. They are ready to use as long as the add , multiply , and zero methods are implemented in the subclasses.

The addMatrix and multiplyMatrix methods check the bounds of the matrices before performing operations. If the two matrices have incompatible bounds, the program throws an exception (lines 16, 36).

Listing 21.11. GenericMatrix.java
(This item is displayed on pages 706 - 708 in the print version)
 1   public abstract class   GenericMatrix  <E   extends   Number>  { 2  /** Abstract method for adding two elements of the matrices */  3    protected abstract   E add(E o1, E o2);  4 5  /** Abstract method for multiplying two elements of the matrices */  6    protected abstract   E multiply(E o1, E o2);  7 8  /** Abstract method for defining zero for the matrix element */  9    protected abstract   E zero();  10 11  /** Add two matrices */  12    public   E[][] addMatrix(E[][] matrix1, E[][] matrix2)  { 13  // Check bounds of the two matrices  14   if   ((matrix1.length != matrix2.length)  15 (matrix1[     ].length != matrix2.length)) { 16   throw new   RuntimeException( 17   "The matrices do not have the same size "   ); 18 } 19 

[Page 707]
 20 E[][] result = 21 (E[][])   new   Number[matrix1.length][matrix1[     ].length]; 22 23  // Perform addition  24   for   (   int   i =     ; i < result.length; i++) 25   for   (   int   j =     ; j < result[i].length; j++) { 26 result[i][j] = add(matrix1[i][j], matrix2[i][j]); 27 } 28 29   return   result; 30 } 31 32  /** Multiply two matrices */  33    public   E[][] multiplyMatrix(E[][] matrix1, E[][] matrix2)  { 34  // Check bounds  35   if   (matrix1[     ].length != matrix2.length) { 36   throw new   RuntimeException( 37   "The matrices do not have compatible size"   ); 38 } 39 40  // Create result matrix  41 E[][] result = 42 (E[][])   new   Number[matrix1.length][matrix2[     ].length]; 43 44  // Perform multiplication of two matrices  45   for   (   int   i =     ; i < result.length; i++) { 46   for   (   int   j =     ; j < result[     ].length; j++) { 47 result[i][j] = zero(); 48 49   for   (   int   k =     ; k < matrix1[     ].length; k++) { 50 result[i][j] = add(result[i][j], 51 multiply(matrix1[i][k], matrix2[k][j])); 52 } 53 } 54 } 55 56   return   result; 57 } 58 59  /** Print matrices, the operator, and their operation result */  60    public static void   printResult(  61  Number[][] m1, Number[][] m2, Number[][] m3,   char   op)  { 62   for   (   int   i =     ; i < m1.length; i++) { 63   for   (   int   j =     ; j < m1[     ].length; j++) 64 System.out.print(   " "   + m1[i][j]); 65 66   if   (i == m1.length /   2   ) 67 System.out.print(   " "   + op +   " "   ); 68   else   69 System.out.print(   " "   ); 70 71   for   (   int   j =     ; j < m2.length; j++) 72 System.out.print(   " "   + m2[i][j]); 73 74   if   (i == m1.length /   2   ) 75 System.out.print(   " = "   ); 76   else   77 System.out.print(   " "   ); 78 

[Page 708]
 79   for   (   int   j =     ; j < m3.length; j++) 80 System.out.print(m3[i][j] +   " "   ); 81 82 System.out.println(); 83 } 84 } 85 } 

Listing 21.12 implements the IntegerMatrix class. The class extends Generic-Matrix<Integer> in line 1. After the generic instantiation, the add method in GenericMatrix<Integer> is now Integer add(Integer o1, Integer o2) . The add , multiply , and zero methods are implemented for Integer objects. These methods are still protected, because they are only invoked by the addMatrix and multiplyMatrix methods.

Listing 21.12. IntegerMatrix.java
 1   public class   IntegerMatrix   extends    GenericMatrix<Integer>  { 2  /** Implement the add method for adding two matrix elements */  3    protected   Integer add(Integer o1, Integer o2)  { 4   return new   Integer(o1.intValue() + o2.intValue()); 5 } 6 7  /** Implement the multiply method for multiplying two  8  matrix elements */  9    protected   Integer multiply(Integer o1, Integer o2)  { 10   return new   Integer(o1.intValue() * o2.intValue()); 11 } 12 13  /** Implement the zero method to specify zero for Integer */  14    protected   Integer zero()  { 15   return new   Integer(     ); 16 } 17 } 

Listing 21.13 implements the RationalMatrix class. The Rational class was introduced in §11.5, "Case Study: The Rational Class." Rational is a subtype of Number . The RationalMatrix class extends GenericMatrix<Rational> in line 1. After the generic instantiation, the add method in GenericMatrix<Rational> is now Rational add(Rational o1, Rational o2) . The add , multiply , and zero methods are implemented for Rational objects. These methods are still protected, because they are only invoked by the addMatrix and multiplyMatrix methods.

Listing 21.13. RationalMatrix.java
(This item is displayed on pages 708 - 709 in the print version)
 1   public class   RationalMatrix   extends    GenericMatrix<Rational>  { 2  /** Implement the add method for adding two rational elements */  3    protected   Rational add(Rational r1, Rational r2)  { 4   return   r1.add(r2); 5 } 6 7  /** Implement the multiply method for multiplying  8  two rational elements */  9    protected   Rational multiply(Rational r1, Rational r2)  { 10   return   r1.multiply(r2); 11 } 12 

[Page 709]
 13  /** Implement the zero method to specify zero for Rational */  14    protected   Rational zero()  { 15   return new   Rational(     ,   1   ); 16 } 17 } 

Listing 21.14 gives a program that creates two Integer matrices (lines 4 “5) and an IntegerMatrix object (line 8), and adds and multiplies two matrices in lines 12 and 16. The output is shown in Figure 21.8.

Figure 21.8. The program creates two Integer matrices and performs addition and multiplication on them.


Listing 21.14. TestIntegerMatrix.java
 1   public class   TestIntegerMatrix { 2   public static void   main(String[] args) { 3  // Create Integer arrays m1, m2  4 Integer[][] m1 =   new   Integer[][]{{   1   ,   2   ,   3   }, {   4   ,   5   ,   6   }, {   1   ,   1   ,   1   }}; 5 Integer[][] m2 =   new   Integer[][]{{   1   ,   1   ,   1   }, {   2   ,   2   ,   2   }, {     ,     ,     }}; 6 7  // Create an instance of IntegerMatrix  8  IntegerMatrix integerMatrix =   new   IntegerMatrix();  9 10 System.out.println(   "\nm1 + m2 is "   ); 11 integerMatrix.printResult( 12 m1, m2,  integerMatrix.addMatrix(m1, m2)  ,   '+'   ); 13 14 System.out.println(   "\nm1 * m2 is "   ); 15 integerMatrix.printResult( 16 m1, m2,  integerMatrix.multiplyMatrix(m1, m2)  ,   '*'   ); 17 } 18 } 

Listing 21.15 gives a program that creates two Rational matrices (lines 4 “10) and a RationalMatrix object (line 13), and adds and multiplies two matrices in lines 17 and 21. The output is shown in Figure 21.9.

Figure 21.9. The program creates two matrices of rational numbers and performs addition and multiplication on them.
(This item is displayed on page 710 in the print version)


Listing 21.15. TestRationalMatrix.java
(This item is displayed on pages 709 - 710 in the print version)
 1   public class   TestRationalMatrix { 2   public static void   main(String[] args) { 3  // Create two Rational arrays m1 and m2  4 Rational[][] m1 =   new   Rational[   3   ][   3   ]; 5 Rational[][] m2 =   new   Rational[   3   ][   3   ]; 6   for   (   int   i =     ; i < m1.length; i++) 

[Page 710]
 7   for   (   int   j =     ; j < m1[     ].length; j++) { 8 m1[i][j] =   new   Rational(i +   1   , j +   5   ); 9 m2[i][j] =   new   Rational(i +   1   , j +   6   ); 10 } 11 12  // Create an instance of RationalMatrix  13  RationalMatrix rationalMatrix =   new   RationalMatrix();  14 15 System.out.println(   "\nm1 + m2 is "   ); 16 rationalMatrix.printResult( 17 m1, m2,  rationalMatrix.addMatrix(m1, m2)  ,   '+'   ); 18 19 System.out.println(   "\nm1 * m2 is "   ); 20 rationalMatrix.printResult( 21 m1, m2,  rationalMatrix.multiplyMatrix(m1, m2)  ,   '*'   ); 22 } 23 } 

 


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