Chapter 4. Fundamental Data Types

CHAPTER GOALS

  • To understand integer and floating-point numbers

  • To recognize the limitations of the numeric types

  • To become aware of causes for overflow and roundoff errors

  • To understand the proper use of constants

  • To write arithmetic expressions in Java

  • To use the String type to manipulate character strings

  • To learn how to read program input and produce formatted output

This chapter teaches how to manipulate numbers and character strings in Java. The goal of this chapter is to gain a firm understanding of these fundamental data types in Java.

You will learn about the properties and limitations of the number types in Java. You will see how to manipulate numbers and strings in your programs. Finally, we cover the important topic of input and output, which enables you to implement interactive programs.

Number Types

In Java, every value is either a reference to an object, or it belongs to one of the eight primitive types shown in Table 1.

Six of the primitive types are number types; four of them for integers and two for floating-point numbers.

Note

Java has eight primitive types, including four integer types and two floating-point types.

Each of the integer types has a different range—Special Topic 4.2 on page 130 explains why the range limits are related to powers of two. The largest number that can be represented in an int is denoted by Integer.MAX_VALUE. Its value is about 2.14 billion. Similarly, Integer.MIN_VALUE is the smallest integer, about −2.14 billion.

Generally, you will use the int type for integer quantities. However, occasionally, calculations involving integers can overflow. This happens if the result of a computation exceeds the range for the number type. For example:

int n = 1000000;
System.out.println(n * n);  // Prints −727379968, which is clearly wrong

Note

A numeric computation overflows if the result falls outside the range for the number type.

The product n * n is 1012, which is larger than the largest integer (about 2 · 109). The result is truncated to fit into an int, yielding a value that is completely wrong. Unfortunately, there is no warning when an integer overflow occurs.

If you run into this problem, the simplest remedy is to use the long type. Special Topic 4.1 on page 130 shows you how to use the BigInteger type in the unlikely event that even the long type overflows.

Overflow is not usually a problem for double-precision floating-point numbers. The double type has a range of about ±10308 and about 15 significant digits. However, you want to avoid the float type—it has less than 7 significant digits. (Some programmers use float to save on memory if they need to store a huge set of numbers that do not require much precision.)

Table 4.1. Primitive Types

Type

Description

Size

int

The integer type, with range −2,147,483,648 (Integer.MIN_VALUE) . . . 2,147,483,647 (Integer.MAX_VALUE, about 2.14 billion)

4 bytes

byte

The type describing a single byte, with range −128 . . . 127 1 byte

1 byte

short

The short integer type, with range −32,768 . . . 32,767

2 bytes

long

The long integer type, with range −9,223,372,036,854,775,808 . . . 9,223,372,036,854,775,807

8 bytes

double

The double-precision floating-point type, with a range of about ±10308 and about 15 significant decimal digits

8 bytes

float

The single-precision floating-point type, with a range of about ±1038 and about 7 significant decimal digits

4 bytes

char

The character type, representing code units in the Unicode encoding scheme (see Special Topic 4.5 on page 153)

2 bytes

boolean

The type with the two truth values false and true (see Chapter 5)

1 bit

Rounding errors are a more serious issue with floating-point values. Rounding errors can occur when you convert between binary and decimal numbers, or between integers and floating-point numbers. When a value cannot be converted exactly, it is rounded to the nearest match. Consider this example:

double f = 4.35;
System.out.println(100 * f); // Prints 434.99999999999994

Note

Rounding errors occur when an exact conversion between numbers is not possible.

This problem is caused because computers represent numbers in the binary number system. In the binary number system, there is no exact representation of the fraction 1/10, just as there is no exact representation of the fraction 1/3 = 0.33333 in the decimal number system. (See Special Topic 4.2 on page 130 for more information.)

For this reason, the double type is not appropriate for financial calculations. In this book, we will continue to use double values for bank balances and other financial quantities so that we keep our programs as simple as possible. However, professional programs need to use the BigDecimal type for this purpose—see Special Topic 4.1 on page 130.

In Java, it is legal to assign an integer value to a floating-point variable:

int dollars = 100;
double balance = dollars; // OK

But the opposite assignment is an error: You cannot assign a floating-point expression to an integer variable.

double balance = 13.75;
int dollars = balance; // Error

You will see in Section 4.3.5 how to convert a value of type double into an integer.

Primitive Types

2. Suppose you want to write a program that works with population data from various countries. Which Java data type should you use?

3. Which of the following initializations are incorrect, and why?

  1. int dollars = 100.0;

  2. double balance = 100;

Constants

In many programs, you need to use numerical constants—values that do not change and that have a special significance for a computation.

A typical example for the use of constants is a computation that involves coin values, such as the following:

payment = dollars + quarters * 0.25 + dimes * 0.1
      + nickels * 0.05 + pennies * 0.01;

Most of the code is self-documenting. However, the four numeric quantities, 0.25, 0.1, 0.05, and 0.01 are included in the arithmetic expression without any explanation. Of course, in this case, you know that the value of a nickel is five cents, which explains the 0.05, and so on. However, the next person who needs to maintain this code may live in another country and may not know that a nickel is worth five cents.

Thus, it is a good idea to use symbolic names for all values, even those that appear obvious. Here is a clearer version of the computation of the total:

double quarterValue = 0.25;
double dimeValue = 0.1;
double nickelValue = 0.05;
double pennyValue = 0.01;
payment = dollars + quarters * quarterValue + dimes * dimeValue
      + nickels * nickelValue + pennies * pennyValue;

There is another improvement we can make. There is a difference between the nickels and nickelValue variables. The nickels variable can truly vary over the life of the program, as we calculate different payments. But nickelValue is always 0.05.

