Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Intro_Java_brief_Liang2011.pdf
Скачиваний:
195
Добавлен:
26.03.2016
Размер:
10.44 Mб
Скачать

14.12 The BigInteger and BigDecimal Classes 481

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.

14.11 Automatic Conversion between Primitive Types and Wrapper Class Types

Java allows primitive types and wrapper classes to be converted automatically. For example, the following statement in (a) can be simplified as in (b) due to autoboxing:

 

Equivalent

 

Integer intObject = new Integer(2);

Integer intObject = 2;

(a)

autoboxing

(b)

Converting a primitive value to a wrapper object is called boxing. The reverse conversion

boxing

is called unboxing. The compiler will automatically box a primitive value that appears in a

unboxing

context requiring an object, and will unbox an object that appears in a context requiring a

 

primitive value. Consider the following example:

 

1

Integer[] intArray = {1, 2, 3};

 

2

System.out.println(intArray[0] + intArray[1] + intArray[2]);

 

In line 1, primitive values 1, 2, and 3 are automatically boxed into objects new Integer(1), new Integer(2), and new Integer(3). In line 2, objects intArray[0], intArray[1], and intArray[2] are automatically converted into int values that are added together.

14.12 The BigInteger and BigDecimal Classes

If you need to compute with very large integers or high-precision floating-point values, you can use the BigInteger and BigDecimal classes in the java.math package. Both are

