This chapter begins with a discussion of the Number
[1] class in the java.lang
package, its subclasses, and the situations where you would use instantiations of these classes rather than the primitive number types.
This section also presents the PrintStream
[2] and DecimalFormat
[3] classes, which provide methods for writing formatted numerical output.
Finally, the Math
[4] class in java.lang
is discussed. It contains mathematical functions to complement the operators built into the language. This class has methods for the trigonometric functions, exponential functions, and so forth.
When working with numbers, most of the time you use the primitive types in your code. For example:
int i = 500; float gpa = 3.65; byte mask = 0xff;
There are, however, reasons to use objects in place of primitives, and the Java platform provides wrapper classes for each of the primitive data types. These classes “wrap” the primitive in an object. Often, the wrapping is done by the compiler; if you use a primitive where an object is expected, the compiler boxes the primitive in its wrapper class for you. Similarly, if you use a number object when a primitive is expected, the compiler unboxes the object for you.
Here is an example of boxing and unboxing:
Integer x, y; x = 12; y = 15; System.out.println(x+y);
When x
and y
are assigned integer values, the compiler boxes the integers because x
and y
are integer objects. In the println()
statement, x
and y
are unboxed so that they can be added as integers.
All of the numeric wrapper classes are subclasses of the abstract class Number
as shown in Figure 8.1.
There are four other subclasses of Number
that are not discussed here. BigDecimal
and BigInteger
are used for high-precision calculations. AtomicInteger
and AtomicLong
are used for multi-threaded applications.
There are three reasons that you might use a Number
object rather than a primitive:
as an argument of a method that expects an object (often used when manipulating collections of numbers);
to use constants defined by the class, such as MIN_VALUE
and MAX_VALUE
, that provide the upper and lower bounds of the data type;
to use class methods for converting values to and from other primitive types, for converting to and from strings, and for converting between number systems (decimal, octal, hexadecimal, binary).
Table 8.1 lists the instance methods that all the subclasses of the Number
class implement.
Table 8.1. Methods Implemented by All Subclasses of Number
Method | Description |
---|---|
| Converts the value of this |
| Compares this |
| Determines whether this number object is equal to the argument. The methods return |
Each Number
class contains other methods that are useful for converting numbers to and from strings and for converting between number systems. Table 8.2 lists these methods in the Integer
class. Methods for the other Number
subclasses are similar.
Table 8.2. Conversion Methods, Integer
Class
Description | |
---|---|
| Decodes a string into an integer. Can accept string representations of decimal, octal, or hexadecimal numbers as input. |
| Returns an integer (decimal only). |
| Returns an integer, given a string representation of decimal, binary, octal, or hexadecimal ( |
| Returns a |
| Returns a |
| Returns an |
| Returns an |
| Returns an |
Earlier you saw the use of the print()
and println()
methods for printing strings to standard output (System.out
). Since all numbers can be converted to strings (as you will see later in this chapter), you can use these methods to print out an arbitrary mixture of strings and numbers. The Java programming language has other methods, however, that allow you to exercise much more control over your print output when numbers are included.
The java.io
package includes a PrintStream
class that has two formatting methods that you can use to replace print()
and println()
. These methods, format()
and printf()
, are equivalent to one another. The familiar System.out
that you have been using happens to be a PrintStream
object, so you can invoke PrintStream
methods on System.out
. Thus, you can use format()
or printf()
anywhere in your code where you have previously been using print()
or println()
. For example,
System.out.format(.....);
The syntax for these two java.io.PrintStream
methods is the same:
public PrintStream format(String format, Object... args)
where format
is a string that specifies the formatting to be used and args
is a list of the variables to be printed using that formatting. A simple example would be:
System.out.format("The value of the float variable is %f, " + "while the value of the integer variable " + "is %d, and the string is %s", floatVar, intVar, stringVar);
The first parameter, format
, is a format string specifying how the objects in the second parameter, args
, are to be formatted. The format string contains plain text as well as format specifiers, which are special characters that format the arguments of Object... args
. The notation Object... args
is called varargs, which means that the number of arguments may vary.
Format specifiers begin with a percent sign (%
) and end with a conversion. The conversion is a character indicating the type of argument to be formatted. In between the percent sign (%
) and the conversion you can have optional flags and specifiers. There are many conversions, flags, and specifiers, which are documented in java.util.Formatter
.[5]
Here is a basic example:
int i = 461012; System.out.format("The value of i is: %d%n", i);
The %d
specifies that the single variable is a decimal integer. The %n
is a platform-independent newline character. The output is:
The value of i is: 461012
The printf()
and format()
methods are overloaded. Each has a version with the following syntax:
public PrintStream format(Locale l, String format, Object... args)
To print numbers in the French system (where a comma is used in place of the decimal place in the English representation of floating point numbers), for example, you would use:
System.out.format (Locale.FRANCE, "The value of the float variable is %f, " + "while the value of the integer variable is %d, and the " + "string is %s%n", floatVar, intVar, stringVar);
Table 8.3 lists some of the conversions and flags that are used in the sample program, TestFormat.java
.
Table 8.3. Conversions and Flags Used in TestFormat.java
Conversion | Flag | Explanation |
---|---|---|
| A decimal integer. | |
| A float. | |
| A new line character appropriate to the platform running the application. You should always use | |
| A date and time conversion—locale-specific full name of month. | |
| A date and time conversion—2-digit day of month. | |
| A date and time conversion— | |
| A date and time conversion—hour in 12-hour clock. | |
| A date and time conversion—minutes in 2 digits, with leading zeroes as necessary. | |
| A date and time conversion—locale-specific am/pm (lowercase). | |
| A date and time conversion—months in 2 digits, with leading zeroes as necessary. | |
| A date and time conversion—date as | |
| Eight characters in width, with leading zeroes as necessary. | |
| Includes sign, whether positive or negative. | |
| Includes locale-specific grouping characters. | |
| Left justified. | |
| Three places after decimal point. | |
| Ten characters in width, right justified, with three places after decimal point. |
The following program shows some of the formatting that you can do with format()
. The java.util
package must be imported, as it contains the Locale
and Calendar
classes:
import java.util.*; public class TestFormat { public static void main(String[] args) { long n = 461012; System.out.format("%d%n", n); System.out.format("%08d%n", n); System.out.format("%+8d%n", n); System.out.format("%,8d%n", n); System.out.format("%+,8d%n%n", n); double pi = Math.PI; System.out.format("%f%n", pi); System.out.format("%.3f%n", pi); System.out.format("%10.3f%n", pi); System.out.format("%-10.3f%n", pi); System.out.format(Locale.FRANCE, "%-10.4f%n%n", pi); Calendar c = Calendar.getInstance(); System.out.format("%tB %te, %tY%n", c, c, c); System.out.format("%tl:%tM %tp%n", c, c, c); System.out.format("%tD%n", c); } }
The output is:
461012 00461012 +461012 461,012 +461,012 3.141593 3.142 3.142 3.142 3,1416 May 29, 2006 2:34 am 05/29/06
The discussion in this section covers just the basics of the format()
and printf()
methods. Further detail can be found in the Formatting section (page 272).
You can use the java.text.DecimalFormat
class to control the display of leading and trailing zeros, prefixes and suffixes, grouping (thousands) separators, and the decimal separator. DecimalFormat
offers a great deal of flexibility in the formatting of numbers, but it can make your code more complex.
The example that follows creates a DecimalFormat
object, myFormatter
, by passing a pattern string to the DecimalFormat
constructor. The format()
method, which DecimalFormat
inherits from NumberFormat
, is then invoked by myFormatter
—it accepts a double
value as an argument and returns the formatted number in a string.
Here is a sample program that illustrates the use of DecimalFormat
:
import java.text.*; public class DecimalFormatDemo { static public void customFormat(String pattern, double value ) { DecimalFormat myFormatter = new DecimalFormat(pattern); String output = myFormatter.format(value); System.out.println(value + " " + pattern + " " + output); } static public void main(String[] args) { customFormat("###,###.###", 123456.789); customFormat("###.##", 123456.789); customFormat("000000.000", 123.78); customFormat("$###,###.###", 12345.67); } }
The output is:
123456.789 ###,###.### 123,456.789 123456.789 ###.## 123456.79 123.78 000000.000 000123.780 12345.67 $###,###.### $12,345.67
Table 8.4 explains each line of output.
Table 8.4. DecimalFormat.java
Output
Value | Pattern | Output | Explanation |
---|---|---|---|
|
|
| The pound sign ( |
|
|
| The |
|
|
| The |
|
|
| The first character in the |
The Java programming language supports basic arithmetic with its arithmetic operators: +
, -
, *
, /
, and %
. The Math
class in the java.lang
package provides methods and constants for doing more advanced mathematical computations.
The methods in the Math
class are all static, so you call them directly from the class, like this:
Math.cos(angle);
Using the static import
language feature (see the The Static Import Statement section, page 190), you don’t have to write Math
in front of every math function:
import static java.lang.Math.*;
This allows you to invoke the Math
class methods by their simple names. For example:
cos(angle);
The Math
class includes two constants:
Math.E
, which is the base of natural logarithms, and
Math.PI
, which is the ratio of the circumference of a circle to its diameter.
The Math
class also includes more than 40 static methods. Table 8.5 lists a number of the basic methods.
Table 8.5. Basic Math
Methods
Method | Description |
---|---|
| Returns the absolute value of the argument. |
| Returns the smallest integer that is greater than or equal to the argument. Returned as a double. |
| Returns the largest integer that is less than or equal to the argument. Returned as a double. |
| Returns the integer that is closest in value to the argument. Returned as a double. |
| Returns the closest long or int, as indicated by the method’s return type, to the argument. |
| Returns the smaller of the two arguments. |
| Returns the larger of the two arguments. |
The following program, BasicMathDemo
,[6] illustrates how to use some of these methods:
public class BasicMathDemo { public static void main(String[] args) { double a = -191.635; double b = 43.74; int c = 16, d = 45; System.out.printf("The absolute value of %.3f is %.3f%n", a, Math.abs(a)); System.out.printf("The ceiling of %.2f is %.0f%n", b, Math.ceil(b)); System.out.printf("The floor of %.2f is %.0f%n", b, Math.floor(b)); System.out.printf("The rint of %.2f is %.0f%n", b, Math.rint(b)); System.out.printf("The max of %d and %d is %d%n", c, d, Math.max(c, d)); System.out.printf("The min of of %d and %d is %d%n", c, d, Math.min(c, d)); } }
Here’s the output from this program:
The absolute value of -191.635 is 191.635 The ceiling of 43.74 is 44 The floor of 43.74 is 43 The rint of 43.74 is 44 The max of 16 and 45 is 45 The min of 16 and 45 is 16
Table 8.6 lists exponential and logarithmic methods of the Math
class.
Table 8.6. Exponential and Logarithmic Methods
Method | Description |
---|---|
| Returns the base of the natural logarithms, e, to the power of the argument. |
| Returns the natural logarithm of the argument. |
| Returns the value of the first argument raised to the power of the second argument. |
| Returns the square root of the argument. |
The following program, ExponentialDemo
,[7] displays the value of e
, then calls each of the methods listed in Table 8.6 on arbitrarily chosen numbers:
public class ExponentialDemo { public static void main(String[] args) { double x = 11.635; double y = 2.76; System.out.printf("The value of e is %.4f%n", Math.E); System.out.printf("exp(%.3f) is %.3f%n", x, Math.exp(x)); System.out.printf("log(%.3f) is %.3f%n", x, Math.log(x)); System.out.printf("pow(%.3f, %.3f) is %.3f%n", x, y, Math.pow(x, y)); System.out.printf("sqrt(%.3f) is %.3f%n", x, Math.sqrt(x)); } }
Here’s the output you’ll see when you run ExponentialDemo
:
The value of e is 2.7183 exp(11.635) is 112983.831 log(11.635) is 2.454 pow(11.635, 2.760) is 874.008 sqrt(11.635) is 3.411
The Math
class also provides a collection of trigonometric functions, which are summarized in Table 8.7. The value passed into each of these methods is an angle expressed in radians. You can use the toRadians
method to convert from degrees to radians.
Table 8.7. Trigonometric Methods
Method | Description |
---|---|
| Returns the sine of the specified double value. |
| Returns the cosine of the specified double value. |
| Returns the tangent of the specified double value. |
| Returns the arcsine of the specified double value. |
| Returns the arccosine of the specified double value. |
| Returns the arctangent of the specified double value. |
| Converts rectangular coordinates |
| Converts the argument to degrees or radians. |
Here’s a program, TrigonometricDemo
,[8] that uses each of these methods to compute various trigonometric values for a 45-degree angle:
public class TrigonometricDemo { public static void main(String[] args) { double degrees = 45.0; double radians = Math.toRadians(degrees); System.out.format("The value of pi is %.4f%n", Math.PI); System.out.format("The sine of %.1f degrees is %.4f%n", degrees, Math.sin(radians)); System.out.format("The cosine of %.1f degrees is %.4f%n", degrees, Math.cos(radians)); System.out.format("The tangent of %.1f degrees is %.4f%n", degrees, Math.tan(radians)); System.out.format("The arcsine of %.4f is %.4f degrees %n", Math.sin(radians), Math.toDegrees(Math.asin(Math.sin(radians)))); System.out.format("The arccosine of %.4f is %.4f " + degrees %n", Math.cos(radians), Math.toDegrees(Math.acos(Math.cos(radians)))); System.out.format("The arctangent of %.4f is %.4f " + degrees %n", Math.tan(radians), Math.toDegrees(Math.atan(Math.tan(radians)))); } }
The output of this program is as follows:
The value of pi is 3.1416 The sine of 45.0 degrees is 0.7071 The cosine of 45.0 degrees is 0.7071 The tangent of 45.0 degrees is 1.0000 The arcsine of 0.7071 is 45.0000 degrees The arccosine of 0.7071 is 45.0000 degrees The arctangent of 1.0000 is 45.0000 degrees
The random()
method returns a pseudo-randomly selected number between 0.0 and 1.0. The range includes 0.0 but not 1.0. In other words: 0.0 <= Math.random() < 1.0
. To get a number in a different range, you can perform arithmetic on the value returned by the random method. For example, to generate an integer between 0 and 9, you would write:
int number = (Math.random() * 10);
By multiplying the value by 10, the range of possible values becomes 0.0 <= number < 10.0
.
Using Math.random
works well when you need to generate a single random number. If you need to generate a series of random numbers, you should create an instance of java.util.Random
and invoke methods on that object to generate numbers.
You use one of the wrapper classes—Byte
, Double
, Float
, Integer
, Long
, or Short
—to wrap a number of primitive type in an object. The Java compiler automatically wraps (boxes) primitives for you when necessary and unboxes them, again when necessary.
The Number
classes include constants and useful class methods. The MIN_VALUE
and MAX_VALUE
constants contain the smallest and largest values that can be contained by an object of that type. The byteValue
, shortValue
, and similar methods convert one numeric type to another. The valueOf
method converts a string to a number, and the toString
method converts a number to a string.
To format a string containing numbers for output, you can use the printf()
or format()
methods in the PrintStream
class. Alternatively, you can use the NumberFormat
class to customize numerical formats using patterns.
The Math
class contains a variety of class methods for performing mathematical functions, including exponential, logarithmic, and trigonometric methods. Math
also includes basic arithmetic functions, such as absolute value and rounding, and a method, random()
, for generating random numbers.
1. | Change |
2. | Create a program that reads an unspecified number of integer arguments from the command line and adds them together. For example, suppose that you enter the following: java Adder 1 3 2 10 The program should display |
3. | Create a program that is similar to the previous one but has the following differences: For example, suppose that you enter the following: java FPAdder 1 1e2 3.0 4.754 The program would display |
Most of the time, if you are using a single character value, you will use the primitive char
type, for example:
char ch = 'a'; char uniChar = 'u039A'; // Unicode for uppercase Greek // omega character char[] charArray ={ 'a', 'b', 'c', 'd', 'e' }; // an array // of chars
There are times, however, when you need to use a char as an object—for example, as a method argument where an object is expected. The Java programming language provides a wrapper class that “wraps” the char
in a Character
object for this purpose. An object of type Character
contains a single field, whose type is char
. This Character
[10] class also offers a number of useful class (i.e., static) methods for manipulating characters.
You can create a Character
object with the Character
constructor:
Character ch = new Character('a'),
The Java compiler will also create a Character
object for you under some circumstances. For example, if you pass a primitive char
into a method that expects an object, the compiler automatically converts the char
to a Character
for you. This feature is called autoboxing—or unboxing, if the conversion goes the other way.
Here is an example of boxing:
Character ch = 'a'; // the primitive char 'a' // is boxed into the Character object ch
and here is an example of both boxing and unboxing:
Character test(Character c) {...} // method parameter and // return type = // Character object char c = test('x'), // primitive 'x' is boxed for method test, // return is unboxed to char 'c'
The Character
class is immutable, so that once it is created, a Character
object cannot be changed.
Table 8.8 lists some of the most useful methods in the Character
class but is not exhaustive. For a complete listing of all methods in this class (there are more than fifty), refer to the java.lang.Character
API specification.
Table 8.8. Useful Methods in the Character
Class
Method | Description |
---|---|
| Determines whether the specified char value is a letter or a digit, respectively. |
| Determines whether the specified char value is white space. |
| Determines whether the specified char value is uppercase or lowercase, respectively. |
| Returns the uppercase or lowercase form of the specified char value. |
| Returns a |
A character preceded by a backslash () is an escape sequence and has special meaning to the compiler. The newline character (
) has been used frequently in this tutorial in System.out.println()
statements to advance to the next line after the string is printed. Table 8.9 shows the Java escape sequences.
Table 8.9. Escape Sequences
Escape Sequence | Description |
---|---|
| Insert a tab in the text at this point. |
Insert a backspace in the text at this point. | |
| Insert a newline in the text at this point. |
| Insert a carriage return in the text at this point. |
| Insert a form feed in the text at this point. |
| Insert a single quote character in the text at this point. |
| Insert a double quote character in the text at this point. |
| Insert a backslash character in the text at this point. |
When an escape sequence is encountered in a print statement, the compiler interprets it accordingly. For example, if you want to put quotes within quotes you must use the escape sequence, "
, on the interior quotes. To print the sentence:
She said "Hello!" to me.
you would write:
System.out.println("She said "Hello!" to me.");
Strings, which are widely used in Java programming, are a sequence of characters. In the Java programming language, strings are objects.
The Java platform provides the String
[11] class to create and manipulate strings.
The most direct way to create a string is to write:
String greeting = "Hello world!";
In this case, “Hello world!” is a string literal—a series of characters in your code that is enclosed in double quotes. Whenever it encounters a string literal in your code, the compiler creates a String
object with its value—in this case, Hello world!
.
As with any other object, you can create String
objects by using the new
keyword and a constructor. The String
class has eleven constructors that allow you to provide the initial value of the string using different sources, such as an array of characters:
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.'}; String helloString = new String(helloArray); System.out.println(helloString);
The last line of this code snippet displays hello
.
The String
class is immutable, so that once it is created a String
object cannot be changed. The String
class has a number of methods, some of which will be discussed next, that appear to modify strings. Since strings are immutable, what these methods really do is create and return a new string that contains the result of the operation.
Methods used to obtain information about an object are known as accessor methods. One accessor method that you can use with strings is the length()
method, which returns the number of characters contained in the string object. After the following two lines of code have been executed, len
equals 17:
String palindrome = "Dot saw I was Tod"; int len = palindrome.length();
A palindrome is a word or sentence that is symmetric—it is spelled the same forward and backward, ignoring case and punctuation. Here is a short and inefficient program to reverse a palindrome string. It invokes the String
method charAt(i)
, which returns the ith character in the string, counting from 0:
public class StringDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); char[] tempCharArray = new char[len]; char[] charArray = new char[len]; // put original string in an array of chars for (int i = 0; i < len; i++) { tempCharArray[i] = palindrome.charAt(i); } // reverse array of chars for (int j = 0; j < len; j++) { charArray[j] = tempCharArray[len - 1 - j]; } String reversePalindrome = new String(charArray); System.out.println(reversePalindrome); } }
Running the program produces this output:
doT saw I was toD
To accomplish the string reversal, the program had to convert the string to an array of characters (first for
loop), reverse the array into a second array (second for
loop), and then convert back to a string. The String
class includes a method, getChars()
, to convert a string, or a portion of a string, into an array of characters, so we could replace the first for
loop in the program above with:
palindrome.getChars(0, len - 1, tempCharArray, 0);
The String
class includes a method for concatenating two strings:
string1.concat(string2);
This returns a new string that is string1
with string2
added to it at the end.
You can also use the concat()
method with string literals, as in:
"My name is ".concat("Rumplestiltskin");
Strings are more commonly concatenated with the +
operator, as in:
"Hello," + " world" + "!"
which results in:
"Hello, world!"
The +
operator is widely used in print
statements. For example:
String string1 = "saw I was "; System.out.println("Dot " + string1 + "Tod");
which prints:
Dot saw I was Tod
Such a concatenation can be a mixture of any objects. For each object that is not a String
, its toString()
method is called to convert it to a String
.
The Java programming language does not permit literal strings to span lines in source files, so you must use the +
concatenation operator at the end of each line in a multi-line string. For example:
String quote = "Now is the time for all good " + "men to come to the aid of their country.";
Breaking strings between lines using the +
concatenation operator is, once again, very common in print
statements.
You have seen the use of the printf()
and format()
methods to print output with formatted numbers. The String
class has an equivalent class method, format()
, that returns a String
object rather than a PrintStream
object.
Using String
’s static format()
method allows you to create a formatted string that you can reuse, as opposed to a one-time print statement. For example, instead of:
System.out.printf("The value of the float variable is " + "%f, while the value of the integer " + "variable is %d, and the string " + "is %s", floatVar, intVar, stringVar);
you can write:
String fs; fs = String.format("The value of the float variable is " + "%f, while the value of the integer " + "variable is %d, and the string " + "is %s", floatVar, intVar, stringVar); System.out.println(fs);
Frequently, a program ends up with numeric data in a string object—a value entered by the user, for example.
The Number
subclasses that wrap primitive numeric types (Byte
,[12] Integer
,[13] Double
,[14] Float
,[15] Long
,[16] and Short
[17]) each provide a class method named valueOf
that converts a string to an object of that type. Here is an example, ValueOfDemo
,[18] that gets two strings from the command line, converts them to numbers, and performs arithmetic operations on the values:
public class ValueOfDemo { public static void main(String[] args) { // this program requires two arguments on the command line if (args.length == 2) { // convert strings to numbers float a = (Float.valueOf(args[0])).floatValue(); float b = (Float.valueOf(args[1])).floatValue(); // do some arithmetic System.out.println("a + b = " + (a + b) ); System.out.println("a - b = " + (a - b) ); System.out.println("a * b = " + (a * b) ); System.out.println("a / b = " + (a / b) ); System.out.println("a % b = " + (a % b) ); } else { System.out.println("This program requires " + "two command-line arguments."); } } }
The following is the output from the program when you use 4.5
and 87.2
for the command-line arguments:
a + b = 91.7 a - b = -82.7 a * b = 392.4 a / b = 0.0516055 a % b = 4.5
Each of the Number
subclasses that wrap primitive numeric types also provides a parseXXX()
method (for example, parseFloat()
) that can be used to convert strings to primitive numbers. Since a primitive type is returned instead of an object, the parseFloat()
method is more direct than the valueOf()
method. For example, in the ValueOfDemo
program, we could use:
float a = Float.parseFloat(args[0]); float b = Float.parseFloat(args[1]);
Sometimes you need to convert a number to a string because you need to operate on the value in its string form. There are several easy ways to convert a number to a string:
int i; String s1 = "" + i; // Concatenate "i" with an empty string; // conversion is handled for you.
String s2 = String.valueOf(i); // The valueOf class method.
Each of the Number
subclasses includes a class method, toString()
, that will convert its primitive type to a string. For example:
int i; double d; String s3 = Integer.toString(i); String s4 = Double.toString(d);
The ToStringDemo
[19] example uses the toString
method to convert a number to a string. The program then uses some string methods to compute the number of digits before and after the decimal point:
public class ToStringDemo { public static void main(String[] args) { double d = 858.48; String s = Double.toString(d); int dot = s.indexOf('.'), System.out.println(dot + " digits before decimal point."); System.out.println( (s.length() - dot - 1) + " digits after decimal point."); } }
The output of this program is:
3 digits before decimal point. 2 digits after decimal point.
The String
class has a number of methods for examining the contents of strings, finding characters or substrings within a string, changing case, and other tasks.
You can get the character at a particular index within a string by invoking the charAt()
accessor method. The index of the first character is 0, while the index of the last character is length()-1
. For example, the following code gets the character at index 9 in a string:
String anotherPalindrome = "Niagara. O roar again!"; char aChar = anotherPalindrome.charAt(9);
Indices begin at 0, so the character at index 9 is “O”, as illustrated in Figure 8.2.
If you want to get more than one consecutive character from a string, you can use the substring
method. The substring
method has two versions, as shown in Table 8.10.
Table 8.10. The substring
Methods in the String
Class
Method | Description |
---|---|
| Returns a new string that is a substring of this string. The first integer argument specifies the index of the first character. The second integer argument is the index of the last character + 1. |
| Returns a new string that is a substring of this string. The integer argument specifies the index of the first character. Here, the returned substring extends to the end of the original string. |
The following code gets from the Niagara palindrome the substring that extends from index 11 up to, but not including, index 15, which is the word “roar” (Figure 8.3):
String anotherPalindrome = "Niagara. O roar again!"; String roar = anotherPalindrome.substring(11, 15);
Table 8.11 lists several other String
methods for manipulating strings.
Table 8.11. Other Methods in the String
Class for Manipulating Strings
Method | Description |
---|---|
| Searches for a match as specified by the string argument (which contains a regular expression) and splits this string into an array of strings accordingly. The optional integer argument specifies the maximum size of the returned array. Regular expressions are covered in Chapter 13. |
| Returns a new character sequence constructed from |
| Returns a copy of this string with leading and trailing white space removed. |
| Returns a copy of this string converted to lowercase or uppercase. If no conversions are necessary, these methods return the original string. |
Here are some other String
methods for finding characters or substrings within a string. The String
class provides accessor methods that return the position within the string of a specific character or substring: indexOf()
and lastIndexOf()
. The indexOf()
methods search forward from the beginning of the string, and the lastIndexOf()
methods search backward from the end of the string. If a character or substring is not found, indexOf()
and lastIndexOf()
return -1
.
The String
class also provides a search method, contains
, that returns true if the string contains a particular character sequence. Use this method when you only need to know that the string contains a character sequence, but the precise location isn’t important.
Table 8.12 describes the various string search methods.
Table 8.12. The Search Methods in the String
Class
Method | Description |
---|---|
| Returns the index of the first (last) occurrence of the specified character. |
| Returns the index of the first (last) occurrence of the specified character, searching forward (backward) from the specified index. |
| Returns the index of the first (last) occurrence of the specified substring. |
| Returns the index of the first (last) occurrence of the specified substring, searching forward (backward) from the specified index. |
| Returns true if the string contains the specified character sequence. |
The String
class has very few methods for inserting characters or substrings into a string. In general, they are not needed: You can create a new string by concatenation of substrings you have removed from a string with the substring that you want to insert.
The String
class does have four methods for replacing found characters or substrings, however. They are listed in Table 8.13.
Table 8.13. Methods in the String
Class for Manipulating Strings
Method | Description |
---|---|
| Returns a new string resulting from replacing all occurrences of |
| Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence. |
| Replaces each substring of this string that matches the given regular expression with the given replacement. |
| Replaces the first substring of this string that matches the given regular expression with the given replacement. |
The following class, Filename
,[20] illustrates the use of lastIndexOf()
and substring()
to isolate different parts of a file name.
The methods in the following Filename
class don’t do any error checking and assume that their argument contains a full directory path and a filename with an extension. If these methods were production code, they would verify that their arguments were properly constructed.
/** * This class assumes that the string used to initialize * fullPath has a directory path, filename, and extension. * The methods won't work if it doesn't. */ public class Filename { private String fullPath; private char pathSeparator, extensionSeparator; public Filename(String str, char sep, char ext) { fullPath = str; pathSeparator = sep; extensionSeparator = ext; } public String extension() { int dot = fullPath.lastIndexOf(extensionSeparator); return fullPath.substring(dot + 1); } public String filename() { // gets filename without extension int dot = fullPath.lastIndexOf(extensionSeparator); int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(sep + 1, dot); } public String path() { int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(0, sep); } }
Here is a program, FilenameDemo
,[21] that constructs a Filename
object and calls all of its methods:
public class FilenameDemo { public static void main(String[] args) { final String FPATH = "/home/mem/index.html"; Filename myHomePage = new Filename(FPATH, '/', '.'), System.out.println("Extension = " + myHomePage.extension()); System.out.println("Filename = " + myHomePage.filename()); System.out.println("Path = " + myHomePage.path()); } }
And here’s the output from the program:
Extension = html Filename = index Path = /home/mem
As shown in Figure 8.4, our extension
method uses lastIndexOf
to locate the last occurrence of the period (.
) in the file name. Then substring
uses the return value of lastIndexOf
to extract the file name extension—that is, the substring from the period to the end of the string. This code assumes that the file name has a period in it; if the file name does not have a period, lastIndexOf
returns -1
, and the substring method throws a StringIndexOutOfBoundsException
.
Also, notice that the extension
method uses dot + 1
as the argument to substring
. If the period character (.
) is the last character of the string, dot + 1
is equal to the length of the string, which is one larger than the largest index into the string (because indices start at 0). This is a legal argument to substring
because that method accepts an index equal to, but not greater than, the length of the string and interprets it to mean “the end of the string.”
The String
class has a number of methods for comparing strings and portions of strings. Table 8.14 lists these methods.
Table 8.14. Methods for Comparing Strings
Method | Description |
---|---|
| Returns |
| Considers the string beginning at the index |
| Compares two strings lexicographically. Returns an integer indicating whether this string is greater than (result is > 0), equal to (result is = 0), or less than (result is < 0) the argument. |
| Compares two strings lexicographically, ignoring differences in case. Returns an integer indicating whether this string is greater than (result is > 0), equal to (result is = 0), or less than (result is < 0) the argument. |
| Returns |
| Returns |
| Tests whether the specified region of this string matches the specified region of the String argument.Region is of length |
| Tests whether the specified region of this string matches the specified region of the String argument.Region is of length |
| Tests whether this string matches the specified regular expression. Regular expressions are discussed in Chapter 13. |
The following program, RegionMatchesDemo
,[22] uses the regionMatches
method to search for a string within another string:
public class RegionMatchesDemo { public static void main(String[] args) { String searchMe = "Green Eggs and Ham"; String findMe = "Eggs"; int searchMeLength = searchMe.length(); int findMeLength = findMe.length(); boolean foundIt = false; for (int i = 0; i <= (searchMeLength - findMeLength); i++) { if (searchMe.regionMatches(i, findMe, 0, findMeLength)) { foundIt = true; System.out.println(searchMe.substring(i, i + findMeLength)); break; } } if (!foundIt) System.out.println("No match found."); } }
The output from this program is Eggs
.
The program steps through the string referred to by searchMe
one character at a time. For each character, the program calls the regionMatches method to determine whether the substring beginning with the current character matches the string the program is looking for.
StringBuilder
[23] objects are like String
objects, except that they can be modified. Internally, these objects are treated like variable-length arrays that contain a sequence of characters. At any point, the length and content of the sequence can be changed through method invocations.
Strings should always be used unless string builders offer an advantage in terms of simpler code (see the sample program at the end of this section) or better performance. For example, if you need to concatenate a large number of strings, appending to a StringBuilder
object is more efficient.
The StringBuilder
class, like the String
class, has a length()
method that returns the length of the character sequence in the builder.
Unlike strings, every string builder also has a capacity, the number of character spaces that have been allocated. The capacity, which is returned by the capacity()
method, is always greater than or equal to the length (usually greater than) and will automatically expand as necessary to accommodate additions to the string builder (Table 8.15).
Table 8.15. StringBuilder
Constructors
Constructor | Description |
---|---|
| Creates an empty string builder with a capacity of 16 (16 empty elements). |
| Constructs a string builder containing the same characters as the specified |
| Creates an empty string builder with the specified initial capacity. |
| Creates a string builder whose value is initialized by the specified string, plus an extra 16 empty elements trailing the string. |
For example, the following code:
StringBuilder sb = new StringBuilder(); // creates empty // builder, capacity 16 sb.append("Greetings"); // adds 9 character string at beginning
will produce a string builder with a length of 9 and a capacity of 16, as shown in Figure 8.5.
The StringBuilder
class has some methods related to length and capacity that the String
class does not have; see Table 8.16.
Table 8.16. Length and Capacity Methods
Constructor | Description |
---|---|
| Sets the length of the character sequence. If |
| Ensures that the capacity is at least equal to the specified minimum. |
A number of operations (for example, append()
, insert()
, or setLength()
) can increase the length of the character sequence in the string builder so that the resultant length()
would be greater than the current capacity()
. When this happens, the capacity is automatically increased.
The principal operations on a StringBuilder
that are not available in String
are the append()
and insert()
methods, which are overloaded so as to accept data of any type. Each converts its argument to a string and then appends or inserts the characters of that string to the character sequence in the string builder. The append()
method always adds these characters at the end of the existing character sequence, while the insert()
method adds the characters at a specified point.
Table 8.17 lists a number of the methods of the StringBuilder
class.
Table 8.17. Various StringBuilder
Methods
Description | |
---|---|
| Appends the argument to this string builder. The data is converted to a string before the append operation takes place. |
| Deletes the specified character(s) in this string builder. |
| Inserts the second argument into the string builder. The first integer argument indicates the index before which the data is to be inserted. The data is converted to a string before the insert operation takes place. |
| Replaces the specified character(s) in this string builder. |
| Reverses the sequence of characters in this string builder. |
| Returns a string that contains the character sequence in the builder. |
The StringDemo
program that was listed in the Strings section (page 212) is an example of a program that would be more efficient if a StringBuilder
were used instead of a String
.
StringDemo
reversed a palindrome. Here, once again, is its listing:
public class StringDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); char[] tempCharArray = new char[len]; char[] charArray = new char[len]; // put original string in an array of chars for (int i = 0; i < len; i++) { tempCharArray[i] = palindrome.charAt(i); } // reverse array of chars for (int j = 0; j < len; j++) { charArray[j] = tempCharArray[len - 1 - j]; } String reversePalindrome = new String(charArray); System.out.println(reversePalindrome); } }
Running the program produces this output:
doT saw I was toD
To accomplish the string reversal, the program converts the string to an array of characters (first for
loop), reverses the array into a second array (second for
loop), and then converts back to a string.
If you convert the palindrome
string to a string builder, you can use the reverse()
method in the StringBuilder
class. It makes the code simpler and easier to read:
public class StringBuilderDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; StringBuilder sb = new StringBuilder(palindrome); sb.reverse(); // reverse it System.out.println(sb); } }
Running this program produces the same output:
doT saw I was toD
Note that println()
prints a string builder, as in:
System.out.println(sb);
because sb.toString()
is called implicitly, as it is with any other object in a println()
invocation.
There is also a StringBuffer
class that is exactly the same as the StringBuilder
class, except that it is thread-safe by virtue of having its methods synchronized. Threads will be discussed in Chapter 12.
Most of the time, if you are using a single character value, you will use the primitive char
type. There are times, however, when you need to use a char as an object—for example, as a method argument where an object is expected. The Java programming language provides a wrapper class that “wraps” the char
in a Character
object for this purpose. An object of type Character
contains a single field whose type is char
. This Character
class also offers a number of useful class (i.e., static) methods for manipulating characters.
Strings are a sequence of characters and are widely used in Java programming. In the Java programming language, strings are objects. The String
class has over 60 methods and 13 constructors.
Most commonly, you create a string with a statement like:
String s = "Hello world!";
rather than using one of the String
constructors.
The String
class has many methods to find and retrieve substrings; these can then be easily reassembled into new strings using the +
concatenation operator.
The String
class also includes a number of utility methods, among them split()
, toLowerCase()
, toUpperCase()
, and valueOf()
. The latter method is indispensable in converting user input strings to numbers. The Number
subclasses also have methods for converting strings to numbers and vice versa.
In addition to the String
class, there is also a StringBuilder
class. Working with StringBuilder
objects can sometimes be more efficient than working with strings. The StringBuilder
class offers a few methods that can be useful for strings, among them reverse()
. In general, however, the String
class has a wider variety of methods.
A string can be converted to a string builder using a StringBuilder
constructor. A string builder can be converted to a string with the toString()
method.
1. | What is the initial capacity of the following string builder? StringBuilder sb = new StringBuilder("Able was I " + "ere I saw Elba."); |
2. | Consider the following string: String hannah = "Did Hannah see bees? Hannah did.";
|
3. | How long is the string returned by the following expression? What is the string? "Was it a car or a cat I saw?".substring(9, 12) |
4. | In the following program, called public class ComputeResult { public static void main(String[] args) { String original = "software"; StringBuilder result = new StringBuilder("hi"); int index = original.indexOf('a'), /*1*/ result.setCharAt(0, original.charAt(0)); /*2*/ result.setCharAt(1, original.charAt(original.length()-1)); /*3*/ result.insert(1, original.charAt(4)); /*4*/ result.append(original.substring(1,4)); /*5*/ result.insert(3, (original.substring(index, index+2) + " ")); System.out.println(result); } } |
[1] docs/api/java/lang/Number.html
[2] docs/api/java/io/PrintStream.html
[3] docs/api/java/text/DecimalFormat.html
[4] docs/api/java/lang/Math.html
[5] docs/api/java/util/Formatter.html
[6] tutorial/java/data/examples/BasicMathDemo.java
[7] tutorial/java/data/examples/ExponentialDemo.java
[8] tutorial/java/data/examples/TrigonometricDemo.java
[9] tutorial/java/data/QandE/MaxVariablesDemo.java
[10] docs/api/java/lang/Character.html
[11] docs/api/java/lang/String.html
[12] docs/api/java/lang/Byte.html
[13] docs/api/java/lang/Integer.html
[14] docs/api/java/lang/Double.html
[15] docs/api/java/lang/Float.html
[16] docs/api/java/lang/Long.html
[17] docs/api/java/lang/Short.html
[18] tutorial/java/data/examples/ValueOfDemo.java
[19] tutorial/java/data/examples/ToStringDemo.java
[20] tutorial/java/data/examples/Filename.java
[21] tutorial/java/data/examples/FilenameDemo.java
[22] tutorial/java/data/examples/RegionMatchesDemo.java
[23] docs/api/java/lang/StringBuilder.html
[24] tutorial/java/data/QandE/ComputeResult.java
18.119.104.160