In Java, constants are identified with the reserved word final. A variable tagged as final can never change after it has been set. If you try to change the value of a final variable, the compiler will report an error and your program will not compile.

Note

A final variable is a constant. Once its value has been set, it cannot be changed.

Many programmers use all-uppercase names for constants (final variables), such as NICKEL_VALUE. That way, it is easy to distinguish between variables (with mostly lowercase letters) and constants. We will follow this convention in this book. However, this rule is a matter of good style, not a requirement of the Java language. The compiler will not complain if you give a final variable a name with lowercase letters.

Here is an improved version of the code that computes the value of a payment.

final double QUARTER_VALUE = 0.25;
final double DIME_VALUE = 0.1;
final double NICKEL_VALUE = 0.05;
final double PENNY_VALUE = 0.01;
payment = dollars + quarters * QUARTER_VALUE + dimes * DIME_VALUE
      + nickels * NICKEL_VALUE + pennies * PENNY_VALUE;

Note

Use named constants to make your programs easier to read and maintain.

Frequently, constant values are needed in several methods. Then you should declare them together with the instance variables of a class and tag them as static and final. As before, final indicates that the value is a constant. The static reserved word means that the constant belongs to the class—this is explained in greater detail in Chapter 8.)

public class CashRegister
{
   // Constants
   public static final double QUARTER_VALUE = 0.25;
   public static final double DIME_VALUE = 0.1;
   public static final double NICKEL_VALUE = 0.05;
   public static final double PENNY_VALUE = 0.01;

   // Instance variables
   private double purchase;
   private double payment;

   // Methods
   ...
}

We declared the constants as public. There is no danger in doing this because constants cannot be modified. Methods of other classes can access a public constant by first specifying the name of the class in which it is declared, then a period, then the name of the constant, such as CashRegister.NICKEL_VALUE.

The Math class from the standard library declares a couple of useful constants:

public class Math
{
   ...
   public static final double E = 2.7182818284590452354;
   public static final double PI = 3.14159265358979323846;
}

You can refer to these constants as Math.PI and Math.E in any of your methods. For example,

double circumference = Math.PI * diameter;

The sample program at the end of this section puts constants to work. The program shows a refinement of the CashRegister class of How To 3.1. The public interface of that class has been modified in order to solve a common business problem.

Busy cashiers sometimes make mistakes totaling up coin values. Our Cash-Register class features a method whose inputs are the coin counts. For example, the call

register.enterPayment(1, 2, 1, 1, 4);

enters a payment consisting of one dollar, two quarters, one dime, one nickel, and four pennies. The enterPayment method figures out the total value of the payment, $1.69. As you can see from the code listing, the method uses named constants for the coin values.

ch04/cashregister/CashRegister.java

1  /**
2     A cash register totals up sales and computes change due.
3  */
4  public class CashRegister
5  {
6     public static final double QUARTER_VALUE = 0.25;
7     public static final double DIME_VALUE = 0.1;
8     public static final double NICKEL_VALUE = 0.05;
9     public static final double PENNY_VALUE = 0.01;
10
11     private double purchase;
12     private double payment;
13
14      /**
15        Constructs a cash register with no money in it.
16      */
17     public CashRegister()
18     {
19        purchase = 0;
20        payment = 0;
21     }
22
23     /**
24        Records the purchase price of an item.
25        @param amount the price of the purchased item
26     */
27     public void recordPurchase(double amount)
28     {
29        purchase = purchase + amount;
30       }
31
32       /**
33          Enters the payment received from the customer.
34          @param dollars the number of dollars in the payment
35          @param quarters the number of quarters in the payment
36          @param dimes the number of dimes in the payment
37          @param nickels the number of nickels in the payment
38          @param pennies the number of pennies in the payment
39       */
40       public void enterPayment(int dollars, int quarters,
41             int dimes, int nickels, int pennies)
42       {
43          payment = dollars + quarters * QUARTER_VALUE + dimes * DIME_VALUE
44                + nickels * NICKEL_VALUE + pennies * PENNY_VALUE;
45       }
46
47       /**
48          Computes the change due and resets the machine for the next customer.
49          @return the change due to the customer
50       */
51       public double giveChange()
52       {
53          double change = payment - purchase;
54          purchase = 0;
55          payment = 0;
56          return change;
57       }
58    }

ch04/cashregister/CashRegisterTester.java

1  /**
2     This class tests the CashRegister class.
3  */
4  public class CashRegisterTester
5  {
6     public static void main(String[] args)
7     {
8         CashRegister register = new CashRegister();
9
10         register.recordPurchase(0.75);
11         register.recordPurchase(1.50);
12         register.enterPayment(2, 0, 5, 0, 0);
13         System.out.print("Change: ");
14         System.out.println(register.giveChange());
15         System.out.println("Expected: 0.25");
16
17         register.recordPurchase(2.25);
18         register.recordPurchase(19.25);
19         register.enterPayment(23, 2, 0, 0, 0);
20         System.out.print("Change: ");
21         System.out.println(register.giveChange());
22         System.out.println("Expected: 2.0");
23      }
24  }

Program Run

Change: 0.25
Expected: 0.25
Change: 2.0
Expected: 2.0
Constant Declaration
final double CM_PER_INCH = 2.54;
and
public static final double CM_PER_INCH = 2.54;

5. What is wrong with the following statement sequence?

double diameter = ...;
double circumference = 3.14 * diameter;

Arithmetic Operations and Mathematical Functions

In the following sections, you will learn how to carry out arithmetic calculations in Java.

Arithmetic Operators

Java supports the same four basic arithmetic operations as a calculator—addition, subtraction, multiplication, and division. As you have already seen, addition and subtraction use the familiar + and - operators, and the * operator denotes multiplication. Division is indicated with a /, not a fraction bar. For example,

Arithmetic Operators