immutable. Both extend the Number class and implement the Comparable interface. The immutable largest integer of the long type is Long.MAX_VALUE (i.e., 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, use the add, subtract, multiple, divide, and remainder methods to perform arithmetic operations, and use the compareTo method to compare two big numbers. For example, the following code creates two BigInteger objects and multiplies them.

BigInteger a = new BigInteger("9223372036854775807");

BigInteger b = new BigInteger("2");

BigInteger c = a.multiply(b); // 9223372036854775807 * 2

System.out.println(c);

482 Chapter 14

Abstract Classes and Interfaces

 

The output is 18446744073709551614.

 

 

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, where scale is the minimum

 

number of digits after the decimal point. For example, the following code creates 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.

 

 

Note that the factorial of an integer can be very large. Listing 14.11 gives a method that can

 

return the factorial of any integer.

 

LISTING 14.11 LargeFactorial.java

 

1

import java.math.*;

 

2

 

 

 

 

 

 

3

public class LargeFactorial {

 

4

public static void main(String[] args) {

 

5

 

System.out.println("50! is \n" + factorial(50));

 

6

}

 

 

 

 

 

7

 

 

 

 

 

 

8

public static BigInteger factorial(long n) {

constant

9

 

BigInteger result = BigInteger.ONE;

 

 

10

 

for (int i = 1; i <= n; i++)

multiply

11

 

 

result = result.multiply(new BigInteger(i + ""));

 

 

12

 

 

 

 

 

 

13

 

return result;

 

14

}

 

 

 

 

 

15

}

 

 

 

 

50! is 30414093201713378043612608166064768844377641568960512000000000000

BigInteger.ONE (line 9) is a constant defined in the BigInteger class. BigInteger.ONE is same as new BigInteger("1").

A new result is obtained by invoking the multiply method (line 11).

14.13 Case Study: The Rational Class

A rational number has a numerator and a denominator in the form a/b, where a is the numerator and b the denominator. For example, 1/3, 3/4, and 10/4 are rational numbers.

A rational number cannot have a denominator of 0, but a numerator of 0 is fine. Every integer i is equivalent to a rational number i/1. Rational numbers are used in exact computations involving fractions—for example, 1/3 = 0.33333 Á . This number cannot be precisely represented in floating-point format using data type double or float. To obtain the exact result, we must use rational numbers.

Java provides data types for integers and floating-point numbers, but not for rational numbers. This section shows how to design a class to represent rational numbers.

14.13 Case Study: The Rational Class 483

Since rational numbers share many common features with integers and floating-point numbers, and Number is the root class for numeric wrapper classes, it is appropriate to define Rational as a subclass of Number. Since rational numbers are comparable, the Rational class should also implement the Comparable interface. Figure 14.10 illustrates the Rational class and its relationship to the Number class and the Comparable interface.

1

java.lang.Comparable

1

Add, Subtract, Multiply, Divide

The numerator of this rational number.

The denominator of this rational number.

Creates a rational number with numerator 0 and denominator 1.

Creates a rational number with specified numerator and denominator.

Returns the numerator of this rational number.

Returns the denominator of this rational number.

Returns the addition of this rational with another.

Returns the subtraction of this rational with another.

Returns the multiplication of this rational with another.

Returns the division of this rational with another.

Returns a string in the form “numerator / denominator.” Returns numerator if denominator is 1.

Returns the greatest common divisor between n and d.

FIGURE 14.10 The properties, constructors, and methods of the Rational class are illustrated in UML.

A rational number consists of a numerator and a denominator. There are many equivalent rational numbers—for example, 1/3 = 2/6 = 3/9 = 4/12. The numerator and the denominator of 1/3 have no common divisor except 1, so 1/3 is said to be in lowest terms.

To reduce a rational number to its lowest terms, you need to find the greatest common divisor (GCD) of the absolute values of its numerator and denominator, then divide both numerator and denominator by this value. You can use the method for computing the GCD of two integers n and d, as suggested in Listing 4.8, GreatestCommonDivisor.java. The numerator and denominator in a Rational object are reduced to their lowest terms.

As usual, let us first write a test program to create two Rational objects and test its methods. Listing 14.12 is a test program.

LISTING 14.12 TestRationalClass.java

1 public class TestRationalClass {

2/** Main method */

3public static void main(String[] args) {

4 // Create and initialize two rational numbers r1 and r2. 5 Rational r1 = new Rational(4, 2);

6 Rational r2 = new Rational(2, 3); 7

create a Rational create a Rational

484 Chapter 14 Abstract Classes and Interfaces

 

8

// Display results

add

9

System.out.println(r1 + " + " + r2 + " = " +

r1.add(r2)

);

10System.out.println(r1 + " - " + r2 + " = " + r1.subtract(r2));

11System.out.println(r1 + " * " + r2 + " = " + r1.multiply(r2));

12System.out.println(r1 + " / " + r2 + " = " + r1.divide(r2));

13System.out.println(r2 + " is " + r2.doubleValue());

14}

15}

2 + 2/3 = 8/3

2 - 2/3 = 4/3

2 * 2/3 = 4/3

2 / 2/3 = 3

2/3 is 0.6666666666666666

The main method creates two rational numbers, r1 and r2 (lines 5–6), and displays the results of r1 + r2, r1 - r2, r1 x r2, and r1 / r2 (lines 9–12). To perform r1 + r2, invoke r1.add(r2) to return a new Rational object. Similarly, r1.subtract(r2) is for r1 - r2, r1.multiply(r2) for r1 x r2, and r1.divide(r2) for r1 / r2.

The doubleValue() method displays the double value of r2 (line 13). The doubleValue() method is defined in java.lang.Number and overridden in Rational.

Note that when a string is concatenated with an object using the plus sign (+), the object’s string representation from the toString() method is used to concatenate with the string. So r1 + " +

"+ r2 + " = " + r1.add(r2) is equivalent to r1.toString() + " + " + r2.toString() +

"= " + r1.add(r2).toString().

The Rational class is implemented in Listing 14.13.

LISTING 14.13 Rational.java

1 public class Rational extends Number implements Comparable {

2 // Data fields for numerator and denominator

3 private long numerator = 0;

4 private long denominator = 1;

5

6 /** Construct a rational with default properties */

7public Rational() {

8

this(0, 1);

9

}

10

11/** Construct a rational with specified numerator and denominator */

12public Rational(long numerator, long denominator) {

13long gcd = gcd(numerator, denominator);

14this.numerator = ((denominator > 0) ? 1 : -1) * numerator / gcd;

15this.denominator = Math.abs(denominator) / gcd;

16}

17

18/** Find GCD of two numbers */

19private static long gcd(long n, long d) {

20long n1 = Math.abs(n);

21long n2 = Math.abs(d);

22int gcd = 1;

23

24for (int k = 1; k <= n1 && k <= n2; k++) {

25if (n1 % k == 0 && n2 % k == 0)

26gcd = k;

27}

14.13 Case Study: The Rational Class 485

28

29return gcd;

30}

31

32/** Return numerator */

33public long getNumerator() {

34return numerator;

35}

36

37/** Return denominator */

38public long getDenominator() {

39return denominator;

40}

41

42/** Add a rational number to this rational */

43public Rational add(Rational secondRational) {

44long n = numerator * secondRational.getDenominator() +

45denominator * secondRational.getNumerator();

46long d = denominator * secondRational.getDenominator();

47return new Rational(n, d);

48}

49

50/** Subtract a rational number from this rational */

51public Rational subtract(Rational secondRational) {

52long n = numerator * secondRational.getDenominator()

53- denominator * secondRational.getNumerator();

54long d = denominator * secondRational.getDenominator();

55return new Rational(n, d);

56}

57

58/** Multiply a rational number to this rational */

59public Rational multiply(Rational secondRational) {

60long n = numerator * secondRational.getNumerator();

61long d = denominator * secondRational.getDenominator();

62return new Rational(n, d);

63}

64

65/** Divide a rational number from this rational */

66public Rational divide(Rational secondRational) {

67long n = numerator * secondRational.getDenominator();

68long d = denominator * secondRational.numerator;

69return new Rational(n, d);

70}

71

72/** Override the toString() method */

73public String toString() {

74if (denominator == 1)

75return numerator + "";

76else

77return numerator + "/" + denominator;

78}

79

80/** Override the equals method in the Object class */

81public boolean equals(Object parm1) {

82if ((this.subtract((Rational)(parm1))).getNumerator() == 0)

83return true;

84else

85return false;

86}

87

a b

a b

a b

a b

+

-

*

,

c d

c d

c d

c d

=

=

=

=

ad

ad

ac bd

ad bc

+

bd

-

bd

bc

bc

486 Chapter 14 Abstract Classes and Interfaces

88/** Implement the abstract intValue method in java.lang.Number */

89public int intValue() {

90return (int)doubleValue();

91}

92

93/** Implement the abstract floatValue method in java.lang.Number */

94public float floatValue() {

95return (float)doubleValue();

96}

97

98/** Implement the doubleValue method in java.lang.Number */

99public double doubleValue() {

100return numerator * 1.0 / denominator;

101}

102

103/** Implement the abstract longValue method in java.lang.Number */

104public long longValue() {

105return (long)doubleValue();

106}

107

108/** Implement the compareTo method in java.lang.Comparable */

109public int compareTo(Object o) {

110if ((this.subtract((Rational)o)).getNumerator() > 0)

111return 1;

112else if ((this.subtract((Rational)o)).getNumerator() < 0)

113return -1;

114else

115return 0;

116}

117}

The rational number is encapsulated in a Rational object. Internally, a rational number is represented in its lowest terms (line 13), and the numerator determines its sign (line 14). The denominator is always positive (line 15).

The gcd() method (lines 19–30 in the Rational class) is private; it is not intended for use by clients. The gcd() method is only for internal use by the Rational class. The gcd() method is also static, since it is not dependent on any particular Rational object.

The abs(x) method (lines 20–21 in the Rational class) is defined in the Math class that returns the absolute value of x.

Two Rational objects can interact with each other to perform add, subtract, multiply, and divide operations. These methods return a new Rational object (lines 43–70).

The methods toString and equals in the Object class are overridden in the Rational class (lines 73–91). The toString() method returns a string representation of a Rational object in the form numerator/denominator, or simply numerator if denominator is 1. The equals(Object other) method returns true if this rational number is equal to the other rational number.

The abstract methods intValue, longValue, floatValue, and doubleValue in the

Number class are implemented in the Rational class (lines 88–106). These methods return int, long, float, and double value for this rational number.

The compareTo(Object other) method in the Comparable interface is implemented in the Rational class (lines 109–116) to compare this rational number to the other rational number.

Tip

The get methods for the properties numerator and denominator are provided in the

Rational class, but the set methods are not provided, so, once a Rational object is created,

Chapter Summary 487

its contents cannot be changed. The Rational class is immutable. The String class and the

immutable

wrapper classes for primitive type values are also immutable.

 

Tip

The numerator and denominator are represented using two variables. It is possible to use an array of two integers to represent the numerator and denominator. See Exercise 14.18. The signatures of the public methods in the Rational class are not changed, although the internal representation of a rational number is changed. This is a good example to illustrate the idea that the data

fields of a class should be kept private so as to encapsulate the implementation of the class from encapsulation the use of the class.

The Rational class has serious limitations. It can easily overflow. For example, the fol- overflow lowing code will display an incorrect result, because the denominator is too large.

public class Test {

public static void main(String[] args) { Rational r1 = new Rational(1, 123456789); Rational r2 = new Rational(1, 123456789); Rational r3 = new Rational(1, 123456789); System.out.println("r1 * r2 * r3 is " +

r1.multiply(r2.multiply(r3)));

}

}

r1 * r2 * r3 is -1/2204193661661244627

To fix it, you may implement the Rational class using the BigInteger for numerator and denominator (see Exercise 14.19).

KEY TERMS

abstract class 458

multiple inheritance

469

abstract method

458

subinterface

474

 

deep copy

473

 

shallow copy

473

 

interface

465

 

single inheritance

473

marker interface

471

wrapper class

476

 

CHAPTER SUMMARY

1.Abstract classes are like regular classes with data and methods, but you cannot create instances of abstract classes using the new operator.

2.An abstract method cannot be contained in a nonabstract class. If a subclass of an abstract superclass does not implement all the inherited abstract methods of the superclass, the subclass must be defined abstract.

3.A class that contains abstract methods must be abstract. However, it is possible to define an abstract class that contains no abstract methods.

4.A subclass can be abstract even if its superclass is concrete.

5.An interface is a classlike construct that contains only constants and abstract methods. In many ways, an interface is similar to an abstract class, but an abstract class can contain constants and abstract methods as well as variables and concrete methods.

488Chapter 14 Abstract Classes and Interfaces

6.An interface is treated like a special class in Java. Each interface is compiled into a separate bytecode file, just like a regular class.

7.The java.lang.Comparable interface defines the compareTo method. Many classes in the Java library implement Comparable.

8.The java.lang.Cloneable interface is a marker interface. An object of the class that implements the Cloneable interface is cloneable.

9.A class can extend only one superclass but can implement one or more interfaces.

10.An interface can extend one or more interfaces.

11.Many Java methods require the use of objects as arguments. 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.

12.Java can automatically convert a primitive type value to its corresponding wrapper object in the context and vice versa.

13.The BigInteger class is useful to compute and process integers of any size. The BigDecimal class can be used to compute and process floating-point numbers with any arbitrary precision.

REVIEW QUESTIONS

Section 14.2

14.1Which of the following classes definitions defines a legal abstract class?

class A {

abstract void unfinished() {

}

}

(a)

class A {

abstract void unfinished();

}

(c)

abstract class A {

abstract void unfinished();

}

(e)

public class abstract A { abstract void unfinished();

}

(b)

abstract class A {

protected void unfinished();

}

(d)

abstract class A {

abstract int unfinished();

}

(f)

14.2The getArea and getPerimeter methods may be removed from the GeometricObject class. What are the benefits of defining getArea and getPerimeter as abstract methods in the GeometricObject class?

14.3True or false? An abstract class can be used just like a nonabstract class except that you cannot use the new operator to create an instance from the abstract class.

Review Questions 489

Sections 14.4–14.6

14.4Which of the following is a correct interface?

interface A {

void print() { };

}

(a)

abstract interface A { print();

}

(c)

abstract interface A extends I1, I2 { abstract void print() { };

}

(b)

interface A { void print();

}

(d)

14.5True or false? If a class implements Comparable, the object of the class can invoke the compareTo method.

14.6Two max methods are defined in §14.5. Explain why the max with the signature max(Comparable, Comparable) is better than the one with the signature max(Object, Object).

14.7You can define the compareTo method in a class without implementing the Comparable interface. What are the benefits of implementing the Comparable interface?

14.8True or false? If a class implements java.awt.event.ActionListener, the object of the class can invoke the actionPerformed method.

Sections 14.7–14.8

14.9Can you invoke the clone() method to clone an object if the class for the object does not implement the java.lang.Cloneable? Does the Date class implement Cloneable?

14.10What would happen if the House class (defined in Listing 14.9) did not override the clone() method or if House did not implement java.lang.Cloneable?

14.11Show the printout of the following code:

java.util.Date date = new java.util.Date(); java.util.Date date1 = date;

java.util.Date date2 = (java.util.Date)(date.clone()); System.out.println(date == date1); System.out.println(date == date2); System.out.println(date.equals(date2));

14.12 Show the printout of the following code:

java.util.ArrayList list = new java.util.ArrayList(); list.add("New York");

java.util.ArrayList list1 = list;

java.util.ArrayList list2 = (java.util.ArrayList)(list.clone()); list.add("Atlanta");

System.out.println(list == list1); System.out.println(list == list2); System.out.println("list is " + list); System.out.println("list1 is " + list1); System.out.println("list2.get(0) is " + list2.get(0)); System.out.println("list2.size() is " + list2.size());

490Chapter 14 Abstract Classes and Interfaces

14.13What is wrong in the following code?

public class Test {

public static void main(String[] args) { GeometricObject x = new Circle(3); GeometricObject y = x.clone(); System.out.println(x == y);

}

}

14.14 Give an example to show why interfaces are preferred over abstract classes.

Section 14.9

14.15Describe primitive-type wrapper classes. Why do you need these wrapper classes?

14.16Can each of the following statements be compiled?

Integer i = new Integer("23"); Integer i = new Integer(23); Integer i = Integer.valueOf("23");

Integer i = Integer.parseInt("23", 8); Double d = new Double();

Double d = Double.valueOf("23.45");

int i = (Integer.valueOf("23")).intValue(); double d = (Double.valueOf("23.4")).doubleValue(); int i = (Double.valueOf("23.4")).intValue(); String s = (Double.valueOf("23.4")).toString();

14.17How do you convert an integer into a string? How do you convert a numeric string into an integer? How do you convert a double number into a string? How do you convert a numeric string into a double value?

14.18Why do the following two lines of code compile but cause a runtime error?

Number numberRef = new Integer(0);

Double doubleRef = (Double)numberRef;

14.19 Why do the following two lines of code compile but cause a runtime error?

Number[] numberArray = new Integer[2]; numberArray[0] = new Double(1.5);

14.20 What is wrong in the following code?

public class Test {

public static void main(String[] args) { Number x = new Integer(3); System.out.println(x.intValue());

System.out.println(x.compareTo(new Integer(4)));

}

}

14.21 What is wrong in the following code?

public class Test {

public static void main(String[] args) { Number x = new Integer(3); System.out.println(x.intValue());

System.out.println((Integer)x.compareTo(new Integer(4)));

}

}

Review Questions 491

14.22 What is the output of the following code?

public class Test {

public static void main(String[] args) { System.out.println(Integer.parseInt("10")); System.out.println(Integer.parseInt("10", 10)); System.out.println(Integer.parseInt("10", 16)); System.out.println(Integer.parseInt("11")); System.out.println(Integer.parseInt("11", 10)); System.out.println(Integer.parseInt("11", 16));

}

}

Sections 14.10–14.12

14.23 What are autoboxing and autounboxing? Are the following statements correct?

Number x = 3;

Integer x = 3;

Double x = 3;

Double x = 3.0;

int x = new Integer(3);

int x = new Integer(3) + new Integer(4); double y = 3.4;

y.intValue();

JOptionPane.showMessageDialog(null, 45.5);

14.24Can you assign new int[10], new String[100], new Object[50], or new Calendar[20] into a variable of Object[] type?

14.25What is the output of the following code?

public class Test {

public static void main(String[] args) { java.math.BigInteger x = new java.math.BigInteger("3"); java.math.BigInteger y = new java.math.BigInteger("7"); x.add(y);

System.out.println(x);

}

}

Comprehensive

14.26Define the following terms: abstract classes, interfaces. What are the similarities and differences between abstract classes and interfaces?

14.27Indicate true or false for the following statements:

An abstract class can have instances created using the constructor of the abstract class.

An abstract class can be extended.

An interface is compiled into a separate bytecode file.

A subclass of a nonabstract superclass cannot be abstract.

A subclass cannot override a concrete method in a superclass to define it abstract.

An abstract method must be nonstatic

An interface can have static methods.

An interface can extend one or more interfaces.

492Chapter 14 Abstract Classes and Interfaces

An interface can extend an abstract class.

An abstract class can extend an interface.

Video Note

Redesign the Rectangle class

PROGRAMMING EXERCISES

Sections 14.1–14.7

14.1* (Enabling GeometricObject comparable) Modify the GeometricObject class to implement the Comparable interface, and define a static max method in the GeometricObject class for finding the larger of two GeometricObject objects. Draw the UML diagram and implement the new GeometricObject class. Write a test program that uses the max method to find the larger of two circles and the larger of two rectangles.

14.2* (The ComparableCircle class) Create a class named ComparableCircle that extends Circle and implements Comparable. Draw the UML diagram and implement the compareTo method to compare the circles on the basis of area. Write a test class to find the larger of two instances of ComparableCircle objects.

14.3* (The Colorable interface) Design an interface named Colorable with a void method named howToColor(). Every class of a colorable object must implement the Colorable interface. Design a class named Square that extends

GeometricObject and implements Colorable. Implement howToColor to display a message "Color all four sides".

Draw a UML diagram that involves Colorable, Square, and GeometricObject. Write a test program that creates an array of five GeometricObjects. For each object in the array, invoke its howToColor method if it is colorable.

14.4* (Revising the House class) Rewrite the House class in Listing 14.9 to perform a deep copy on the whenBuilt field.

14.5* (Enabling Circle comparable) Rewrite the Circle class in Listing 14.2 to extend GeometricObject and implement the Comparable interface. Override the equals method in the Object class. Two Circle objects are equal if their radii are the same. Draw the UML diagram that involves Circle, GeometricObject, and Comparable.

14.6* (Enabling Rectangle comparable) Rewrite the Rectangle class in Listing 14.3 to extend GeometricObject and implement the Comparable interface. Override the equals method in the Object class. Two Rectangle objects are equal if their areas are the same. Draw the UML diagram that involves Rectangle,

GeometricObject, and Comparable.

14.7* (The Octagon class) Write a class named Octagon that extends GeometricObject and implements the Comparable and Cloneable2 interfaces. Assume that all eight sides of the octagon are of equal size. The area can be computed using the following formula:

area = A2 + 4/ 2B*side*side

Draw the UML diagram that involves Octagon, GeometricObject, Comparable, and Cloneable. Write a test program that creates an Octagon object with side value 5 and displays its area and perimeter. Create a new object using the clone method and compare the two objects using the compareTo method.

Programming Exercises 493

14.8* (Summing the areas of geometric objects) Write a method that sums the areas of all the geometric objects in an array. The method signature is:

public static double sumArea(GeometricObject[] a)

Write a test program that creates an array of four objects (two circles and two rectangles) and computes their total area using the sumArea method.

14.9* (Finding the largest object) Write a method that returns the largest object in an array of objects. The method signature is:

public static Object max(Comparable[] a)

All the objects are instances of the Comparable interface. The order of the objects in the array is determined using the compareTo method.

Write a test program that creates an array of ten strings, an array of ten integers, and an array of ten dates, and finds the largest string, integer, and date in the arrays.

14.10** (Displaying calendars) Rewrite the PrintCalendar class in Listing 5.12 to display a calendar for a specified month using the Calendar and GregorianCalendar classes. Your program receives the month and year from the command line. For example:

java Exercise14_10 1 2010

This displays the calendar shown in Figure 14.11.

You also can run the program without the year. In this case, the year is the current year. If you run the program without specifying a month and a year, the month is the current month.

FIGURE 14.11 The program displays a calendar for January 2010.

Section 14.12

14.11** (Divisible by 5 or 6) Find the first ten numbers (greater than Long.MAX_VALUE) that are divisible by 5 or 6.

14.12** (Divisible by 2 or 3) Find the first ten numbers with 50 decimal digits that are divisible by 2 or 3.

14.13** (Square numbers) Find the first ten square numbers that are greater than Long.MAX_VALUE. A square number is a number in the form of n2 .

14.14** (Large prime numbers) Write a program that finds five prime numbers larger than Long.MAX_VALUE.

494 Chapter 14 Abstract Classes and Interfaces

14.15** (Mersenne prime) A prime number is called a Mersenne prime if it can be written in the form 2p - 1 for some positive integer p. Write a program that finds all Mersenne primes with p … 100 and displays the output as shown below. (You have to use BigInteger to store the number, because it is too big to be stored in long. Your program may take several hours to complete.)

p2^p - 1

23

37

5 31

...

Section 14.13

14.16** (Approximating e) Exercise 4.26 approximates e using the following series:

e = 1 + 1 + 1 + 1 + 1 + Á + 1 1! 2! 3! 4! i!

In order to get better precision, use BigDecimal with 25 digits of precision in the computation. Write a program that displays the e value for i = 100, 200,

Á, and 1000.

14.17(Using the Rational class) Write a program that will compute the following summation series using the Rational class:

1

+ 2 + 3 + Á + 98 + 99

2

3

4

99

100

You will discover that output is incorrect because of integer overflow (too large). To fix this problem, see Exercise 14.19.

14.18* (Demonstrating the benefits of encapsulation) Rewrite the Rational class in §14.13 using a new internal representation for numerator and denominator. Create an array of two integers as follows:

private long[] r = new long[2];

Use r[0] to represent the numerator and r[1] to represent the denominator. The signatures of the methods in the Rational class are not changed, so a client application that uses the previous Rational class can continue to use this new Rational class without being recompiled.

14.19** (Using BigInteger for the Rational class) Redesign and implement the Rational class in §14.13 using BigInteger for numerator and denominator.

14.20* (Creating a rational-number calculator) Write a program similar to Listing 9.5, Calculator.java. Instead of using integers, use rationals, as shown in Figure 14.12.

FIGURE 14.12 The program takes three arguments (operand1, operator, and operand2) from the command line and displays the expression and the result of the arithmetic operation.

Programming Exercises 495

You will need to use the split method in the String class, introduced in §9.2.6, “Converting, Replacing, and Splitting Strings,” to retrieve the numerator string and denominator string, and convert2 strings into integers using the

Integer.parseInt method.

14.21* (Math: The Complex class) A complex number is a number of the form a + bi, where a and b are real numbers and i is - 1. The numbers a and b are known as the real part and imaginary part of the complex number, respectively. You can perform addition, subtraction, multiplication, and division for complex numbers using the following formula:

a + bi + c + di = 1a + c2 + 1b + d2i a + bi - 1c + di2 = 1a - c2 + 1b - d2i

1a + bi2*1c + di2 = 1ac - bd2 + 1bc + ad2i

1a + bi2/1c + di2 = 1ac + bd2/1c2 + d22 + 1bc - ad2i/1c2 + d22

You can also obtain the absolute value2for a complex number using the following formula:

|a + bi| = a2 + b2

Design a class named Complex for representing complex numbers and the methods add, subtract, multiply, divide, and abs for performing com- plex-number operations, and override the toString method for returning a string representation for a complex number. The toString method returns a + bi as a string. If b is 0, it simply returns a.

Provide three constructors Complex(a, b), Complex(a), and Complex().

Complex() creates a Complex object for number 0 and Complex(a) creates a Complex object with 0 for b. Also provide the getRealPart() and getImaginaryPart() methods for returning the real and imaginary part of the complex number, respectively.

Write a test program that prompts the user to enter two complex numbers and display the result of their addition, subtraction, multiplication, and division. Here is a sample run:

Enter the first complex number: 3.5 5.5 Enter the second complex number: -3.5 1 3.5 + 5.5i + -3.5 + 1.0i = 0.0 + 6.5i

3.5 + 5.5i - -3.5 + 1.0i = 7.0 + 4.5i

3.5 + 5.5i * -3.5 + 1.0i = -17.75 + -15.75i 3.5 + 5.5i / -3.5 + 1.0i = -0.5094 + -1.7i |3.5 + 5.5i| = 6.519202405202649

This page intentionally left blank

CHAPTER 15

GRAPHICS

Objectives

To describe Java coordinate systems in a GUI component (§15.2).

To draw things using the methods in the Graphics class (§15.3).

To override the paintComponent method to draw things on a GUI component (§15.3).

To use a panel as a canvas to draw things (§15.3).

To draw strings, lines, rectangles, ovals, arcs, and polygons (§§15.4, 15.6–15.7).

To obtain font properties using FontMetrics and know how to center a message (§15.8).

To display an image in a GUI component (§15.11).

To develop reusable GUI components FigurePanel,

MessagePanel, StillClock, and ImageViewer

(§§15.5, 15.9, 15.10, 15.12).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]