java.lang
PackageThe java.lang
package is indispensable when programming in Java. It is automatically imported into every source file at compile time. The package contains the Object
class that is the superclass of all classes, and the wrapper classes (Boolean
, Character
, Byte
, Short
, Integer
, Long
, Float
, Double
) used to handle primitive values as objects. It provides classes essential for interacting with the JVM (Runtime
), for security (SecurityManager
), for loading classes (ClassLoader
), for dealing with threads (Thread
), and for exceptions (Throwable
). The java.lang
package also contains classes that provide the standard input, output, and error streams (System
), string handling (String
, StringBuilder
, StringBuffer
), and mathematical functions (Math
).
Figure 10.1 shows the important classes that are discussed in detail in this chapter.
Object
ClassAll classes extend the Object
class, either directly or indirectly. A class declaration, without the extends
clause, implicitly extends the Object
class (see Section 7.1, p. 284). Thus, the Object
class is always at the root of any inheritance hierarchy. The Object
class defines the basic functionality that all objects exhibit and all classes inherit. Note that this also applies to arrays, since these are genuine objects in Java.
The Object
class provides the following general utility methods (see Example 10.1 for usage of some of these methods):
When storing objects in hash tables, this method can be used to get a hash value for an object. This value is guaranteed to be consistent during the execution of the program. This method returns the memory address of the object as the default hash value of the object. For a detailed discussion of the hashCode()
method, see Section 15.1 on page 748.
Object reference and value equality are discussed together with the ==
and !=
operators (see Section 5.11, p. 191). The equals()
method in the Object
class returns true
only if the two references compared denote the same object. The equals()
method is usually overridden to provide the semantics of object value equality, as is the case for the wrapper classes and the String
class. For a detailed discussion of the equals()
method, see Section 15.1 on page 748.
final Class<?> getClass()
Returns the runtime class of the object, which is represented by an object of the class java.lang.Class
at runtime.
protected Object clone() throws CloneNotSupportedException
New objects that are exactly the same (i.e., have identical states) as the current object can be created by using the clone()
method, i.e., primitive values and reference values are copied. This is called shallow copying. A class can override this method to provide its own notion of cloning. For example, cloning a composite object by recursively cloning the constituent objects is called deep copying.
When overridden, the method in the subclass is usually declared public
to allow any client to clone objects of the class. If the overriding clone()
method in the subclass relies on the clone()
method in the Object
class (i.e., a shallow copy), the subclass must implement the Cloneable
marker interface to indicate that its objects can be safely cloned. Otherwise, the clone()
method in the Object
class will throw a checked CloneNotSupportedException
.
String toString()
If a subclass does not override this method, it returns a textual representation of the object, which has the following format:
“<name of the class>@
<hash code value of object>”
Since the default hash value of an object is its memory address, this value is printed as a hexadecimal number, e.g., 3e25a5
. This method is usually overridden and used for debugging purposes. The method call System.out.println(objRef)
will implicitly convert its argument to a textual representation by calling the toString()
method on the argument. See also the binary string concatenation operator +
, discussed in Section 5.6 on page 180.
protected void finalize() throws Throwable
This method is discussed in connection with garbage collection (see Section 9.4, p. 396). It is called on an object just before it is garbage collected, so that any cleaning up can be done. However, the default finalize()
method in the Object
class does not do anything useful.
In addition, the Object
class provides support for thread communication in synchronized code, through the following methods, which are discussed in Section 13.6 on page 634:
final void wait(long timeout) throws InterruptedException
final void wait(long timeout, int nanos) throws InterruptedException
final void wait() throws InterruptedException
final void notify()
final void notifyAll()
A thread invokes these methods on the object whose lock it holds. A thread waits for notification by another thread.
Example 10.1 Methods in the Object
class
class MyClass implements Cloneable {
public Object clone() {
Object obj = null;
try { obj = super.clone();} // Calls overridden method.
catch (CloneNotSupportedException e) { System.out.println(e);}
return obj;
}
}
//____________________________________________________
public class ObjectMethods {
public static void main(String[] args) {
// Two objects of MyClass.
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
// Two strings.
String str1 = new String("WhoAmI");
String str2 = new String("WhoAmI");
// Method hashCode() overridden in String class.
// Strings that are equal have the same hash code.
System.out.println("hash code for str1: " + str1.hashCode());
System.out.println("hash code for str2: " + str2.hashCode() + "
");
// Hash codes are different for different MyClass objects.
System.out.println("hash code for MyClass obj1: " + obj1.hashCode());
System.out.println("hash code for MyClass obj2: " + obj2.hashCode()+"
");
// Method equals() overridden in the String class.
System.out.println("str1.equals(str2): " + str1.equals(str2));
System.out.println("str1 == str2: " + (str1 == str2) + "
");
// Method equals() from the Object class called.
System.out.println("obj1.equals(obj2): " + obj1.equals(obj2));
System.out.println("obj1 == obj2: " + (obj1 == obj2) + "
");
// The runtime object that represents the class of an object.
Class rtStringClass = str1.getClass();
Class rtMyClassClass = obj1.getClass();
// The name of the class represented by the runtime object.
System.out.println("Class for str1: " + rtStringClass);
System.out.println("Class for obj1: " + rtMyClassClass + "
");
// The toString() method is overridden in the String class.
String textRepStr = str1.toString();
String textRepObj = obj1.toString();
System.out.println("Text representation of str1: " + textRepStr);
System.out.println("Text representation of obj1: " + textRepObj + "
");
// Shallow copying of arrays.
MyClass[] array1 = {new MyClass(), new MyClass(), new MyClass()};
MyClass[] array2 = array1.clone();
// Array objects are different, but share the element objects.
System.out.println("array1 == array2: " + (array1 == array2));
for(int i = 0; i < array1.length; i++) {
System.out.println("array1[" + i + "] == array2[" + i + "] : " +
(array1[i] == array2[i]));
}
System.out.println();
// Clone an object of MyClass.
MyClass obj3 = (MyClass) obj1.clone(); // Cast required.
System.out.println("hash code for MyClass obj3: " + obj3.hashCode());
System.out.println("obj1 == obj3: " + (obj1 == obj3));
}
}
Output from the program:
hash code for str1: -1704812257
hash code for str2: -1704812257
hash code for MyClass obj1: 25669322
hash code for MyClass obj2: 14978587
str1.equals(str2): true
str1 == str2: false
obj1.equals(obj2): false
obj1 == obj2: false
Class for str1: class java.lang.String
Class for obj1: class MyClass
Text representation of str1: WhoAmI
Text representation of obj1: MyClass@187aeca
array1 == array2: false
array1[0] == array2[0] : true
array1[1] == array2[1] : true
array1[2] == array2[2] : true
hash code for MyClass obj3: 19770577
obj1 == obj3: false
10.1 What is the return type of the hashCode()
method in the Object
class?
Select the one correct answer.
(a) String
(b) int
(c) long
(d) Object
(e) Class
10.2 Which statement is true?
Select the one correct answer.
(a) If the references x
and y
denote two different objects, the expression x.equals(y)
is always false
.
(b) If the references x
and y
denote two different objects, the expression (x.hashCode() == y.hashCode())
is always false
.
(c) The hashCode()
method in the Object
class is declared final
.
(d) The equals()
method in the Object
class is declared final
.
(e) All arrays have a method named clone
.
10.3 Which exception can the clone()
method of the Object
class throw?
Select the one correct answer.
(a) CloneNotSupportedException
(b) NotCloneableException
(c) IllegalCloneException
(d) NoClonesAllowedException
Wrapper classes were introduced with the discussion of the primitive data types (see Section 2.2, p. 28), and also in connection with boxing and unboxing of primitive values (see Section 5.1, p. 162). Primitive values in Java are not objects. In order to manipulate these values as objects, the java.lang
package provides a wrapper class for each of the primitive data types. All wrapper classes are final
. The objects of all wrapper classes that can be instantiated are immutable, i.e., the value in the wrapper object cannot be changed.
Although the Void
class is considered a wrapper class, it does not wrap any primitive value and is not instantiable (i.e., has no public
constructors). It just denotes the Class
object representing the keyword void
. The Void
class will not be discussed further in this section.
In addition to the methods defined for constructing and manipulating objects of primitive values, the wrapper classes also define useful constants, fields, and conversion methods.
The Character
class has only one public
constructor, taking a char
value as parameter. The other wrapper classes all have two public
one-argument constructors: one takes a primitive value and the other takes a string.
WrapperType(type v)
WrapperType(String str)
The type is a primitive data type. The string argument is converted to a primitive value that corresponds to the WrapperType. Otherwise a NumberFormatException
is thrown if the string is not parsable.
Boxing is a convenient way to wrap a primitive value in an object (see (1a) in Figure 10.2 and Section 5.1, p. 162).
Character charObj1 = '
';
Boolean boolObj1 = true;
Integer intObj1 = 2008;
Double doubleObj1 = 3.14;
A constructor that takes a primitive value can be used to create wrapper objects (see (1b) in Figure 10.2).
Character charObj1 = new Character('
'),
Boolean boolObj1 = new Boolean(true);
Integer intObj1 = new Integer(2008);
Double doubleObj1 = new Double(3.14);
We can also use the valueOf()
method that takes the primitive value to wrap as an argument (see (1c) in Figure 10.2).
Character charObj1 = Character.valueOf('
'),
Boolean boolObj1 = Boolean.valueOf(true);
Integer intObj1 = Integer.valueOf(2008);
Double doubleObj1 = Double.valueOf(3.14);
A constructor that takes a String
object representing the primitive value can also be used to create wrapper objects. The constructors for the numeric wrapper types throw an unchecked NumberFormatException
if the String
parameter does not parse to a valid number (see (2a) in Figure 10.2).
Boolean boolObj2 = new Boolean("TrUe"); // case ignored: true
Boolean boolObj3 = new Boolean("XX"); // false
Integer intObj2 = new Integer("2008");
Double doubleObj2 = new Double("3.14");
Long longObj1 = new Long("3.14"); // NumberFormatException
Each wrapper class (except Character
) defines the static method valueOf(String str)
that returns the wrapper object corresponding to the primitive value represented by the String
object passed as argument (see (6b) in Figure 10.2). This method for the numeric wrapper types also throws a NumberFormatException
if the String
parameter is not a valid number.
Boolean boolObj4 = Boolean.valueOf("false");
Integer intObj3 = Integer.valueOf("1949");
Double doubleObj3 = Double.valueOf("-3.0");
In addition to the one-argument valueOf()
method, the integer wrapper classes define an overloaded static valueOf()
method that can take a second argument. This argument specifies the base (or radix) in which to interpret the string representing the signed integer in the first argument:
Byte byteObj1 = Byte.valueOf("1010", 2); // Decimal value 10
Short shortObj2 = Short.valueOf("012", 8); // Not " 12". Decimal value 10.
Integer intObj4 = Integer.valueOf("-a", 16); // Not "-0xa". Decimal value -10.
Long longObj2 = Long.valueOf("-a", 16); // Not "-0xa". Decimal value -10L.
Each wrapper class overrides the toString()
method from the Object
class. The overriding method returns a String
object containing the string representation of the primitive value in the wrapper object (see (3) in Figure 10.2).
String charStr = charObj1.toString(); // "
"
String boolStr = boolObj2.toString(); // "true"
String intStr = intObj1.toString(); // "2008"
String doubleStr = doubleObj1.toString(); // "3.14"
Each wrapper class defines a static method toString(
type
v)
that returns the string corresponding to the primitive value of type
, passed as argument (see (6a) in Figure 10.2).
String charStr2 = Character.toString('
'), // "
"
String boolStr2 = Boolean.toString(true); // "true"
String intStr2 = Integer.toString(2008); // Base 10. "2008"
String doubleStr2 = Double.toString(3.14); // "3.14"
For integer primitive types, the base is assumed to be 10. For floating-point numbers, the textual representation (decimal form or scientific notation) depends on the sign and the magnitude (absolute value) of the number. The NaN value, positive infinity, and negative infinity will result in the strings "NaN"
, "Infinity"
, and "-Infinity"
, respectively.
In addition, the wrapper classes Integer
and Long
define overloaded toString()
methods for converting integers to string representation in decimal, binary, octal, and hexadecimal notation (see p. 435).
Unboxing is a convenient way to unwrap the primitive value in a wrapper object (see (4a) in Figure 10.2 and Section 5.1, p. 162).
char c = charObj1; // '
'
boolean b = boolObj2; // true
int i = intObj1; // 2008
double d = doubleObj1; // 3.14
Each wrapper class defines a typeValue()
method which returns the primitive value in the wrapper object (see (4b) in Figure 10.2).
char c = charObj1.charValue(); // '
'
boolean b = boolObj2.booleanValue(); // true
int i = intObj1.intValue(); // 2008
double d = doubleObj1.doubleValue(); // 3.14
In addition, each numeric wrapper class defines typeValue()
methods for converting the primitive value in the wrapper object to a value of any numeric primitive data type. These methods are discussed below.
Each wrapper class also implements the Comparable<
Type
>
interface (see Section 15.1, p. 765), which defines the following method:
This method returns a value which is less than, equal to, or greater than zero, depending on whether the primitive value in the current wrapper Type
object is less than, equal to, or greater than the primitive value in the wrapper Type
object denoted by argument obj2
.
// Comparisons based on objects created above
Character charObj2 = 'a';
int result1 = charObj1.compareTo(charObj2); // < 0
int result2 = intObj1.compareTo(intObj3); // > 0
int result3 = doubleObj1.compareTo(doubleObj2); // == 0
int result4 = doubleObj1.compareTo(intObj1); // ClassCastException
Each wrapper class overrides the equals()
method from the Object
class (see Section 15.1, p. 751). The overriding method compares two wrapper objects for object value equality.
// Comparisons based on objects created above
boolean charTest = charObj1.equals(charObj2); // false
boolean boolTest = boolObj2.equals(Boolean.FALSE); // false
boolean intTest = intObj1.equals(intObj2); // true
boolean doubleTest = doubleObj1.equals(doubleObj2); // true
The following values are interned when they are wrapped during boxing, i.e., only one wrapper object exists in the program for these primitive values when boxing is applied:
• boolean
values true
or false
,
• a byte
,
• a char
in the range u0000
to u007f
,
• an int
or short
value in the range -128 and 127
If references w1
and w2
refer to two wrapper objects that box the same value which is among the ones mentioned above, then w1 == w2
is always true
. In other words, for the values listed above, object equality and reference equality give the same result.
// Reference and object equality
Byte bRef1 = (byte)10;
Byte bRef2 = (byte)10;
System.out.println(bRef1 == bRef2); // true
System.out.println(bRef1.equals(bRef2)); // true
Integer iRef1 = 1000;
Integer iRef2 = 1000;
System.out.println(iRef1 == iRef2); // false
System.out.println(iRef1.equals(iRef2)); // true
Each wrapper class also overrides the hashCode()
method in the Object
class (see Section 15.1, p. 760). The overriding method returns a hash value based on the primitive value in the wrapper object.
int index = charObj1.hashCode();
The numeric wrapper classes Byte
, Short
, Integer
, Long
, Float
, and Double
are all subclasses of the abstract
class Number
(see Figure 10.1).
Each numeric wrapper class defines an assortment of constants, including the minimum and maximum value of the corresponding primitive data type:
Each numeric wrapper class defines the following set of typeValue()
methods for converting the primitive value in the wrapper object to a value of any numeric primitive type:
byte byteValue()
short shortValue()
int intValue()
long longValue()
float floatValue()
double doubleValue()
The following code shows conversion of values in numeric wrapper objects to any numeric primitive type.
Byte byteObj2 = new Byte((byte) 16); // Cast mandatory
Integer intObj5 = new Integer(42030);
Double doubleObj4 = new Double(Math.PI);
short shortVal = intObj5.shortValue(); // (1)
long longVal = byteObj2.longValue();
int intVal = doubleObj4.intValue(); // (2) Truncation
double doubleVal = intObj5.doubleValue();
Notice the potential for loss of information at (1) and (2) above, when the primitive value in a wrapper object is converted to a narrower primitive data type.
Each numeric wrapper class defines a static method parse
Type(String str)
, which returns the primitive numeric value represented by the String
object passed as argument. The Type in the method name parse
Type stands for the name of a numeric wrapper class, except for the name of the Integer
class which is abbreviated to Int
. These methods throw a NumberFormatException
if the String
parameter is not a valid argument (see (5) in Figure 10.2.)
byte value1 = Byte.parseByte("16");
int value2 = Integer.parseInt("2010"); // parseInt, not parseInteger.
int value3 = Integer.parseInt("7UP"); // NumberFormatException
double value4 = Double.parseDouble("3.14");
For the integer wrapper types, the overloaded static method parse
Type()
can additionally take a second argument, which can specify the base in which to interpret the string representing the signed integer in the first argument:
byte value6 = Byte.parseByte("1010", 2); // Decimal value 10
short value7 = Short.parseShort("012", 8); // Not " 12". Decimal value 10.
int value8 = Integer.parseInt("-a", 16); // Not "-0xa". Decimal value -10.
long value9 = Long.parseLong("-a", 16); // Not "-0xa". Decimal value -10L.
The wrapper classes Integer
and Long
provide static methods for converting integers to string representation in decimal, binary, octal, and hexadecimal notation. Some of these methods from the Integer
class are listed here, but analogous methods are also defined in the Long
class. Example 10.2 demonstrates use of these methods.
static String toBinaryString(int i)
static String toHexString(int i)
static String toOctalString(int i)
These three methods return a string representation of the integer argument as an unsigned integer in base 2, 16, and 8, respectively, with no extra leading zeroes.
static String toString(int i, int base)
static String toString(int i)
The first method returns the minus sign '-'
as the first character if the integer i
is negative. In all cases, it returns the string representation of the magnitude of the integer i
in the specified base.
The last method is equivalent to the method toString(int i, int base)
, where the base has the value 10, that returns the string representation as a signed decimal (see also (6a) in Figure 10.2).
Example 10.2 String Representation of Integers
public class IntegerRepresentation {
public static void main(String[] args) {
int positiveInt = +41; // 051, 0x29
int negativeInt = -41; // 037777777727, -051, 0xffffffd7, -0x29
System.out.println("String representation for decimal value: " + positiveInt);
integerStringRepresentation(positiveInt);
System.out.println("String representation for decimal value: " + negativeInt);
integerStringRepresentation(negativeInt);
}
public static void integerStringRepresentation(int i) {
System.out.println(" Binary: " + Integer.toBinaryString(i));
System.out.println(" Octal: " + Integer.toOctalString(i));
System.out.println(" Hex: " + Integer.toHexString(i));
System.out.println(" Decimal: " + Integer.toString(i));
System.out.println(" Using toString(int i, int base) method:");
System.out.println(" Base 2: " + Integer.toString(i, 2));
System.out.println(" Base 8: " + Integer.toString(i, 8));
System.out.println(" Base 16: " + Integer.toString(i, 16));
System.out.println(" Base 10: " + Integer.toString(i, 10));
}
}
String representation for decimal value: 41
Binary:101001
Octal:51
Hex:29
Decimal:41
Using toString(int i, int base) method:
Base 2:101001
Base 8:51
Base 16:29
Base 10:41
String representation for decimal value: -41
Binary:11111111111111111111111111010111
Octal:37777777727
Hex:ffffffd7
Decimal:-41
Using toString(int i, int base) method:
Base 2:-101001
Base 8:-51
Base 16:-29
Base 10:-41
The Character
class defines a myriad of constants, including the following which represent the minimum and the maximum value of the char
type (see Section 2.2, p. 29):
The Character
class also defines a plethora of static methods for handling various attributes of a character, and case issues relating to characters, as defined by the Unicode standard, version 4.0:
static int getNumericValue(char ch)
static boolean isLowerCase(char ch)
static boolean isUpperCase(char ch)
static boolean isTitleCase(char ch)
static boolean isDigit(char ch)
static boolean isLetter(char ch)
static boolean isLetterOrDigit(char ch)
static char toUpperCase(char ch)
static char toLowerCase(char ch)
static char toTitleCase(char ch)
The following code converts a lowercase character to an uppercase character:
char ch = 'a';
if (Character.isLowerCase(ch)) ch = Character.toUpperCase(ch);
The Boolean
class defines the following wrapper objects to represent the primitive values true
and false
, respectively:
10.4 Which of the following are wrapper classes?
Select the three correct answers.
(a) java.lang.Void
(b) java.lang.Int
(c) java.lang.Boolean
(d) java.lang.Long
(e) java.lang.String
10.5 Which of the following classes do not extend the java.lang.Number
class?
Select the two correct answers.
(a) java.lang.Float
(b) java.lang.Byte
(c) java.lang.Character
(d) java.lang.Boolean
(e) java.lang.Short
10.6 Which of these classes define immutable objects?
Select the three correct answers.
(a) Character
(b) Byte
(c) Number
(d) Short
(e) Object
10.7 Which of these classes have a one-parameter constructor taking a string?
Select the two correct answers.
(a) Void
(b) Integer
(c) Boolean
(d) Character
(e) Object
10.8 Which of the wrapper classes have a booleanValue()
method?
Select the one correct answer.
(a) All wrapper classes.
(b) All wrapper classes except Void
.
(c) All wrapper classes that also implement the compareTo()
method.
(d) All wrapper classes extending Number
.
(e) Only the class Boolean
.
10.9 Which statements are true about wrapper classes?
Select the two correct answers.
(a) String
is a wrapper class.
(b) Double
has a compareTo()
method.
(c) Character
has a intValue()
method.
(d) Byte
extends Number
.
10.10 What will the program print when compiled and run?
public class RQ200_60 {
public static void main(String[] args) {
Integer i = -10;
Integer j = -10;
System.out.print(i==j);
System.out.print(i.equals(j));
Integer n = 128;
Integer m = 128;
System.out.print(n==m);
System.out.print(n.equals(m));
}
}
Select the one correct answer.
(a) falsetruefalsetrue
(b) truetruetruetrue
(c) falsetruetruetrue
(d) truetruefalsetrue
(e) None of the above.
10.11 What will the program print when compiled and run?
public class RQ200_70 {
public static void main(String[] args) {
Integer i = new Integer(-10);
Integer j = new Integer(-10);
Integer k = -10;
System.out.print(i==j);
System.out.print(i.equals(j));
System.out.print(i==k);
System.out.print(i.equals(k));
}
}
Select the one correct answer.
(a) falsetruefalsetrue
(b) truetruetruetrue
(c) falsetruetruetrue
(d) truetruefalsetrue
(e) None of the above.
Handling character sequences is supported through three final
classes: String
, StringBuilder
and StringBuffer
. The Java 2 platform uses the variable-length UTF-16 encoding to store characters in char
arrays and in the string handling classes. The UTF-16 encoding allows characters whose Unicode values are in the range 0000 to 10FFFF. The char
type only represents Unicode values in the range 0000 to FFFF, i.e. characters that can be represented in a single 16-bit word. This means that the supplementary characters are represented by multiple char
values, i.e. multiple 16-bit words, when these are stored in a string or a char
array. The string handling classes provide methods to handle the full range of characters in the UTF-16 encoding, but we will not dwell on the subject in this book.
The String
class implements immutable character strings, which are read-only once the string has been created and initialized, whereas the StringBuilder
class implements dynamic character strings. The StringBuffer
class is a thread-safe version of the StringBuilder
class.
This section discusses the class String
that provides facilities for creating, initializing, and manipulating character strings. The next section discusses the StringBuilder
and StringBuffer
classes.
The easiest way of creating a String
object is using a string literal:
String str1 = "You cannot change me!";
A string literal is a reference to a String
object. The value in the String
object is the character sequence enclosed in the double quotes of the string literal. Since a string literal is a reference, it can be manipulated like any other String
reference. The reference value of a string literal can be assigned to another String
reference: the reference str1
will denote the String
object with the value "You cannot change me!"
after the assignment above. A string literal can be used to invoke methods on its String
object:
The compiler optimizes handling of string literals (and compile-time constant expressions that evaluate to strings): only one String
object is shared by all string-valued constant expressions with the same character sequence. Such strings are said to be interned, meaning that they share a unique String
object if they have the same content. The String
class maintains a private pool where such strings are interned.
String str2 = "You cannot change me!";
Both String
references str1
and str2
denote the same String
object, initialized with the character string: "You cannot change me!"
. So does the reference str3
in the following code. The compile-time evaluation of the constant expression involving the two string literals, results in a string that is already interned:
String str3 = "You cannot" + " change me!"; // Compile-time constant expression
In the following code, both the references can1
and can2
denote the same String
object that contains the string "7Up"
:
String can1 = 7 + "Up"; // Value of compile-time constant expression: "7Up"
String can2 = "7Up"; // "7Up"
However, in the code below, the reference can4
will denote a new String
object that will have the value "7Up"
at runtime:
String word = "Up";
String can4 = 7 + word; // Not a compile-time constant expression.
The sharing of String
objects between string-valued constant expressions poses no problem, since the String
objects are immutable. Any operation performed on one String
reference will never have any effect on the usage of other references denoting the same object. The String
class is also declared final
, so that no subclass can override this behavior.
The String
class has numerous constructors to create and initialize String
objects based on various types of arguments. Here we present a few selected constructors:
Note that using a constructor creates a brand new String
object, i.e., using a constructor does not intern the string. A reference to an interned string can be obtained by calling the intern()
method in the String
class—in practice, there is usually no reason to do so.
In the following code, the String
object denoted by str4
is different from the String
object passed as argument:
String str4 = new String("You cannot change me!");
Constructing String
objects can also be done from arrays of bytes, arrays of characters, or string builders:
byte[] bytes = {97, 98, 98, 97};
String()
This constructor creates a new String
object, whose content is the empty string, ""
.
String(String str)
This constructor creates a new String
object, whose contents are the same as those of the String
object passed as argument.
String(char[] value)
String(char[] value, int offset, int count)
These constructors create a new String
object whose contents are copied from a char
array. The second constructor allows extraction of a certain number of characters (count
) from a given offset
in the array.
String(StringBuilder builder)
String(StringBuffer buffer)
These constructors allow interoperability with the StringBuilder
and the StringBuffer
class, respectively.
char[] characters = {'a', 'b', 'b', 'a'};
StringBuilder strBuilder = new StringBuilder("abba");
//...
String byteStr = new String(bytes); // Using array of bytes: "abba"
String charStr = new String(characters); // Using array of chars: "abba"
String buildStr = new String(strBuilder); // Using string builder: "abba"
In Example 10.3, note that the reference str1
does not denote the same String
object as the references str4
and str5
. Using the new
operator with a String
constructor always creates a new String
object. The expression "You cannot" + words
is not a constant expression and, therefore, results in a new String
object. The local references str2
and str3
in the main()
method and the static reference str1
in the Auxiliary
class all denote the same interned string. Object value equality is hardly surprising between these references. It might be tempting to use the operator ==
for object value equality of string literals, but this is not advisable.
Example 10.3 String Construction and Equality
public class StringConstruction {
static String str1 = "You cannot change me!"; // Interned
public static void main(String[] args) {
String emptyStr = new String(); // ""
System.out.println("emptyStr: "" + emptyStr + """);
String str2 = "You cannot change me!"; // Interned
String str3 = "You cannot" + " change me!"; // Interned
String str4 = new String("You cannot change me!"); // New String object
String words = " change me!";
String str5 = "You cannot" + words; // New String object
System.out.println("str1 == str2: " + (str1 == str2)); // (1) true
System.out.println("str1.equals(str2): " + str1.equals(str2)); // (2) true
System.out.println("str1 == str3: " + (str1 == str3)); // (3) true
System.out.println("str1.equals(str3): " + str1.equals(str3)); // (4) true
System.out.println("str1 == str4: " + (str1 == str4)); // (5) false
System.out.println("str1.equals(str4): " + str1.equals(str4)); // (6) true
System.out.println("str1 == str5: " + (str1 == str5)); // (7) false
System.out.println("str1.equals(str5): " + str1.equals(str5)); // (8) true
System.out.println("str1 == Auxiliary.str1: " +
(str1 == Auxiliary.str1)); // (9) true
System.out.println("str1.equals(Auxiliary.str1): " +
str1.equals(Auxiliary.str1)); // (10) true
System.out.println(""You cannot change me!".length(): " +
"You cannot change me!".length());// (11) 21
}
}
class Auxiliary {
static String str1 = "You cannot change me!"; // Interned
}
Output from the program:
emptyStr: ""
str1 == str2: true
str1.equals(str2): true
str1 == str3: true
str1.equals(str3): true
str1 == str4: false
str1.equals(str4): true
str1 == str5: false
str1.equals(str5): true
str1 == Auxiliary.str1: true
str1.equals(Auxiliary.str1): true
"You cannot change me!".length(): 21
This interface is implemented by all three classes: String
, StringBuilder
and StringBuffer
. Many methods in these classes accept arguments of this interface type, and specify it as their return type. This facilitates interoperability between these classes. This interface defines the following methods:
char charAt(int index)
A character at a particular index in a sequence can be read using the charAt()
method. The first character is at index 0
and the last one at index one less than the number of characters in the string. If the index value is not valid, an IndexOutOfBoundsException
is thrown.
int length()
This method returns the number of char
values in this sequence.
CharSequence subSequence(int start, int end)
This method returns a new CharSequence
that is a subsequence of this sequence. Characters from the current sequence are read from index start
to the index end-1
, inclusive.
String toString()
This method returns a string containing the characters in this sequence in the same order as this sequence.
char charAt(int index)
This method is defined in the CharSequence
interface which the String
class implements (p. 442).
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
This method copies characters from the current string into the destination character array. Characters from the current string are read from index srcBegin
to the index srcEnd-1
, inclusive. They are copied into the destination array (dst
), starting at index dstBegin
and ending at index dstbegin+(srcEnd-srcBegin)-1
. The number of characters copied is (srcEnd-srcBegin)
. An IndexOutOfBoundsException
is thrown if the indices do not meet the criteria for the operation.
int length()
This method is defined in the CharSequence
interface which the String
class implements (p. 442).
boolean isEmpty()
This method returns true
if the length of the string is 0
, otherwise false
.
Example 10.4 uses some of these methods at (3), (4), (5), and (6). The program prints the frequency of a character in a string and illustrates copying from a string into a character array.
Example 10.4 Reading Characters from a String
public class ReadingCharsFromString {
public static void main(String[] args) {
int[] frequencyData = new int [Character.MAX_VALUE]; // (1)
String str = "You cannot change me!"; // (2)
// Count the frequency of each character in the string.
for (int i = 0; i < str.length(); i++) // (3)
try {
frequencyData[str.charAt(i)]++; // (4)
} catch(StringIndexOutOfBoundsException e) {
System.out.println("Index error detected: "+ i +" not in range.");
}
// Print the character frequency.
System.out.println("Character frequency for string: "" + str + """);
for (int i = 0; i < frequencyData.length; i++)
if (frequencyData[i] != 0)
System.out.println((char)i + " (code "+ i +"): " +
frequencyData[i]);
System.out.println("Copying into a char array:");
char[] destination = new char [str.length()];
str.getChars( 0, 7, destination, 0); // (5) "You can"
str.getChars(10, str.length(), destination, 7); // (6) " change me!"
// Print the character array.
for (int i = 0; i < 7 + (str.length() - 10); i++)
System.out.print(destination[i]);
System.out.println();
}
}
Output from the program:
Character Frequency for string: "You cannot change me!"
(code 32): 3
! (code 33): 1
Y (code 89): 1
a (code 97): 2
c (code 99): 2
e (code 101): 2
g (code 103): 1
h (code 104): 1
m (code 109): 1
n (code 110): 3
o (code 111): 2
t (code 116): 1
u (code 117): 1
Copying into a char array:
You can change me!
In Example 10.4, the frequencyData
array at (1) stores the frequency of each character that can occur in a string. The string in question is declared at (2). Since a char
value is promoted to an int
value in arithmetic expressions, it can be used as an index in an array. Each element in the frequencyData
array functions as a frequency counter for the character corresponding to the index value of the element:
frequencyData[str.charAt(i)]++; // (4)
The calls to the getChars()
method at (5) and (6) copy particular substrings from the string into designated places in the destination
array, before printing the whole character array.
We leave it as an exercise for the reader to implement a solution for character frequencies using a Map
(see Section 15.8, p. 821).
Characters are compared based on their Unicode values.
boolean test = 'a' < 'b'; // true since 0x61 < 0x62
Two strings are compared lexicographically, as in a dictionary or telephone directory, by successively comparing their corresponding characters at each position in the two strings, starting with the characters in the first position. The string "abba"
is less than "aha"
, since the second character 'b'
in the string "abba"
is less than the second character 'h'
in the string "aha"
. The characters in the first position in each of these strings are equal. See also The Comparator<E>
Interface, p. 771.
The following public methods can be used for comparing strings:
boolean equals(Object obj)
boolean equalsIgnoreCase(String str2)
The String
class overrides the equals()
method from the Object
class. The String
class equals()
method implements String
object value equality as two String
objects having the same sequence of characters. The equalsIgnoreCase()
method does the same, but ignores the case of the characters.
int compareTo(String str2)
The String
class implements the Comparable<String>
interface. The compareTo()
method compares the two strings and returns a value based on the outcome of the comparison:
• the value 0
, if this string is equal to the string argument
• a value less than 0
, if this string is lexicographically less than the string argument
• a value greater than 0
, if this string is lexicographically greater than the string argument
Here are some examples of string comparisons:
String strA = new String("The Case was thrown out of Court");
String strB = new String("the case was thrown out of court");
boolean b1 = strA.equals(strB); // false
boolean b2 = strA.equalsIgnoreCase(strB); // true
String str1 = new String("abba");
String str2 = new String("aha");
int compVal1 = str1.compareTo(str2); // negative value => str1 < str2
String toUpperCase()
String toUpperCase(Locale locale)
String toLowerCase()
String toLowerCase(Locale locale)
Note that the original string is returned if none of the characters need their case changed, but a new String
object is returned if any of the characters need their case changed. These methods delegate the character-by-character case conversion to corresponding methods from the Character
class.
These methods use the rules of the (default) locale (returned by the method Locale.getDefault()
), which embodies the idiosyncrasies of a specific geographical, political, or cultural region regarding number/date/currency formats, character classification, alphabet (including case idiosyncrasies), and other localizations (see Section 12.1, p. 532).
Example of case in strings:
String strA = new String("The Case was thrown out of Court");
String strB = new String("the case was thrown out of court");
String strC = strA.toLowerCase(); // Case conversion => New String object:
// "the case was thrown out of court"
String strD = strB.toLowerCase(); // No case conversion => Same String object
String strE = strA.toUpperCase(); // Case conversion => New String object:
// "THE CASE WAS THROWN OUT OF COURT"
boolean test1 = strC == strA; // false
boolean test2 = strD == strB; // true
boolean test3 = strE == strA; // false
Concatenation of two strings results in a string that consists of the characters of the first string followed by the characters of the second string. The overloaded operator +
for string concatenation is discussed in Section 5.6 on page 180. In addition, the following method can be used to concatenate two strings:
The concat()
method does not modify the String
object on which it is invoked, as String objects are immutable. Instead the concat()
method returns a reference to a brand new String
object:
String billboard = "Just";
billboard.concat(" lost in space."); // (1) Returned reference value not stored.
System.out.println(billboard); // (2) "Just"
billboard = billboard.concat(" advertise").concat(" here."); // (3) Chaining.
System.out.println(billboard); // (4) "Just advertise here."
At (1), the reference value of the String
object returned by the method concat()
is not stored. This String
object becomes inaccessible after (1). We see that the reference billboard
still denotes the string literal "Just"
at (2).
At (3), two method calls to the concat()
method are chained. The first call returns a reference value to a new String
object whose content is "Just advertise"
. The second method call is invoked on this String
object using the reference value that was returned in the first method call. The second call results in yet another String
object whose content is "Just advertise here."
. The reference value of this String
object is assigned to the reference billboard
. Because String
objects are immutable, the creation of the temporary String
object with the content "Just advertise"
is inevitable at (3).
The compiler uses a string builder to avoid this overhead of temporary String
objects when applying the string concatenation operator (p. 460).
A simple way to convert any primitive value to its string representation is by concatenating it with the empty string (""
), using the string concatenation operator (+
) (see also (6c) in Figure 10.2):
String strRepresentation = "" + 2008; // String conversion: "2008" <---- 2008
Application of the concatenation operator may result in string conversion being performed on one of the operands, as shown above. The string concatenation operator (+
) is discussed in Section 5.7, p. 185. Some more examples of string concatenation follow:
String motto = new String("Program once"); // (1)
motto += ", execute everywhere."; // (2)
motto = motto.concat(" Don't bet on it!"); // (3)
Note that a new String
object is assigned to the reference motto
each time in the assignment at (1), (2), and (3). The String
object with the contents "Program once"
becomes inaccessible after the assignment at (2). The String
object with the contents "Program once, execute everywhere."
becomes inaccessible after (3). The reference motto
denotes the String
object with the following contents after execution of the assignment at (3):
"Program once, execute everywhere. Don't bet on it!"
The following overloaded methods can be used to find the index of a character or the start index of a substring in a string. These methods search forward toward the end of the string. In other words, the index of the first occurrence of the character or substring is found. If the search is unsuccessful, the value –1 is returned.
int indexOf(int ch)
int indexOf(int ch, int fromIndex)
The first method finds the index of the first occurrence of the argument character in a string. The second method finds the index of the first occurrence of the argument character in a string, starting at the index specified in the second argument. If the index argument is negative, the index is assumed to be 0. If the index argument is greater than the length of the string, it is effectively considered to be equal to the length of the string; resulting in the value -1 being returned.
int indexOf(String str)
int indexOf(String str, int fromIndex)
The first method finds the start index of the first occurrence of the substring argument in a string. The second method finds the start index of the first occurrence of the substring argument in a string, starting at the index specified in the second argument.
The String
class also defines a set of methods that search for a character or a substring, but the search is backwards toward the start of the string. In other words, the index of the last occurrence of the character or substring is found.
int lastIndexOf(int ch)
int lastIndexOf(int ch, int fromIndex)
int lastIndexOf(String str)
int lastIndexOf(String str, int fromIndex)
The following methods can be used to create a string in which all occurrences of a character or a subsequence in a string have been replaced with another character or subsequence:
String replace(char oldChar, char newChar)
String replace(CharSequence target, CharSequence replacement)
The first method returns a new String
object that is a result of replacing all occurrences of the oldChar
in the current string with the newChar
. The current string is returned if no occurrences of the oldChar
can be found.
The second method returns a new String
object that is a result of replacing all occurrences of the character sequence target
in the current string with the character sequence replacement
. The current string is returned if no occurrences of the target
can be found.
boolean contains(CharSequence cs)
This method returns true
if the current string contains the specified character sequence, otherwise false
.
String funStr = "Java Jives";
// 0123456789
int jInd1a = funStr.indexOf('J'), // 0
int jInd1b = funStr.indexOf('J', 1); // 5
int jInd2a = funStr.lastIndexOf('J'), // 5
int jInd2b = funStr.lastIndexOf('J', 4); // 0
String banner = "One man, One vote";
// 01234567890123456
int subInd1a = banner.indexOf("One"); // 0
int subInd1b = banner.indexOf("One", 3); // 9
int subInd2a = banner.lastIndexOf("One"); // 9
int subInd2b = banner.lastIndexOf("One", 10); // 9
int subInd2c = banner.lastIndexOf("One", 8); // 0
int subInd2d = banner.lastIndexOf("One", 2); // 0
String newStr = funStr.replace('J', 'W'), // "Wava Wives"
String newBanner = banner.replace("One", "No"); // "No man, No vote"
boolean found1 = banner.contains("One"); // true
boolean found2 = newBanner.contains("One"); // false
String trim()
This method can be used to create a string where white space (in fact all characters with values less than or equal to the space character 'u0020'
) from the front (leading) and the end (trailing) of a string has been removed.
String substring(int startIndex)
String substring(int startIndex, int endIndex)
The String
class provides these overloaded methods to extract substrings from a string. A new String
object containing the substring is created and returned. The first method extracts the string that starts at the given index startIndex
and extends to the end of the string. The end of the substring can be specified by using a second argument endIndex
that is the index of the first character after the substring, i.e., the last character in the substring is at index endIndex-1
. If the index value is not valid, a StringIndexOutOfBoundsException
is thrown.
Examples of extracting substrings:
String utopia = "
Java Nation
";
utopia = utopia.trim(); // "Java Nation"
utopia = utopia.substring(5); // "Nation"
String radioactive = utopia.substring(3,6); // "ion"
The String
class overrides the toString()
method in the Object
class and returns the String
object itself:
String toString()
This method is defined in the CharSequence
interface which the String
class implements (p. 442).
The String
class also defines a set of static overloaded valueOf()
methods to convert objects and primitive values into strings.
static String valueOf(Object obj)
static String valueOf(char[] charArray)
static String valueOf(boolean b)
static String valueOf(char c)
All these methods return a string representing the given parameter value. A call to the method with the parameter obj
is equivalent to obj.toString()
. The boolean
values true
and false
are converted into the strings "true"
and "false"
. The char
parameter is converted to a string consisting of a single character.
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(float f)
static String valueOf(double d)
The static valueOf()
method that accepts a primitive value as argument is equivalent to the static toString()
method in the corresponding wrapper class for each of the primitive data types (see also (6a) and (6b) in Figure 10.2 on p. 393).
Note that there are no valueOf()
methods that accept a byte
or a short
.
Examples of string conversions:
String anonStr = String.valueOf("Make me a string."); // "Make me a string."
String charStr = String.valueOf(new char[] {'a', 'h', 'a'});// "aha"
String boolTrue = String.valueOf(true); // "true"
String doubleStr = String.valueOf(Math.PI); // "3.141592653589793"
The String class provides support for formatted text representation of primitive values and objects through its overloaded format()
methods. Formatting of values is covered extensively in Section 12.7, p. 593.
Methods for string pattern matching take an argument that specifies a regular expression (see Section 12.6, p. 554).
The following method attempts to match the current string against the specified regular expression. The call
str.matches(regexStr);
is equivalent to the call
Pattern.matches(regexStr, str);
See The java.util.regex.Pattern
Class, p. 562, for details.
The following methods can be used to replace substrings that match a given regular expression. The call
str.replaceFirst(regexStr, replacement);
is equivalent to the call
Pattern.compile(regexStr).matcher(str).replaceFirst(replacement);
See The java.util.regex.Matcher
Class, p. 570, for details.
String replaceFirst(String regexStr, String replacement)
String replaceAll(String regexStr, String replacement)
The first method returns a new String
by replacing the first substring of this string that matches the given regular expression with the given replacement.
The second method returns a new String
by replacing each substring of this string that matches the given regular expression with the given replacement.
The split()
method can be called on a string to create an array by splitting the string according to a regular expression pattern (see Section 12.6, p. 554). Given that the reference input
is of type String
, the call
input.split(regexStr,limit);
is equivalent to the call
Pattern.compile(regexStr).split(input, limit);
Splitting is covered in The java.util.regex.Pattern
Class, p. 563.
String[] split(String regexStr)
String[] split(String regexStr, int limit)
The method splits the current string around matches of the specified pattern. The limit determines how many times the pattern will be applied to the string to create the array.
Other miscellaneous methods exist for reading the string characters into an array of characters (toCharArray()
), converting the string into an array of bytes (getBytes()
), and searching for prefixes (startsWith()
) and suffixes (endsWith()
) of the string. The method hashCode()
can be used to compute a hash value based on the characters in the string.
10.12 Which of the following operators cannot have an operand of type String
?
Select the two correct answers.
(a) +
(b) -
(c) +=
(d) .
(e) &
10.13 Which expression will extract the substring "kap"
, given the following declaration:
String str = "kakapo";
Select the one correct answer.
(a) str.substring(2, 2)
(b) str.substring(2, 3)
(c) str.substring(2, 4)
(d) str.substring(2, 5)
(e) str.substring(3, 3)
10.14 What will be the result of attempting to compile and run the following code?
class MyClass {
public static void main(String[] args) {
String str1 = "str1";
String str2 = "str2";
String str3 = "str3";
str1.concat(str2);
System.out.println(str3.concat(str1));
}
}
Select the one correct answer.
(a) The code will fail to compile because the expression str3.concat(str1)
will not result in a valid argument for the println()
method.
(b) The program will print str3str1str2
, when run.
(c) The program will print str3
, when run.
(d) The program will print str3str1
, when run.
(e) The program will print str3str2
, when run.
10.15 Which statement about the trim()
method of the String
class is true?
Select the one correct answer.
(a) It returns a string where the leading white space of the original string has been removed.
(b) It returns a string where the trailing white space of the original string has been removed.
(c) It returns a string where both the leading and trailing white space of the original string has been removed.
(d) It returns a string where all the white space of the original string has been removed.
(e) None of the above.
10.16 Which statements are true?
Select the two correct answers.
(a) String
objects are immutable.
(b) Subclasses of the String
class can be mutable.
(c) All wrapper classes are declared final
.
(d) All objects have a public
method named clone
.
(e) The expression ((new StringBuilder()) instanceof String)
is always true
.
10.17 Which of these expressions are legal?
Select the four correct answers.
(a) "co".concat("ol")
(b) ("co" + "ol")
(c) ('c' + 'o' + 'o' + 'l')
(d) ("co" + new String('o' + 'l'))
(e) ("co" + new String("co"))
10.18 What will be the result of attempting to compile and run the following program?
public class RefEq {
public static void main(String[] args) {
String s = "ab" + "12";
String t = "ab" + 12;
String u = new String("ab12");
System.out.println((s==t) + " " + (s==u));
}
}
Select the one correct answer.
(a) The program will fail to compile.
(b) The program will print false false
, when run.
(c) The program will print false true
, when run.
(d) The program will print true false
, when run.
(e) The program will print true true
, when run.
10.19 Which of these parameter lists can be found in a constructor of the String
class?
Select the three correct answers.
(a) ()
(b) (int capacity)
(c) (char[] data)
(d) (String str)
10.20 Which method is not defined in the String
class?
Select the one correct answer.
(a) trim()
(b) length()
(c) concat(String)
(d) hashCode()
(e) reverse()
10.21 Which statement about the charAt()
method of the String
class is true?
Select the one correct answer.
(a) The charAt()
method takes a char
value as an argument.
(b) The charAt()
method returns a Character
object.
(c) The expression ("abcdef").charAt(3)
is illegal.
(d) The expression "abcdef".charAt(3)
evaluates to the character 'd'
.
(e) The index of the first character is 1.
10.22 Which expression will evaluate to true
?
Select the one correct answer.
(a) "hello: there!".equals("hello there")
(b) "HELLO THERE".equals("hello there")
(c) ("hello".concat("there")).equals("hello there")
(d) "Hello There".compareTo("hello there") == 0
(e) "Hello there".toLowerCase().equals("hello there")
10.23 What will the following program print when run?
public class Search {
public static void main(String[] args) {
String s = "Contentment!";
int middle = s.length()/2;
String nt = s.substring(middle-1, middle+1);
System.out.println(s.lastIndexOf(nt, middle));
}
}
Select the one correct answer.
(a) 2
(b) 4
(c) 5
(d) 7
(e) 9
(f) 11
10.24 What will the following program print when run?
public class Uppity {
public static void main(String[] args) {
String str1 = "lower", str2 = "LOWER", str3 = "UPPER";
str1.toUpperCase();
str1.replace("LOWER","UPPER");
System.out.println((str1.equals(str2)) + " " + (str1.equals(str3)));
}
}
Select the one correct answer.
(a) The program will print false true
.
(b) The program will print false false
.
(c) The program will print true false
.
(d) The program will print true true
.
(e) The program will fail to compile.
(f) The program will compile, but throw an exception at runtime.
10.25 What will the following program print when run?
public class FunCharSeq {
private static void putO(String s1) {
s1 = s1.trim();
s1 += "O";
}
public static void main(String[] args) {
String s1 = " W ";
putO(s1);
s1.concat("W");
System.out.println("|" + s1 + "|");
}
}
Select the one correct answer.
(a) |WOW|
(b) | WW |
(c) | WO |
(e) The program will fail to compile.
(f) The program will compile, but throw an exception at runtime.
The classes StringBuilder
and StringBuffer
implement mutable sequences of characters. Both classes support the same operations. However, the StringBuffer
class is the thread-safe analog of the StringBuilder
class. Certain operations on a string buffer are synchronized, so that when used by multiple threads, these operations are performed in an orderly way (see Section 13.5, p. 626). Note that a String
object is also thread-safe—because it is immutable, a thread cannot change its state. String builders are preferred when heavy modification of character sequences is involved and synchronization of operations is not important.
Although the rest of this section is about string builders, it is equally applicable to string buffers.
In contrast to the String
class, which implements immutable character sequences, the StringBuilder
class implements mutable character sequences. Not only can the character sequences in a string builder be changed, but the capacity of the string builder can also change dynamically. The capacity of a string builder is the maximum number of characters that a string builder can accommodate before its size is automatically augmented.
Although there is a close relationship between objects of the String
and StringBuilder
classes, these are two independent final
classes, both directly extending the Object
class. Hence, String
references cannot be stored (or cast) to StringBuilder
references, and vice versa.
The StringBuilder
class provides various facilities for manipulating string builders:
The final
class StringBuilder
provides four constructors that create and initialize StringBuilder
objects and set their initial capacity.
StringBuilder(String str)
StringBuilder(CharSequence charSeq)
The contents of the new StringBuilder
object are the same as the contents of the String
object or the character sequence passed as argument. The initial capacity of the string builder is set to the length of the argument sequence, plus room for 16 more characters.
StringBuilder(int length)
The new StringBuilder
object has no content. The initial capacity of the string builder is set to the value of the argument length
, which cannot be less than 0.
StringBuilder()
This constructor also creates a new StringBuilder
object with no content. The initial capacity of the string builder is set for 16 characters.
Examples of StringBuilder
object creation and initialization:
StringBuilder strBuilder1 = new StringBuilder("Phew!"); // "Phew!", capacity 21
StringBuilder strBuilder2 = new StringBuilder(10); // "", capacity 10
StringBuilder strBuilder3 = new StringBuilder(); // "", capacity 16
int length()
From the CharSequence
interface (p. 442).
Returns the number of characters in the string builder.
char charAt(int index) From the CharSequence
interface (p. 442).
void setCharAt(int index, char ch)
These methods read and change the character at a specified index in the string builder, respectively. The first character is at index 0 and the last one at index one less than the number of characters in the string builder. A StringIndexOutOfBoundsException
is thrown if the index is not valid.
CharSequence subSequence(int start, int end)
This method is implemented as part of the CharSequence
interface (p. 442).
The following is an example of reading and changing string builder contents:
StringBuilder strBuilder = new StringBuilder("Javv"); // "Javv", capacity 20
strBuilder.setCharAt(strBuilder.length()-1, strBuilder.charAt(1)); // "Java"
The StringBuilder
class overrides the toString()
method from the Object
class (see also the CharSequence
interface, p. 442). It returns the contents of a string builder in a String
object.
String fromBuilder = strBuilder.toString(); // "Java"
Since the StringBuilder
class does not override the equals()
method from the Object
class, nor does it implement the Comparable
interface, the contents of string builders should be converted to String
objects for string comparison.
The StringBuilder
class also does not override the hashCode()
method from the Object
class. Again, a string builder can be converted to a String
object in order to obtain a hash value.
Appending, inserting, and deleting characters automatically results in adjustment of the string builder’s capacity, if necessary. The indices passed as arguments in the methods must be equal to or greater than 0. A StringIndexOutOfBoundsException
is thrown if an index is not valid.
Note that the methods in this subsection return the reference value of the modified stringbuilder, making it convenient to chain calls to these methods.
The overloaded method append()
can be used to append characters at the end of a string builder.
StringBuilder append(Object obj)
The obj
argument is converted to a string as if by the static method call String.valueOf(obj)
, and this string is appended to the current string builder.
StringBuilder append(String str)
StringBuilder append(CharSequence charSeq)
StringBuilder append(CharSequence charSeq, int start, int end)
StringBuilder append(char[] charArray
StringBuilder append(char[] charArray, int offset, int length)
StringBuilder append(char c)
These methods allow characters from various sources to be appended to the end of the current string builder.
StringBuilder append(boolean b)
StringBuilder append(int i)
StringBuilder append(long l)
StringBuilder append(float f)
StringBuilder append(double d)
These methods convert the primitive value of the argument to a string by applying the static method String.valueOf()
to the argument, before appending the result to the string builder.
The overloaded method insert()
can be used to insert characters at a given position in a string builder.
StringBuilder insert(int offset, Object obj)
StringBuilder insert(int dstOffset, CharSequence seq)
StringBuilder insert(int dstOffset, CharSequence seq, int start, int end)
StringBuilder insert(int offset, String str)
StringBuilder insert(int offset, char[] charArray)
StringBuilder insert(int offset, char c)
StringBuilder insert(int offset, boolean b)
StringBuilder insert(int offset, int i)
StringBuilder insert(int offset, long l)
StringBuilder insert(int offset, float f)
StringBuilder insert(int offset, double d)
The argument is converted, if necessary, by applying the static method String.valueOf()
. The offset
argument specifies where the characters are to be inserted and must be greater than or equal to 0.
The following methods can be used to delete characters from specific positions in a string builder:
StringBuilder deleteCharAt(int index)
StringBuilder delete(int start, int end)
The first method deletes a character at a specified index in the string builder, contracting the string builder by one character. The second method deletes a substring, which is specified by the start
index (inclusive) and the end
index (exclusive).
Among other miscellaneous methods included in the class StringBuilder
is the following method, which reverses the contents of a string builder:
Examples of appending, inserting, and deleting in string builders:
StringBuilder builder = new StringBuilder("banana split"); // "banana split"
builder.delete(4,12); // "bana"
builder.append(42); // "bana42"
builder.insert(4,"na"); // "banana42"
builder.reverse(); // "24ananab"
builder.deleteCharAt(builder.length()-1); // "24anana"
builder.append('s'), // "24ananas"
All the previous methods modify the contents of the string builder and also return a reference value denoting the string builder. This allows chaining of method calls. The method calls invoked on the string builder denoted by the reference builder
can be chained as follows, giving the same result:
builder.delete(4,12).append(42).insert(4,"na").reverse().
deleteCharAt(builder.length()-1).append('s'), // "24ananas"
The method calls in the chain are evaluated from left to right, so that the previous chain of calls is interpreted as follows:
(((((builder.delete(4,12)).append(42)).insert(4,"na")).reverse()).
deleteCharAt(builder.length()-1)).append('s'), // "24ananas"
Each method call returns the reference value of the modified string builder. This value is used to invoke the next method. The string builder remains denoted by the reference builder
.
The compiler uses string builders to implement the string concatenation, +
. The following example code of string concatenation
String str1 = 4 + "U" + "Only"; // (1) "4UOnly"
is equivalent to the following code using one string builder:
String str2 = new StringBuilder().
append(4).append("U").append("Only").toString(); // (2)
The code at (2) does not create any temporary String
objects when concatenating several strings, since a single StringBuilder
object is modified and finally converted to a String
object.
int capacity()
Returns the current capacity of the string builder, i.e., the number of characters the current builder can accommodate without allocating a new, larger array to hold characters.
void ensureCapacity(int minCapacity)
Ensures that there is room for at least a minCapacity
number of characters. It expands the string builder, depending on the current capacity of the builder.
void trimToSize()
Attempts to reduce the storage used for the character sequence. It may affect the capacity of the string builder.
void setLength(int newLength)
This method ensures that the actual number of characters, i.e., the length of the string builder, is exactly equal to the value of the newLength
argument, which must be greater than or equal to 0. This operation can result in the string being truncated or padded with null characters ('u0000'
).
This method only affects the capacity of the string builder if the value of the parameter newLength
is greater than current capacity.
One use of this method is to clear the string builder:
builder.setLength(0); // Empty the builder.
10.26 What will be the result of attempting to compile and run the following program?
public class MyClass {
public static void main(String[] args) {
String s = "hello";
StringBuilder sb = new StringBuilder(s);
sb.reverse();
if (s == sb) System.out.println("a");
if (s.equals(sb)) System.out.println("b");
if (sb.equals(s)) System.out.println("c");
}
}
Select the one correct answer.
(a) The code will fail to compile because the constructor of the String
class is not called properly.
(b) The code will fail to compile because the expression (s == sb)
is illegal.
(c) The code will fail to compile because the expression (s.equals(sb))
is illegal.
(d) The program will print c
, when run.
(e) The program will throw a ClassCastException
, when run.
10.27 What will be the result of attempting to compile and run the following program?
public class MyClass {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("have a nice day");
sb.setLength(6);
System.out.println(sb);
}
}
Select the one correct answer.
(a) The code will fail to compile because there is no method named setLength
in the StringBuilder
class.
(b) The code will fail to compile because the StringBuilder
reference sb
is not a legal argument to the println()
method.
(c) The program will throw a StringIndexOutOfBoundsException
, when run.
(d) The program will print have a nice day
, when run.
(e) The program will print have a
, when run.
(f) The program will print ce day
, when run.
10.28 Which of these parameter lists can be found in a constructor of the StringBuilder
class?
Select the three correct answers.
(a) ()
(b) (int capacity)
(d) (String str)
10.29 Which method is not defined in the StringBuilder
class?
Select the one correct answer.
(a) trim()
(b) length()
(c) append(String)
(d) reverse()
(e) setLength(int)
10.30 What will be the result of attempting to compile and run the following program?
public class StringMethods {
public static void main(String[] args) {
String str = new String("eeny");
str.concat(" meeny");
StringBuilder strBuilder = new StringBuilder(" miny");
strBuilder.append(" mo");
System.out.println(str + strBuilder);
}
}
Select the one correct answer.
(a) The program will fail to compile.
(b) The program will print eeny meeny miny mo
, when run.
(c) The program will print meeny miny mo
, when run.
(d) The program will print eeny miny mo
, when run.
(e) The program will print eeny meeny miny
, when run.
10.31 What will the following program print when run?
public class PeskyCharSeq {
public static void main (String[] args) {
StringBuilder sb1 = new StringBuilder("WOW");
StringBuilder sb2 = new StringBuilder(sb1);
System.out.println((sb1==sb2) + " " + sb1.equals(sb2));
}
}
Select the one correct answer.
(a) The program will print false true
.
(b) The program will print false false
.
(c) The program will print true false
.
(d) The program will print true true
.
(e) The program will fail to compile.
(f) The program will compile, but throws an exception at runtime.
10.32 What will the following program print when run?
public class MoreCharSeq {
public static void main (String[] args) {
String s1 = "WOW";
StringBuilder s2 = new StringBuilder(s1);
String s3 = new String(s2);
System.out.println((s1.hashCode() == s2.hashCode()) + " " +
(s1.hashCode() == s3.hashCode()));
}
}
Select the one correct answer.
(a) The program will print false true
.
(b) The program will print false false
.
(c) The program will print true false
.
(d) The program will print true true
.
(e) The program will fail to compile.
(f) The program will compile, but throw an exception at runtime.
10.33 What will the following program print when run?
public class CharSeq {
public static void main (String[] args) {
String cs1 = "JAVA";
StringBuilder cs2 = new StringBuilder(cs1);
System.out.println(cs1.compareTo(cs2) == cs2.compareTo(cs1));
}
}
Select the one correct answer.
(a) The program will print false
.
(b) The program will print true
.
(c) The program will fail to compile.
(d) The program will compile, but throw an exception at runtime.
10.34 What will the following program print when run?
public class Appendage {
private static void putO(StringBuilder s1) {
s1 = s1.append("O");
}
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder("W");
putO(s1);
s1.append("W!");
System.out.println(s1);
}
}
Select the one correct answer.
(a) The program will print WW!
.
(b) The program will print WOW!
.
(c) The program will print W
.
(d) The program will fail to compile.
(e) The program will compile, but throw an exception at runtime.
10.35 What will the following program print when run?
public class Chains {
private static StringBuilder putO(StringBuilder s1) {
s1.append("O");
return s1;
}
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder("W");
boolean status = putO(s1).append("W!").toString().compareTo("WOW!") != 0;
System.out.println(s1 + " " + status);
}
}
Select the one correct answer.
(a) The program will print WOW! false
.
(b) The program will print WOW! true
.
(c) The program will print WW! true
.
(d) The program will fail to compile.
(e) The program will compile, but throw an exception at runtime.
The following information was included in this chapter:
• discussion of the Object
class, which is the most fundamental class in Java
• discussion of the wrapper classes, which not only allow primitive values to be treated as objects, but also contain useful methods for converting values
• discussion of the String
class, showing how immutable strings are created and used
• discussion of the StringBuilder
class, showing how dynamic strings are created and manipulated
• comparison of the String
, StringBuilder
, and StringBuffer
classes
10.1 Create a class named Pair
, which aggregates two arbitrary objects. Implement the equals()
and hashCode()
methods in such a way that a Pair
object is identical to another Pair
object if, and only if, the pair of constituent objects are identical. Make the toString()
implementation return the textual representation of both the constituent objects in a Pair
object. Objects of the Pair
class should be immutable.
10.2 A palindrome is a text phrase that is spelled the same backward and forward. The word redivider is a palindrome, since the word would be spelled the same even if the character sequence were reversed. Write a program that takes a string as an argument and reports whether the string is a palindrome.