becomes

(a + b) / 2

Parentheses are used just as in algebra: to indicate in which order the subexpressions should be computed. For example, in the expression (a + b) / 2, the sum a + b is computed first, and then the sum is divided by 2. In contrast, in the expression

a + b / 2

only b is divided by 2, and then the sum of a and b / 2 is formed. Just as in regular algebraic notation, multiplication and division bind more strongly than addition and subtraction. For example, in the expression a + b / 2, the / is carried out first, even though the + operation occurs farther to the left.

Increment and Decrement

Incrementing a value by 1 is so common when writing programs that there is a special shorthand for it, namely

items++;

This statement adds 1 to items. It is easier to type and read than the equivalent assignment statement

items = items + 1;

As you might have guessed, there is also a decrement operator --. The statement

items--;

subtracts 1 from items.

Note

The ++ and -- operators increment and decrement a variable.

Incrementing a Variable

Figure 4.1. Incrementing a Variable

Integer Division

Division works as you would expect, as long as at least one of the numbers involved is a floating-point number. That is,

7.0 / 4.0
7 / 4.0
7.0 / 4

all yield 1.75. However, if both numbers are integers, then the result of the division is always an integer, with the remainder discarded. That is,

7 / 4

evaluates to 1, because 7 divided by 4 is 1 with a remainder of 3 (which is discarded). Discarding the remainder is often useful, but it can also be a source of subtle programming errors—see Common Error 4.1 on page 142.

Note

If both arguments of the / operator are integers, the result is an integer and the remainder is discarded.

If you are interested only in the remainder of an integer division, use the % operator:

7 % 4

is 3, the remainder of the integer division of 7 by 4. The % symbol has no analog in algebra. It was chosen because it looks similar to /, and the remainder operation is related to division.

Note

The % operator computes the remainder of a division.

Here is a typical use for the integer / and % operations. Suppose you want to know how much change a cash register should give, using separate values for dollars and cents. You can compute the value as an integer, denominated in cents, and then compute the whole dollar amount and the remaining change:

final int PENNIES_PER_NICKEL = 5;
final int PENNIES_PER_DIME = 10;
final int PENNIES_PER_QUARTER = 25;
final int PENNIES_PER_DOLLAR = 100;

// Compute total value in pennies
int total = dollars * PENNIES_PER_DOLLAR + quarters * PENNIES_PER_QUARTER
      + nickels * PENNIES_PER_NICKEL + dimes * PENNIES_PER_DIME + pennies;

// Use integer division to convert to dollars, cents
int dollars = total / PENNIES_PER_DOLLAR;
int cents = total % PENNIES_PER_DOLLAR;

For example, if total is 243, then dollars is set to 2 and cents to 43.

Powers and Roots

To compute xn, you write Math.pow(x, n). However, to compute x2 it is significantly more efficient simply to compute x * x.

To take the square root of a number, you use the Math.sqrt method. For example, √x is written as Math.sqrt(x).

In algebra, you use fractions, superscripts for exponents, and radical signs for roots to arrange expressions in a compact two-dimensional form. In Java, you have to write all expressions in a linear arrangement.

Note

The Math class contains methods sqrt and pow to compute square roots and powers.

Analyzing an Expression

Figure 4.2. Analyzing an Expression

For example, the subexpression

Analyzing an Expression

of the quadratic formula becomes

(-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a)

Figure 2 shows how to analyze such an expression. With complicated expressions like these, it is not always easy to keep the parentheses ( ) matched—see Common Error 4.2 on page 143.

Table 2 shows additional methods of the Math class. Inputs and outputs are floating-point numbers.

Casting and Rounding

Occasionally, you have a value of type double that you need to convert to the type int. Use the cast operator (int) for this purpose. You write the cast operator before the expression that you want to convert:

double balance = total + tax;
int dollars = (int) balance;

Table 4.2. Mathematical Methods

Function

Returns

Math.sqrt(x)

Square root of x (≥0)

Math.pow(x, y)

xy (x>0, or x = 0 and y>0, or x<0 and y is an integer)

Math.sin(x)

Sine of x (x in radians)

Math.cos(x)

Cosine of x

Math.tan(x)

Tangent of x

Math.asin(x)

Arc sine (sin−1x∈[−π/2, π/2], x∈[−1, 1])

Math.acos(x)

Arc cosine (cos−1x∈[0, π], x∈[−1, 1])

Math.atan(x)

Arc tangent (tan−1x∈[−π/2, π/2])

Math.atan2(y, x)

Arc tangent (tan−1yx∈[−π, π]), x may be 0

Math.toRadians(x)

Convert x degrees to radians (i.e., returns x · π/180)

Math.toDegrees(x)

Convert x radians to degrees (i.e., returns x · 180/π)

Math.exp(x)

ex

Math.log(x)

Natural log (ln(x), x > 0)

Math.log10(x)

Decimal log (log10(x), x > 0)

Math.round(x)

Closest integer to x (as a long)

Math.ceil(x)

Smallest integer >x (as a double)

Math.floor(x)

Largest integer ≤x (as a double)

Math.abs(x)

Absolute value |x|

Math.max(x, y)

The larger of x and y

Math.min(x, y)

The smaller of x and y

The cast (int) converts the floating-point value balance to an integer by discarding the fractional part. For example, if balance is 13.75, then dollars is set to 13.

Note

You use a cast (typeName) to convert a value to a different type.

The cast tells the compiler that you agree to information loss, in this case, to the loss of the fractional part. You can also cast to other types, such as (float) or (byte).

If you want to round a floating-point number to the nearest whole number, use the Math.round method. This method returns a long integer, because large floating-point numbers cannot be stored in an int.

long rounded = Math.round(balance);

If balance is 13.75, then rounded is set to 14.

