Java Strings API - mariamaged/Java-Android-Kotlin GitHub Wiki
Java - Strings
4.1.1 Creating String Objects
You can create
objectsof theclassString by:
- Using the
newoperator.- Using String
literal values(values within double quotes).
- Let' create two String objects with the value "Paul" using the operator "new":
String st1 = new String("Paul");
String str2 = new String("Paul");
System.out.println(str1 == str2);
- Comparing the objects referred to by the variables str1 and str2 prints
false. - The operator == compares the
addressesof theobjectsreferred to by the variablesstr1andstr2. - Even thought these String objects store the same sequence of characters, they refer to
separate objectsstored atseparate locations.
- Let's initialize two String variables with the value "Harry" using the assignment operator (=):
String str3 = "Harry";
String str4 = "Harry";
System.out.println(str3 == str4);
- In the case of the variables
str3andstr4, the objects are created and stored in a pool of String objects. - Before creating a
new objectin the pool, Java searches for an object withsimilar contents. - When the following line executes, no String object with the value of "Harry" is found in the pool of String objects:
String str3 = "Harry";
- As a result, Java creates a String object with the value "Harry" in the pool of String objects referred to by the variable
str3.
- When the following line of code executes, Java is able to find a String object with the value "Harry" in the pool of String objects:
String str4 = "Harry";
- Java does not create a new String object in this case, and the variable
str4refers to the existing String object "Harry".
- You can create a String object by enclosing a value within double quotes ("):
System.out.println("Morning");
- These values are reused from the String constant pool if a
matching valueis found. - If a matching value is not found, the JVM creates a String object with the specified value and places it in the String constant pool.
String morning1 = "Morning";
System.out.println("Morning" == morning1); // Prints true.
- You can also
invokeother overloaded constructors of the classStringto create its objects by using the operatornew:
String girl = new String("Shreya"); // Constructor that takes a string.
char[] name = {'P', 'a', 'u', 'l');
String boy = new String(name); // Constructor that takes a char array.
- You can also create objects of String using the classes StringBuilder and StringBuffer.
StringBuilder sd1 = new StringBuilder("String Builder");
String str5 = new String(sdl);
StringBuffer sd2 = new StringBuffer("String Buffer");
String str6 = new String(sd2);
Note: Because String is a class, you can assign null to it.
The default value for String is null.
4.1.2 The class String is immutable
- Once created, the contents of an object of the class String
can never be modified. - The immutability of String objects helps the JVM reuse String objects,:
- Reducing memory overhead.
- Increasing performance.
- String objects can be shared across multiple reference variables without any
fear of changes in their values. - If the reference variables
strandstr2refer to the same String object value "Java",str1need not worry for its lifetime that the value "Java" might be changed through the variablestr2.
Implementation of String Immutability
- The class String stores its values in a
privatevariable of the type char arraychar[] value.- Arrays are fixed in size and don't grow once initialized.
- This value variable is marked as
finalin the class String.- Note that final is a
nonaccess modifier, and a final variable can be initialized once.
- Note that final is a
- Non of the methods defined in the class String manipulate the individual elements of the array value.
- The char array used by the class String is marked as private, which means that that is isn't accessible
outside the class for modification. - The class String itself doesn't modify the value of the variable either.
- All the methods defined in the class
String, such assubstring,concat,toLowerCase,toUpperCase,trim, and so on, which seem to modify the content of the String object on which they're called, create and return a new String object rather than modify the existing value.
4.1.3 Methods of the class String
charAt()
You can use the method charAt(int index) to retrieve a character at a specified index of a String:
String name = new String("Paul");
System.out.println(name.charAt(0)); // Prints P.
System.out.println(name.charAt(2)); // Prints a.
- Because the last character is placed at index 3, the following code will
throw an exceptionatruntime:
System.out.println(name.charAt(4));
- Runtime exception: is a
programming errordetermined by the Java Runtime Environment (JRE) during the execution of the code.
indexOf()
You can search a String for the occurrence of a
charor aString. If the specified char or String is found in the target String, this method returns thefirst matching position; otherwise, it returns-1.
By default, the indexOf() methods starts its search from the
first charof the target String.
If you wish, you can also set the
starting position.
String letters = "ABCAB";
System.out.println(letters.indexOf('B')); // Prints 1.
System.out.println(letters.indexOf("S")); // Prints -1.
System.out.println(letters.indexOf("CA")); // Prints 2.
System.out.println(letters.indexOf("B", 2)); // Prints 4.
substring()
- The first returns a substring of a String from the
position you specifyto theendof the String, as in the following example:
String exam = "Oracle";
String sub = exam.substring(2);
System.out.println(sub); // Prints acle.
- You can also specify the end position with this method:
String exam = "Oracle";
String result = exam.substring(2, 4);
System.out.println(result); // Prints ac.
- Here's a simple way to remember this rule:
- Length of
Stringreturned by substring() = end - start.
- Length of
trim()
The trim() method returns a new String by removing all the leading and trailing white space in a String.
White spaces are
blanks(new lines, space, or tabs).
String varWithSpaces = " AB CB ";
System.out.print(":");
System.out.print(varWithSpaces);
System.out.println(":");
// : AB CB :
System.out.print(":");
System.out.print(varWithSpaces.trim());
System.out.print(":");
// :AB CB:
replace()
This method will return a new String by replacing all occurrences of a char with another char.
Instead of a char to be replaced by another char, you can also specify a sequence of characters - a String to be replaced by another String.
String letters = "ABCAB";
System.out.println(letters.replace('B', 'b')); // Prints AbCAb
System.out.println(letters.replace("CA", "12")); // Prints AB12AB
- Notice the type of the method parameters passed on this method: either
charorString.- You can't miss these parameter types.
String letters = "ABCAB";
System.out.println(letters.replace('B', "b")); // Won't compile.
System.out.println(letters.replace("B", 'b')); // Won't compile.
length()
You can use the length() method to retrieve the length of a String.
System.out.println("Shreya".length()); // Prints 6.
startsWith() and endsWith()
The method startsWith() determines whether a String starts with a
specified prefix, specified as aString.
You can also specify whether you wish to search from the start of a String or from a particular position.
This method returns true if a match is found or false otherwise.
String letters = "ABCAB";
System.out.println(letters.startsWith("AB")); // Prints true.
System.out.println(letters.startsWith("a")); // Prints false.
System.out.println(letters.startsWith("A", 3)); // Prints true.
The method endsWith() tests whether a String ends with a particular suffix.
It returns true for a matching value and false otherwise.
System.out.println(letters.endsWith("CAB")); // Prints true.
System.out.println(letters.endsWith("B")); // Prints true.
System.out.println(letters.endsWith("b")); // Prints false.
Method Chaining
It is a common practice to use multiple String methods in a single line of code:
String result = "Sunday ".replace(' ', 'Z').trim().concat("M n");
System.out.println(result); // Prints SundayZZM N
- These methods are evaluated from
left to right.
4.1.4 String objects and Operators
- Concatenation operators (+ and +=) have a special meaning for
Strings. - Behind the scenes, string concatenation is implemented by using the StringBuilder or StringBuffer classes.
- But remember that a string is immutable.
String aString = "OCJA" + "Cert" + "Exam"; // String that contains OCJACertExam.
int num = 10;
int val = 12;
String aStr = "OCJA";
String anotherStr = num + val + aStr;
System.out.println(anotherStr); // Prints 22OCJA not 1012OCJA.
- The expression (num + val + aStr) is evaluated from left to right.
- Here's the sequence of steps executed by Java to execute the expression:
- Add operands num and val to get 22.
- Concatenate 22 with OCJA to get 220CJA.
- If you wish to treat the numbers stored in variables num and val as String values, modify the expression as follows:
String anotherStr = "" + num + val + aStr; // Evaluates to 10120CJA.
- When you use += to concatenate String values, ensure that the variable you are using has been initialized (and does not contain null).
String lang = "Java";
lang += " is everywhere";
String initializedToNull = null;
initializedToNull += "Java";
System.out.println(initializedToNull); // Prints nullJava.
4.1.5 Determining Equality of Strings
- The correct way to compare two String values for equality is to use the
equals()method defined in the String class. - This method returns a
truevalue if the object being compared to:- Is not null.
- Is a String object.
- Represents the same sequence of characters as the object to which it is being compared.
Equals Method
public boolean equals(Object anObject) {
if(this == anObject) return true;
if(anObject instanceOf String) {
String anotherString = (String) anObject;
int n = count;
if(n == anotherString.count) {
char[] v1 = value;
char[] v2 = anotherString.value;
int i = offset;
int j = anotherString.offset;
while(n-- != 0) {
if(v1[i++] != v2[j++]) return false;
}
return true;
}
}
return false;
}
4.2 Mutable Strings: StringBuilder
The class StringBuilder is defined in the package
java.lang, and it has amutablesequence of characters.
- You should use the class StringBuilder when:
- You're dealing with larger strings.
- You're modifying the contents of a string often.
- Doing so will improve the
performance of your code. - Unlike StringBuilder, the String class has an immutable sequence of characters.
- Every time you modify a string that's represented by the String class, your code creates new String objects instead of modifying the existing one.
4.2.1 The StringBuilder class is mutable
- In contrast to the class
String, the classStringBuilderuses a non-final char array to store its value. - Following is a partial definition of the class
AbstractStringBuilder(the superclass of the classStringBuilder). - It includes the declaration of the variables:
valuewhich is used to store the value of the string.countwhich is used to store the length of the string.
4.2.2 Creating StringBuilder objects
- You can create objects of the class StringBuilder using multiple overloaded constructors, as follows:
class CreateStringBuilderObjects {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder(sb1);
StringBuilder sb3 = new StringBuilder(50); // Constructor that accepts an int value specifying initial capacity of StringBuilder object.
StringBuilder sb4 = new StringBuilder("Shreya Gupta"); // Constructor that accepts a String.
}
}
- When you create a StringBuilder object using its
default constructor, the following code executes behind the scenes to initialize the arrayvaluedefined in the StringBuilder itself.
public StringBuilder() {
this.value = new char[16];
}
- When you create a StringBuilder by passing it a String, the following code executes behind the scenes to initialize the array value:
public StringBuilder(String str) {
this.value = new char[str.length() + 16];
this.append(str);
}
- When you create a StringBuilder by passing it an integer:
public StringBuilder(int x) {
this.value = new char[x];
}
4.2.3 Methods of class StringBuilder
append()
The append method add the specified value at the
endof the existing value of a StringBuilder object.
- Because you may want to add data from
multiple data typesto a StringBuilder object, this method has been overloaded so that it can accept data of any type.
- This method accepts
all the primitives,String,char array, andObject, as method parameters, as shown in the following example:
class AppendStringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder();
sb1.append(true); // Appends boolean.
sb1.append(10); // Appends int.
sb1.append('a'); // Appends char.
sb1.append(20.99); // Appends double.
sb1.append("Hi"); // Appends String.
System.out.println(sb1); // Prints true10a20.99Hi.
}
}
- You can append a complete
char array,StringBuilder, orStringor its subset as follows:
StringBuilder sb1 = new StringBuidler();
char[] name = {'J', 'a', 'v', 'a', '8'};
sb1.append(name, 1, 3); // Starting with position 1 append 3 characters, position 1 inclusive.
System.out.println(sb1); // Prints ava.
- Because the method append also accepts a method parameter of type
Object, you can pass it any object from theJava APIor yourown user-defined object:
class AppendStringBuilder2 {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder();
sb1.append("Java");
sb1.append(new Person("Oracle")); // Append object of class Person.
System.out.println(sb1);
}
}
class Person {
String name;
Person(String str) {this.name = str;}
}
- The output of the previous code is:
- When you append an object's value to a StringBuilder, the method append calls the static String.valueOf() method.
- The version taking an
Objectparameter:- Returns the four-letter string "null" if the parameter is null.
- Otherwise, it calls its
toString()method. - If the
toString()method has been overriden by the class, then the method append adds the String value returned by it to the target StringBuilder object. - In the absence of the overriden
toStringmethod, thetoString()in the class Object executes.- For your information, the
default implementationof the method toString() in the class Object:- Returns the name of the class.
- Followed by the
@char. - And
unsigned hexadecimal representationof thehashcodeof the object (the value returned by the object's hashCode() method).
- For your information, the
append implementation
public AbstractStringBuilder append(boolean b) {
if(b) {
int newCount = count + 4;
if(newCount > value.length) expandCapacity(newCount);
value[count++] = 't';
value[count++] = 'r';
value[count++] = 'u';
value[count++] = 'e';
}
else {
int newCount = count + 4;
if(newCount > value.length) expandCapacity(newCount);
value[count++] = 'f';
value[count++] = 'a';
value[count++] = 'l';
value[count++] = 's';
value[count++] = 'e';
}
}
Insert
- The insert method is as powerful as the append method.
- It also exists in multiple flavors (read: overloaded method) that accept any data type.
- The main difference between the
appendandinsertmethods is that:- The insert method enables you to insert the requested data at a
particular position. - The append method allows you add the requested data only at the
endof the StringBuilder object.
- The insert method enables you to insert the requested data at a
class InsertStringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("Bon");
sb1.insert(2, 'r');
System.out.println(sb1); // Prints Born.
}
}
- You can also insert a complete
char array,StringBuffer,orStringor its subset, as follows:
StringBuilder sb1 = new StringBuilder("123");
char[] name = {'J', 'a', 'v', 'a'};
sb1.insert(1, name, 1, 3);
System.out.println(sb1); // Prints 1ava23.
delete() and deleteCharAt()
The method delete removes the characters in a substring of the specified StringBuilder.
The method deleteCharAt removes the char at the specified position.
class DeleteStringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("0123456");
sb1.delete(2, 4);
System.out.println(sb1); // Prints 01456.
}
}
class DeleteStringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("0123456");
sb1.deleteCharAt(2);
System.out.println(sb1); // Prints 013456.
}
}
trim()
Unlike the class String, the class StringBuilder doesn't define the method
trim().
An attempt to use it with this class will
preventyour code fromcompiling.
reverse()
As the name suggests, the reverse method reverses the sequence of characters of a StringBuilder.
- You can't use the method
reverseto reverse asubstringof StringBuilder.
class ReverseStringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("0123456");
sb1.reverse();
System.out.println(sb1); // Prints 6543210.
}
}
replace()
Unlike the replace method defined in the class String, the replace method in the class StringBuilder replaces a
sequence of characters, identified by theirpositions, with anotherString, as in the following example:
class ReplaceStringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("0123456");
sb1.replace(2, 4, "ABCD");
System.out.println(sb1); // Prints 01ABCD456.
}
}
subSequence()
Apart from the method
substring, you can also use the method subSequence to retrieve a sequence of a StringBuilder object.
- This method returns objects of type
CharSequence. - This method
does not modifythe existing value of a StringBuilder.
class SubSequenceStringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("0123456");
System.out.println(sb1.subSequence(2, 4)); // Prints 23.
System.out.println(sb1); // Prints 0123456.
}
}
A quick note on StringBuffer
- The classes StringBuffer and StringBuilder offer the
same functionality, with one difference:- The
methodsof the class StringBuffer aresynchronizedwhere necessary, whereas the methods of the class StringBuilder aren't.
- The
- When you work with the class StringBuffer,
only one threadout of multiple threads can execute your method. - This arrangement prevents any
inconsistenciesin the value of the instance variables that are modified by these (synchronized) methods. - But it introduces
additional overhead, so working with synchronized methods and the StringBufferaffects the performanceof your code.