Overview
Introduction
Creating a String
Operations on Strings
StringBuffer & StringBuilder
Top 10 Problems on Strings
Introduction
A String is nothing but just a sequence of characters. A Character may be an alphabet, a digit or any other character.
Strings in Java are reference-type objects, that are immutable. An immutable object cannot be changed once it has been declared. In Java, Strings should be surrounded by "double quotes".
Creating a String
There are 2 ways to create a string in Java.
String literal
String Object
String literal
String str = "Hello World";
In the above statement, we have created a String called ‘str’ with the value “Hello World” in it. While evaluating this statement, Java would first evaluate the right part of the statement and creates a String literal with the value “Hello World”. This string literal is created in a special place in heap memory that is known as the “String Constant Pool” or SCP. Once it has created the string literal, then it will create a variable with the name str in the stack memory that will hold the address of the newly created string literal.
Let's say, If we create another string with the same value,
String anotherStr = "Hello World";
Since the string “Hello World” already exists in the string constant pool, Java would not create another string literal, but will directly create a variable named “anotherStr” that would point to the same String literal. This is done for effective memory utilization.
If we were to compare Strings using the equality operator str == anotherStr
then, it would return us true, Since both the strings are holding the same memory address.
Note - It is not a correct way to check the equality of strings using the equality operator.
String Object
String str = new String("Hello World");
Same as before, Java would evaluate the right part of the statement and would create a String object inside the heap memory with the value “Hello World”. After the creation of a string object, It would create a variable named str in the stack memory that would point to the string object.
Let's say, If we create another string with the same value,
String anotherStr = new String("Hello World");
Unlike String literal, if we would create another string object with the same value, then Java would create another string object which will get referenced by the “anotherStr” variable.
Here, If we were to compare Strings using the equality operator str == anotherStr
then, it would return false. Since both variables are holding different memory addresses.
Multi-line Strings
To create multi-line strings we can use triple double quotes. In the below code, we have created a multi-line string.
String str = """
This is
a multi-line String
example""";
Operations on Strings
Since Strings are immutable, No operations on them would modify the original string but would rather return the modified string.
Concatenating Strings.
We can concatenate String using any of the below ways
String str = "The Quick Brown ";
String anotherStr = "Quick Fox";
System.out.println(str + " " + anotherStr);
System.out.println(str.concat(" ".concat(anotherStr)));
System.out.printf("%s %s", str, anotherStr);
// All of them will provide the same output
The Quick Brown Quick Fox
Another way to concatenate strings is using StringBuilder or StringBuffer
Converting to UPPERCASE or lowercase.
Methods | Description |
str.toLowerCase() | Converts a string into lowercase |
str.toUpperCase() | Converts a string into UPPERCASE |
String str = "This is a String";
System.out.println(str.toUpperCase()); // THIS IS A STRING
System.out.println(str.toLowerCase()); // this is a string
Validation on Strings.
Method | Description |
str.startsWith(String s) | Returns true if the string str starts with the string s |
str.endsWith(String s) | Returns true if the string str ends with the string s |
str.contains(String s) | Returns true if the string str contains the string s |
str.isBlank() | Returns true if the string str is blank |
str.isEmpty() | Returns true if the string str is empty |
String str = "The Quick Brown Quick";
System.out.println(str.startsWith("The")); // true
System.out.println(str.startsWith("Quick", 5)); // false
System.out.println(str.endsWith("Quick")); // true
System.out.println(str.contains("Quick")); // true
In startsWith()
we can optionally provide an int offset
to skip the offset number of chars from the start.
String emptyStr = "";
String blankStr = " ";
System.out.println(emptyStr.isBlank()); // true
System.out.println(emptyStr.isEmpty()); // true
System.out.println(blankStr.isBlank()); // true
System.out.println(blankStr.isEmpty()); // false
Locating a Character by its index.
str.charAt(5)
- Returns a character that is at the index 5 in the string str.
If the index provided is negative or larger than the string size then this method would throw a StringIndexOutOfBoundsException.
String str = "The Quick Brown Fox";
System.out.println(str.charAt(4)); // Q
Finding the occurrence of a Char or String.
Method | Description |
str.indexOf(String s) | Returns the index of the first occurrence of a String s |
str.indexOf(Char ch) | Returns the index of the first occurrence of a Char ch |
str.lastIndexOf(String s) | Returns the index of the last occurrence of a String s |
str.lastIndexOf(Char s) | Returns the index of the last occurrence of a character ch |
In case of indexOf()
we can also provide an int fromIndex
as a 2nd parameter. If provided Java would start the search from the fromIndex. If not provided the default value would be 0.
Similarly, lastIndexOf()
can also have an int fromIndex
as a 2nd parameter, but here fromIndex
is the index counted from the end of the String. If not provided the default value would be the length of the string.
Refer above diagram to understand the below code
String str = "The Quick Brown Quick";
System.out.println(str.indexOf('Q')); // 4
System.out.println(str.indexOf("Quick")); // 4
System.out.println(str.indexOf('Q', 5)); // 16
System.out.println(str.indexOf("Quick", 5)); // 16
System.out.println(str.lastIndexOf('Q')); // 16
System.out.println(str.lastIndexOf("Quick")); // 16
System.out.println(str.lastIndexOf('B', 12)); // 10
System.out.println(str.lastIndexOf("Quick", 12)); // 4
Splitting a String
str.split(String regex)
- Returns an array of Strings after splitting them based on the regex pattern
String str = "The Quick Brown Quick";
String[] spilittedString = str.split(" ");
System.out.println(Arrays.toString(spilittedString));
// Output -
[The, Quick, Brown, Quick]
Replacing or Extracting a Substring.
Method | Description |
str.replace(CharSequence target, CharSequence replacement) | Returns a string after replacing the target with the replacement String |
str.replaceAll(String regex, String replacement) | Replace all the string that matches the pattern regex with the replacement String |
str.substring(int beginIndex) | Returns a substring starting from the beginIndex |
String str = "The Quick Brown Quick";
System.out.println(str.replace("Quick", "Brown"));
System.out.println(str.replaceAll("[a-z]", "*"));
// Replace all small case letters with *
System.out.println(str.replaceFirst("Quick", "Brown"));
System.out.println(str.substring(0, 10));
System.out.println(str.substring(10));
// Output
The Brown Brown Brown
T** Q**** B**** Q****
The Brown Brown Quick
The Quick
Brown Quick
Removing trailing & leading spaces.
Methods | Description |
str.trim() | Removes all the leading and trailing spaces |
str.strip() | Removes all the leading and trailing spaces. A newer method that takes into account different kinds of white spaces. |
str.stripLeading() | Removes all the leading spaces |
str.stripTrailing() | Removes all the trailing spaces |
str.stripIndent() | Shifts a multi-line string to the leftmost possible position |
String str = " Hello World! ";
System.out.println(str.strip()); // Hello World!
System.out.println(str.trim()); // Hello World!
System.out.println(str.stripLeading()); // Hello World!
System.out.println(str.stripTrailing()); // Hello World!
The output of the methods is written next to them in a comment.
strip() vs trim()
strip()
is a newer method that considers all kinds of white spaces. \u2000 is a kind of white space in Unicode encoding
String str = "\u2000\u2000\u2000Hello World";
System.out.println(str); // Hello World
System.out.println(str.trim()); // Hello World
System.out.println(str.strip()); // Hello World
Comparing String
| Returns |
| Returns true if |
| Returns true if |
The difference between equals()
and contentEquals()
is that equals() would only accept Strings whereas contentEquals()
is more flexible and can take StringBuffer or CharSequence
String str = "ABC";
String anotherStr = "XYZ";
System.out.println(str.compareTo(anotherStr)); //-23
System.out.println(str.compareTo(str)); // 0
System.out.println(anotherStr.compareTo(str)); // 23
String str = "The Quick Brown Quick";
String anotherStr = "The Quick Brown Quick";
System.out.println(str.equals(anotherStr)); // true
System.out.println(str.contentEquals(anotherStr)); // true
StringBuffer & StringBuilder
Strings are immutable and fixed in size. To create a mutable and growable string we can use StringBuilder & StringBuffer Class.
StringBuffer stringBuffer = new StringBuffer("The ");
stringBuffer.append("Quick ")
.append("Brown ")
.append("Fox");
System.out.println(stringBuffer);
StringBuilder stringBuilder = new StringBuilder("The ");
stringBuilder.append("Quick ")
.append("Brown ")
.append("Fox");
System.out.println(stringBuilder);
Instead of supplying a String while creating a StringBuilder/StringBuffer object, we can also supply the initial capacity of the string that we are planning to create. StringBuilder stringBuilder = new StringBuilder(10);
Same as Strings we have many methods declared on them. One of the methods to know about is stringBuilder.reverse()
. This would reverse the entire String.
StringBuilder stringBuilder = new StringBuilder("Quick Brown Fox");
System.out.println(stringBuilder.reverse());
// Output
xoF nworB kciuQ
StringBuffer vs StringBuilder
At first, we only had StringBuffer Class to create growable Strings. StringBuffer is a thread-safe & synchronized class and hence it requires some extra validation that reduces its performance and makes it slower. StringBuilder Class was introduced as a non-thread-safe and non-synchronized class making it faster than the StringBuffer class.
In conclusion,
StringBuffer - Thread-safe, synchronized but slower
StringBuilder - Not thread-safe, not synchronized but faster