Note

Use the Math.round method to round a floating-point number to the nearest integer.

Table 4.3. Arithmetic Expressions

Mathematical Expression

Java Expression

Comments

Arithmetic Expressions

(x + y) / 2

The parentheses are required;

x + y / 2 computes x + y/2.

Arithmetic Expressions

x * y / 2

Parentheses are not required; operators with the same precedence are evaluated left to right.

Arithmetic Expressions

Math.pow(1 + r / 100, n)

Complex formulas are "flattened" in Java.

Arithmetic Expressions

Math.sqrt(a * a + b * b)

a * a is simpler than Math.pow(a, 2).

Arithmetic Expressions

(i + j + k) / 3.0

If i, j, and k are integers, using a denominator of 3.0 forces floating-point division.

Arithmetic Expressions
n--;
n++;
n--;

7. What is the value of 1729 / 100? Of 1729 % 100?

8. Why doesn't the following statement compute the average of s1, s2, and s3?

double average = s1 + s2 + s3 / 3; // Error

9. What is the value of Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) in mathematical notation?

10. When does the cast (long) x yield a different result from the call Math.round(x)?

11. How do you round the double value x to the nearest int value, assuming that you know that it is less than 2 · 109?

Calling Static Methods

In the preceding section, you encountered the Math class, which contains a collection of helpful methods for carrying out mathematical computations. These methods have a special form: they are static methods that do not operate on an object.

That is, you don't call

double root = 100.sqrt(); // Error

In Java, numbers are not objects, so you can never invoke a method on a number. Instead, you pass a number as an explicit parameter to a method, enclosing the number in parentheses after the method name:

double root = Math.sqrt(100);

This call makes it appear as if the sqrt method is applied to an object called Math. However, Math is a class, not an object. A method such as Math.sqrt that does not operate on any object is called a static method. (The term "static" is a historical holdover from the C and C++ programming languages. It has nothing to do with the usual meaning of the word.) In contrast, a method that is invoked on an object is class, is called an instance method:

harrysChecking.deposit(100); // deposit is an instance method

Note

A static method does not operate on an object.

Static methods do not operate on objects, but they are still declared inside classes. When calling the method, you specify the class to which the sqrt method belongs—hence the call is Math.sqrt(100).

How can you tell that Math is a class and not an object? By convention, class names start with an uppercase letter (such as Math or BankAccount). Objects and methods start with a lowercase letter (such as harrysChecking and println). Therefore, harrysChecking.deposit(100) denotes a call of the deposit method on the harrysChecking object inside the System class. On the other hand, Math.sqrt(100) denotes a call to the sqrt method inside the Math class.

This use of upper- and lowercase letters is merely a convention, not a rule of the Java language. It is, however, a convention that the authors of the Java class libraries follow consistently. You should do the same in your programs so that you don't confuse your fellow programmers.

Static Method Call

13. Is the call System.out.println(4) a static method call?

Strings

Many programs process text that consists of characters: letters, numbers, punctuation, spaces, and so on. A string is a sequence of characters, such as "Hello, World!". In the following sections, you will learn how to work with strings in Java.

The String Class

In Java, strings are objects that belong to the class String. (You can tell that String is a class name because it starts with an uppercase letter. The primitive types int and double start with lowercase letters.)

Note

A string is a sequence of characters. Strings are objects of the String class.

You do not need to call a constructor to create a string object. You can obtain a string literal simply by enclosing a sequence of characters in double quotation marks. For example, the string literal "Harry" is an object of the String class.

The number of characters in a string is called the length of the string. As you have seen in Chapter 2, you can use the length method to obtain the length of a string. For example, "Hello".length() is 5, and the length of "Hello, World!" is 13. (The quotation marks are not part of the string and do not contribute to the length, but you must count spaces and punctuation marks.)

A string of length zero, containing no characters, is called the empty string and is written as "".

Concatenation

You can use the + operator to put strings together to form a longer string.

String name = "Dave";
String message = "Hello, " + name;

This process is called concatenation.

The + operator concatenates two strings, provided one of the expressions, either to the left or the right of a + operator, is a string. The other one is automatically forced to become a string as well, and both strings are concatenated.

For example, consider this code:

String a = "Agent";
int n = 7;
String bond = a + n;

Note

Strings can be concatenated, that is, put end to end to yield a new longer string. String concatenation is denoted by the + operator.

Because a is a string, n is converted from the integer 7 to the string "7". Then the two strings "Agent" and "7" are concatenated to form the string "Agent7".

This concatenation is very useful to reduce the number of System.out.print instructions. For example, you can combine

System.out.print("The total is ");
System.out.println(total);

to the single call

System.out.println("The total is " + total);

The concatenation "The total is " + total computes a single string that consists of the string "The total is ", followed by the string equivalent of the number total.

Note

Whenever one of the arguments of the + operator is a string, the other argument is converted to a string.

Converting Strings to Numbers

Sometimes you have a string that contains a number, usually from user input. For example, suppose that the string variable input has the value "19". To get the integer value 19, you use the static parseInt method of the Integer class.

int count = Integer.parseInt(input);
   // count is the integer 19

To convert a string containing floating-point digits to its floating-point value, use the static parseDouble method of the Double class. For example, suppose input is the string "3.95".

double price = Double.parseDouble(input);
   // price  is the floating-point number 3.95

However, if the string contains spaces or other characters that cannot occur inside numbers, an error occurs. For now, we will always assume that user input does not contain invalid characters.

Note

If a string contains the digits of a number, you use the Integer.parseInt or Double.parseDouble method to obtain the number value.

Substrings

The substring method computes substrings of a string. The call

s.substring(start, pastEnd)

returns a string that is made up of the characters in the string s, starting at position start, and containing all characters up to, but not including, the position pastEnd. Here is an example:

String greeting = "Hello, World!";
String sub = greeting.substring(0, 5); // sub is "Hello"

Note

Use the substring method to extract a part of a string.

The substring operation makes a string that consists of five characters taken from the string greeting. A curious aspect of the substring operation is the numbering of the starting and ending positions. The first string position is labeled 0, the second one 1, and so on. For example, Figure 3 shows the position numbers in the greeting string.

Note

String positions are counted starting with 0.

String Positions

Figure 4.3. String Positions

The position number of the last character (12 for the string "Hello, World!") is always 1 less than the length of the string.

Let us figure out how to extract the substring "World". Count characters starting at 0, not 1. You find that W, the eighth character, has position number 7. The first character that you don't want, !, is the character at position 12 (see Figure 4).

Extracting a Substring

Figure 4.4. Extracting a Substring

Therefore, the appropriate substring command is

String sub2 = greeting.substring(7, 12);

It is curious that you must specify the position of the first character that you do want and then the first character that you don't want. There is one advantage to this setup. You can easily compute the length of the substring: It is pastEnd - start. For example, the string "World" has length 12 − 7 = 5.

If you omit the second parameter of the substring method, then all characters from the starting position to the end of the string are copied. For example,

String tail = greeting.substring(7); // Copies all characters from position 7 on
sets tail to the string "World!".

If you supply an illegal string position (a negative number, or a value that is larger than the length of the string), then your program terminates with an error message.

In this section, we have made the assumption that each character in a string occupies a single position. Unfortunately, that assumption is not quite correct. If you process strings that contain characters from international alphabets or special symbols, some characters may occupy two positions—see Special Topic 4.5 on page 153.

Extracting a Substring

15. Assuming the String variable river holds the value "Mississippi", what is the value of river.substring(1, 2)? Of river.substring(2, river.length() - 3)?

Reading Input

The Java programs that you have made so far have constructed objects, called methods, printed results, and exited. They were not interactive and took no user input. In this section, you will learn one method for reading user input.

Because output is sent to System.out, you might think that you use System.in for input. Unfortunately, it isn't quite that simple. When Java was first designed, not much attention was given to reading keyboard input. It was assumed that all programmers would produce graphical user interfaces with text fields and menus. System.in was given a minimal set of features—it can only read one byte at a time. Finally, in Java version 5, a Scanner class was added that lets you read keyboard input in a convenient manner.

To construct a Scanner object, simply pass the System.in object to the Scanner constructor:

Scanner in = new Scanner(System.in);

Note

Use the Scanner class to read keyboard input in a console window.

You can create a scanner out of any input stream (such as a file), but you will usually want to use a scanner to read keyboard input from System.in.

Once you have a scanner, you use the nextInt or nextDouble methods to read the next integer or floating-point number.

System.out.print("Enter quantity: ");
int quantity = in.nextInt();
System.out.print("Enter price: ");
double price = in.nextDouble();

When the nextInt or nextDouble method is called, the program waits until the user types a number and hits the Enter key. You should always provide instructions for the user (such as "Enter quantity:") before calling a Scanner method. Such an instruction is called a prompt.

If the user supplies an input that is not a number, then a run-time exception occurs. You will see in the next chapter how you can check whether the user supplied a numeric input.

The nextLine method returns the next line of input (until the user hits the Enter key) as a String object. The next method returns the next word, terminated by any white space, that is, a space, the end of a line, or a tab.

System.out.print("Enter city: ");
String city = in.nextLine();
System.out.print("Enter state code: ");
String state = in.next();

Here, we use the nextLine method to read a city name that may consist of multiple words, such as San Francisco. We use the next method to read the state code (such as CA), which consists of a single word.

Here is an example of a program that takes user input. This program uses the CashRegister class and simulates a transaction in which a user purchases an item, pays for it, and receives change.

We call this class CashRegisterSimulator, not CashRegisterTester. We reserve the Tester suffix for classes whose sole purpose is to test other classes.

ch04/cashregister/CashRegisterSimulator.java

1    import java.util.Scanner;
2
3    /**
4       This program simulates a transaction in which a user pays for an item
5       and receives change.
6    */
7    public class CashRegisterSimulator
8    {
9   public static void main(String[] args)
10   {
11      Scanner in = new Scanner(System.in);
12
13      CashRegister register = new CashRegister();
14
15      System.out.print("Enter price: ");
16      double price = in.nextDouble();
17      register.recordPurchase(price);
18
19      System.out.print("Enter dollars: ");
20      int dollars = in.nextInt();
21      System.out.print("Enter quarters: ");
22      int quarters = in.nextInt();
23      System.out.print("Enter dimes: ");
24      int dimes = in.nextInt();
25      System.out.print("Enter nickels: ");
26      int nickels = in.nextInt();
27      System.out.print("Enter pennies: ");
28      int pennies = in.nextInt();
29      register.enterPayment(dollars, quarters, dimes, nickels, pennies);
30
31      System.out.print("Your change: ");
32      System.out.println(register.giveChange());
33   }
34 }

Program Run

Enter price: 7.55
Enter dollars: 10
Enter quarters: 2
Enter dimes: 1
Enter nickels: 0
Enter pennies: 0
Your change: 3.05
Reading Input

17. Suppose in is a Scanner object that reads from System.in, and your program calls

String name = in.next();

What is the value of name if the user enters John Q. Public?

Summary of Learning Objectives

Choose appropriate types for representing numeric data.

  • Java has eight primitive types, including four integer types and two floating-point types.

  • A numeric computation overflows if the result falls outside the range for the number type.

  • Rounding errors occur when an exact conversion between numbers is not possible.

Write code that uses constants to document the purpose of numeric values.

  • A final variable is a constant. Once its value has been set, it cannot be changed.

  • Use named constants to make your programs easier to read and maintain.

Write arithmetic expressions in Java.

  • The ++ and -- operators increment and decrement a variable.

  • If both arguments of the / operator are integers, the result is an integer and the remainder is discarded.

  • The % operator computes the remainder of a division.

  • The Math class contains methods sqrt and pow to compute square roots and powers.

  • You use a cast (typeName) to convert a value to a different type.

  • Use the Math.round method to round a floating-point number to the nearest integer.

Distinguish between static methods and instance methods.

  • A static method does not operate on an object.

Process strings in Java programs.

  • A string is a sequence of characters. Strings are objects of the String class.

  • Strings can be concatenated, that is, put end to end to yield a new longer string. String concatenation is denoted by the + operator.

  • Whenever one of the arguments of the + operator is a string, the other argument is converted to a string.

  • If a string contains the digits of a number, you use the Integer.parseInt or Double.parseDouble method to obtain the number value.

  • Use the substring method to extract a part of a string.

  • String positions are counted starting with 0.

Write programs that read user input.

  • Use the Scanner class to read keyboard input in a console window.

Classes, Objects, and Methods Introduced in this Chapter

java.io.PrintStream            max                      java.util.Scanner
   printf                      min                         next
java.lang.Double               pow                         nextDouble
   parseDouble                 round                       nextInt
java.lang.Integer              sin                         nextLine
   MAX_VALUE                   sqrt                     javax.swing.JOptionPane
   MIN_VALUE                   tan                         showInputDialog
   parseInt                    toDegrees                   showMessageDialog
   toString                    toRadians
java.lang.Math              java.lang.String
   E                           format
   PI                          substring
   abs                      java.lang.System
   acos                        in
   asin                     java.math.BigDecimal
   atan                        add
   atan2                       multiply
   ceil                        subtract
   cos                      java.math.BigInteger
   exp                         add
   floor                       multiply
   log                         subtract
   log10

Media Resources

  • Worked Example Computing the Volume and Surface Area of a Pyramid

  • Worked Example Extracting Initials

  • • Lab Exercises

  • Media Resources
  • Media Resources

Review Exercises

R4.1 Write the following mathematical expressions in Java.

Review Exercises

R4.2 Write the following Java expressions in mathematical notation.

  1. dm = m * (Math.sqrt(1 + v / c) / (Math.sqrt(1 - v / c) - 1));

  2. volume = Math.PI * r * r * h;

  3. volume = 4 * Math.PI * Math.pow(r, 3) / 3;

  4. p = Math.atan2(z, Math.sqrt(x * x + y * y));

R4.3 What is wrong with this version of the quadratic formula?

x1 = (-b - Math.sqrt(b * b - 4 * a * c)) / 2 * a;
x2 = (-b + Math.sqrt(b * b - 4 * a * c)) / 2 * a;

R4.4 Give an example of integer overflow. Would the same example work correctly if you used floating-point?

R4.5 Give an example of a floating-point roundoff error. Would the same example work correctly if you used integers and switched to a sufficiently small unit, such as cents instead of dollars, so that the values don't have a fractional part?

R4.6 Consider the following code:

CashRegister register = new CashRegister();
register.recordPurchase(19.93);
register.enterPayment(20, 0, 0, 0, 0);
System.out.print("Change: ");
System.out.println(register.giveChange());

The code segment prints the total as 0.07000000000000028. Explain why. Give a recommendation to improve the code so that users will not be confused.

R4.7 Let n be an integer and x a floating-point number. Explain the difference between

n = (int) x;

and

n = (int) Math.round(x);

R4.8 Let n be an integer and x a floating-point number. Explain the difference between

n = (int) (x + 0.5);

and

n = (int) Math.round(x);

For what values of x do they give the same result? For what values of x do they give different results?

R4.9 Consider the vending machine implementation in How To 4.1 on page 146. What happens if the givePennyStamps method is invoked before the giveFirstClassStamps method?

R4.10 Explain the differences between 2, 2.0, '2', "2", and "2.0".

R4.11 Explain what each of the following two program segments computes:

int x = 2;
int y = x + x;

and

String s = "2";
String t = s + s;

R4.12 True or false? (x is an int and s is a String)

  1. Integer.parseInt("" + x) is the same as x

  2. "" + Integer.parseInt(s) is the same as s

  3. s.substring(0, s.length()) is the same as s

R4.13 How do you get the first character of a string? The last character? How do you remove the first character? The last character?

R4.14 How do you get the last digit of an integer? The first digit? That is, if n is 23456, how do you find out that the first digit is 2 and the last digit is 6? Do not convert the number to a string. Hint: %, Math.log.

R4.15 This chapter contains several recommendations regarding variables and constants that make programs easier to read and maintain. Summarize these recommendations.

R4.16 What is a final variable? Can you declare a final variable without supplying its value? (Try it out.)

R4.17 What are the values of the following expressions? In each line, assume that

double x = 2.5;
double y = −1.5;
int m = 18;
int n = 4;
  1. x + n * y - (x + n) * y

  2. m / n + m % n

  3. 5 * x - n / 5

  4. Math.sqrt(Math.sqrt(n))

  5. (int) Math.round(x)

  6. (int) Math.round(x) + (int) Math.round(y)

  7. 1 - (1 - (1 - (1 - (1 - n))))

R4.18 What are the values of the following expressions? In each line, assume that

int n = 4;
String s = "Hello";
String t = "World";
  1. s + t

  2. s + n

  3. n + t

  4. s.substring(1, n)

  5. s.length() + t.length()

Programming Exercises

P4.1 Enhance the CashRegister class by adding separate methods enterDollars, enterQuarters, enterDimes, enterNickels, and enterPennies.

Use this tester class:

public class CashRegisterTester
{
   public static void main (String[] args)
   {
      CashRegister register = new CashRegister();
      register.recordPurchase(20.37);
      register.enterDollars(20);
      register.enterQuarters(2);
      System.out.println("Change: " + register.giveChange());
      System.out.println("Expected: 0.13");
   }
}

P4.2 Enhance the CashRegister class so that it keeps track of the total number of items in a sale. Count all recorded purchases and supply a method

int getItemCount()

that returns the number of items of the current purchase. Remember to reset the count at the end of the purchase.

P4.3 Implement a class IceCreamCone with methods getSurfaceArea() and getVolume(). In the constructor, supply the height and radius of the cone. Be careful when looking up the formula for the surface area—you should only include the outside area along the side of the cone since the cone has an opening on the top to hold the ice cream.

P4.4 Write a program that prompts the user for two numbers, then prints

  • The sum

  • The difference

  • The product

  • The average

  • The distance (absolute value of the difference)

  • The maximum (the larger of the two)

  • The minimum (the smaller of the two)

To do so, implement a class

public class Pair
{
   /**
      Constructs a pair.
      @param aFirst the first value of the pair
      @param aSecond  the second value of the pair
   */
   public Pair(double aFirst, double aSecond) { ... }

   /**
      Computes the sum of the values of this pair.
      @return the sum of the first and second values
   */
   public double getSum() { ... }
   ...
}

Then implement a class PairTester that constructs a Pair object, invokes its methods, and prints the results.

P4.5 Declare a class DataSet that computes the sum and average of a sequence of integers. Supply methods

  • void addValue(int x)

  • int getSum()

  • double getAverage()

Hint: Keep track of the sum and the count of the values. Then write a test program DataSetTester that calls addValue four times and prints the expected and actual results.

P4.6 Write a class DataSet that computes the largest and smallest values in a sequence of numbers. Supply methods

  • void addValue(int x)

  • int getLargest()

  • int getSmallest()

Keep track of the smallest and largest values that you've seen so far. Then use the Math.min and Math.max methods to update them in the addValue method. What should you use as initial values? Hint: Integer.MIN_VALUE, Integer.MAX_VALUE.

Write a test program DataSetTester that calls addValue four times and prints the expected and actual results.

P4.7 Write a program that prompts the user for a measurement in meters and then converts it into miles, feet, and inches. Use a class

public class Converter
{
   /**

Constructs a converter that can convert between two units.

@param aConversionFactor the factor by which to multiply to convert to the target unit

*/
   public Converter(double aConversionFactor) { ... }
/**

Converts from a source measurement to a target measurement.

@param fromMeasurement the measurement

@return the input value converted to the target unit

*/
    public double convertTo(double fromMeasurement) { ... }

    /**

Converts from a target measurement to a source measurement.

@param toMeasurement the target measurement

@return the value whose conversion is the target measurement

*/
    public double convertFrom(double toMeasurement) { ... }
}

In your ConverterTester class, construct and test the following Converter object:

final double MILE_TO_KM = 1.609;
Converter milesToMeters = new Converter(1000 * MILE_TO_KM);

P4.8 Write a class Square whose constructor receives the length of the sides. Then supply methods to compute

  • The area and perimeter of the square

  • The length of the diagonal (use the Pythagorean theorem)

P4.9 Implement a class SodaCan whose constructor receives the height and diameter of the soda can. Supply methods getVolume and getSurfaceArea. Supply a SodaCanTester class that tests your class.

P4.10 Implement a class Balloon that models a spherical balloon that is being filled with air. The constructor constructs an empty balloon. Supply these methods:

  • void addAir(double amount) adds the given amount of air

  • double getVolume() gets the current volume

  • double getSurfaceArea() gets the current surface area

  • double getRadius() gets the current radius

Supply a BalloonTester class that constructs a balloon, adds 100 cm3 of air, tests the three accessor methods, adds another 100 cm3 of air, and tests the accessor methods again.

P4.11 Giving change. Enhance the CashRegister class so that it directs a cashier how to give change. The cash register computes the amount to be returned to the customer, in pennies.

Add the following methods to the CashRegister class:

  • int giveDollars()

  • int giveQuarters()

  • int giveDimes()

  • int giveNickels()

  • int givePennies()

Each method computes the number of dollar bills or coins to return to the customer, and reduces the change due by the returned amount. You may assume that the methods are called in this order. Here is a test class:

public class CashRegisterTester
{
   public static void main(String[] args)
   {
      CashRegister register = new CashRegister();

      register.recordPurchase(8.37);
      register.enterPayment(10, 0, 0, 0, 0);
      System.out.println("Dollars: " + register.giveDollars());
      System.out.println("Expected: 1");
      System.out.println("Quarters: " + register.giveQuarters());
      System.out.println("Expected: 2");
      System.out.println("Dimes: " + register.giveDimes());
      System.out.println("Expected: 1");
      System.out.println("Nickels: " + register.giveNickels());
      System.out.println("Expected: 0");
      System.out.println("Pennies: " + register.givePennies());
      System.out.println("Expected: 3");
   }
}

P4.12 In How To 4.1 on page 146, we represented the state of the vending machine by storing the balance in pennies. This is ingenious, but it is perhaps not the most obvious solution. Another possibility is to store the number of dollars that the customer inserted and the change that remains after giving out the first class stamps. Reimplement the vending machine in this way. Of course, the public interface should remain unchanged.

P4.13 Write a program that reads in an integer and breaks it into a sequence of individual digits in reverse order. For example, the input 16384 is displayed as

4
8
3
6
1

You may assume that the input has no more than five digits and is not negative. Declare a class DigitExtractor:

Declare a class DigitExtractor:
     public class DigitExtractor
     {
        /**
           Constructs a digit extractor that gets the digits
           of an integer in reverse order.
           @param anInteger the integer to break up into digits
        */
        public DigitExtractor(int anInteger) { ... }

        /**
           Returns the next digit to be extracted.
           @return the next digit
        */
        public int nextDigit() { ... }
     }

In your main class DigitPrinter, call System.out.println(myExtractor.nextDigit()) five times.

P4.14 Implement a class QuadraticEquation whose constructor receives the coefficients a, b, c of the quadratic equation ax2 + bx + c = 0. Supply methods getSolution1 and getSolution2 that get the solutions, using the quadratic formula. Write a test class QuadraticEquationTester that constructs a QuadraticEquation object, and prints the two solutions.

P4.15 Write a program that reads two times in military format (0900, 1730) and prints the number of hours and minutes between the two times. Here is a sample run. User input is in color.

Please enter the first time: 0900
Please enter the second time: 1730
8 hours 30 minutes

Extra credit if you can deal with the case where the first time is later than the second:

Please enter the first time: 1730
Please enter the second time: 0900
15 hours 30 minutes

Implement a class TimeInterval whose constructor takes two military times. The class should have two methods getHours and getMinutes.

P4.16 Writing large letters. A large letter H can be produced like this:

Programming Exercises
}
}

Declare similar classes for the letters E, L, and O. Then write the message

Programming Exercises

in large letters.

P4.17 Write a class ChristmasTree whose toString method yields a string depicting a Christmas tree:

Programming Exercises

Remember to use escape sequences.

P4.18 Your job is to transform numbers 1, 2, 3, . . ., 12 into the corresponding month names January, February, March, . . ., December. Implement a class Month whose constructor parameter is the month number and whose getName method returns the month name. Hint:Make a very long string "January February March . . . ", in which you add spaces such that each month name has the same length. Then use substring to extract the month you want.

P4.19 Write a class to compute the date of Easter Sunday. Easter Sunday is the first Sunday after the first full moon of spring. Use this algorithm, invented by the mathematician Carl Friedrich Gauss in 1800:

  1. Let y be the year (such as 1800 or 2001).

  2. Divide y by 19 and call the remainder a. Ignore the quotient.

  3. Divide y by 100 to get a quotient b and a remainder c.

  4. Divide b by 4 to get a quotient d and a remainder e.

  5. Divide 8 * b + 13 by 25 to get a quotient g. Ignore the remainder.

  6. Divide 19 * a + b - d - g + 15 by 30 to get a remainder h. Ignore the quotient.

  7. Divide c by 4 to get a quotient j and a remainder k.

  8. Divide a + 11 * h by 319 to get a quotient m. Ignore the remainder.

  9. Divide 2 * e + 2 * j - k - h + m + 32 by 7 to get a remainder r. Ignore the quotient.

  10. Divide h - m + r + 90 by 25 to get a quotient n. Ignore the remainder.

  11. Divide h - m + r + n + 19 by 32 to get a remainder p. Ignore the quotient.

Then Easter falls on day p of month n. For example, if y is 2001:

a = 6                g = 6               r = 6
b = 20               h = 18              n = 4
c = 1                j = 0, k = 1        p = 15
d = 5, e = 0         m = 0

Therefore, in 2001, Easter Sunday fell on April 15. Write a class Easter with methods getEasterSundayMonth and getEasterSundayDay.

Programming Projects

Project 4.1 In this project, you will perform calculations with triangles. A triangle is defined by the x- and y-coordinates of its three corner points.

Your job is to compute the following properties of a given triangle:

  • the lengths of all sides

  • the angles at all corners

  • the perimeter

  • the area

Of course, you should implement a Triangle class with appropriate methods. Supply a program that prompts a user for the corner point coordinates and produces a nicely formatted table of the triangle properties.

This is a good team project for two students. Both students should agree on the Triangle interface. One student implements the Triangle class, the other simultaneously implements the user interaction and formatting.

Project 4.2 The CashRegister class has an unfortunate limitation: It is closely tied to the coin system in the United States and Canada. Research the system used in most of Europe. Your goal is to produce a cash register that works with euros and cents. Rather than designing another limited CashRegister implementation for the European market, you should design a separate Coin class and a cash register that can work with coins of all types.

Answers to Self-Check Questions

  1. int and double.

  2. The world's most populous country, China, has about 1.2 x 109 inhabitants. Therefore, individual population counts could be held in an int. However, the world population is over 6 × 109. If you compute totals or averages of multiple countries, you can exceed the largest int value. Therefore, double is a better choice. You could also use long, but there is no benefit because the exact population of a country is not known at any point in time.

  3. The first initialization is incorrect. The right hand side is a value of type double, and it is not legal to initialize an int variable with a double value. The second initialization is correct—an int value can always be converted to a double.

  4. The first declaration is used inside a method, the second inside a class.

  5. (1) You should use a named constant, not the "magic number" 3.14. (2) 3.14 is not an accurate representation of π.

  6. One less than it was before.

  7. 17 and 29.

  8. Only s3 is divided by 3. To get the correct result, use parentheses. Moreover, if s1, s2, and s3 are integers, you must divide by 3.0 to avoid integer division:

    (s1 + s2 + s3) / 3.0
  9. Answers to Self-Check Questions
  10. When the fractional part of x is ≥0.5.

  11. By using a cast: (int) Math.round(x).

  12. x is a number, not an object, and you cannot invoke methods on numbers.

  13. No—the println method is called on the object System.out.

  14. s is set to the string "Agent5".

  15. The strings "i" and "ssissi".

  16. The class only has a method to read a single byte. It would be very tedious to form characters, strings, and numbers from those bytes.

  17. The value is "John". The next method reads the next word.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.191.86