Strings in Java vs Strings in C++
Learn via video course
Overview
A String in Java is basically an object that represents a sequence of characters. Java implements strings as objects and it has extensive string-handling capabilities such as compare(), concat(), equals(), split(), length(), etc. The java.lang.String class implements Serializable, Comparable and CharSequence interfaces.
A string in C++ is an object of std::string class implemented in the Standard Template Library (STL). It represents a collection or sequence of various characters. The string class stores the characters as a collection of bytes in contiguous memory locations.
Scope of Article
This article aims to:
- Explain the concept of String immutability in Java
- Illustrate multiple ways to initialize strings in Java
- Demonstrate the various methods provided by the String class in Java
- Strings in C++, using C-Style char arrays and using std::string class
- Demonstrate the various string methods available in C++
- Comparison between strings in Java and strings in C++.
Introduction
Strings in Java and C++ are a sequence of characters. Java implements strings as objects of the String class, which is present in the java.lang package. In Java, strings can be declared as string literals as well using quotes. C++ has two ways of representing strings. The first one is using a character array and the second one is using objects of std::string class implemented in the Standard Template Library.
What are Java Strings
Java implements strings as objects of String Class. Strings in Java can be constructed in multiple ways, depending on their use. Each quoted stream of characters is a String literal. String literals are stored in a common pool known as String Pool in Java. This facilitates the sharing of storage for strings with the same contents to save memory. An array of characters works the same as Java strings.
Another way to declare strings in Java is by creating objects of String class using the new operator. Instances of Java String class are stored in the heap memory.
Strings in Java are immutable i.e. they cannot be changed once initialized. The String objects in Java are cached in the String Constant Pool, and this is one of the possible reasons for making Strings immutable in Java. Strings are immutable in Java due to various other reasons such as synchronization, security, caching, etc.
Let us discuss an example to better understand the concept of immutability in Java.
The statement given above creates a string Welcome in the String Pool and assigns it to the reference variable str1. Now, let us create another reference variable, str2.
The str2 variable holds the same reference to Welcome as str1. Now, if we change str2 such that:
It modifies the value of str2. But strings are immutable, right?
- It is important to understand here that the Welcome string in the constant pool is not modified as a result of this operation.
- As a result of this operation, JVM creates a new String literal with the value Welcome Home! and assigns its reference to str2.
- Hence, none of the existing strings are modified. Only the reference variables are changed. str2 now points to Welcome Home! instead of Welcome.
- str1 still points to Welcome in the pool. Interestingly, there are now three strings in the string constant pool: Welcome, Welcome Home! and Home!
Now, consider the below statement.
As we change str1 to Hello! and new object with this value is created and str1 points to this literal in the String Pool. As we can observe none of the strings points to Welcome, it is detected by the garbage collector, and memory is restored.
Where a modifiable string is required we use the StringBuffer class. Its objects can be modified and do not require creating a new object. Thus, the StringBuffer class modifies the string in less time complexity than the String class.
Note:
Both the String and StringBuffer classes are defined in java.lang package.
Strings in Java can be initialized in multiple ways
Creating an object of String class
We create an object of string class using the new keyword.
Syntax:
Example:
Output:
Explanation:
- The above program creates two objects, one in the heap memory and one in the string constant pool to hold the "Hello" string.
- The reference to the object in the heap memory is assigned to the reference variable s.
Using Double quotes
Strings can also be directly created by writing the stream of characters between double-quotes.
Syntax:
Example:
Output:
Explanation:
- Here a string "Hello" is created in the string constant pool and its reference is assigned to the variable s.
- In this example, no object is created in the heap memory.
Using character Array
We can initialize a string by passing a character array as a parameter while creating an object of String class.
Syntax:
We can also specify the offset and the length of the character array to convert to an string. If the offset is s and length is l, the string consists of all the characters in the array from index s to s + l - 1. Throws StringIndexOutOfBoundsException if s + l - 1 is out of bounds.
Syntax:
Example:
Output:
StringIndexOutOfBoundsException Example:
Output:
Using ASCII Characters
We can also use an array of bytes to create a string. Again we pass byte array as a parameter. We can also mention starting index(offset) and the number of characters to include(length) from the array.
Syntax:
Example:
Output:
stringObj takes all the bytes and converts and combines to get a string as ABCDEF.
Operations on Java Strings
Java has a number of string methods to concatenate two strings, search for a substring, compare two strings, change the case of letters of a string, etc. Some of the basic operations that can be performed on Java Strings are given below:
Method | Description |
---|---|
str.length() | returns the length of the specified string. |
str1.concat(str2) | Appends str2 to the end of str1. |
str1.equals(str2) | Checks if all the characters of str1 and str2 are equal. If they are equal, it returns true else it returns false. |
str1.contains(str2) | Returns true if str1 contains str2 as a substring else returns false. |
str.substring(int start) | Returns the substring of str1 from the given start index to the end of the string. |
str.substring(int start, int end) | Returns the substring of the starting from start index and ending at end-1 index. |
str.replace(char oldChar, char newChar) | Returns a new string replacing all occurrences of oldChar with newChar in str. |
str.charAt(int index) | Returns the character present at the specified index in str. |
str1.compareTo(str2) | Compares two strings lexicographically. Returns 0 if both are equal, a negative number if str2 is greater and a positive number if str1 is greater. |
str.trim() | Removes all leading and trailing whitespaces. |
str.toLowerCase() | Converts all the characters of str to lowercase. |
str.toUpperCase() | Converts all the characters of str to uppercase. |
str.valueOf() | Returns the string representation of the specified value. |
str.toCharArray() | Returns character array representation of the given string. |
str1.startsWith(str2) | Returns true if str1 begins with the given string str2 else returns false. |
str1.endsWith(str2) | Returns true if the str1 ends with the given string str2 else returns false. |
str.isEmpty() | Returns true if the given string is empty. |
Let us now see an example performing a few methods mentioned above.
Example:
Output:
Explanation:
- In the example above, str1 and str2 are initialized as Butterfly and Beautiful respectively.
- length() returns the length of the number of characters in the str1 i.e. 9.
- concat() combines str1 and str2 and returns ButterflyBeautiful.
- equals() returns true if str1 and str2 have same characters and hence, it returns false.
- contains() returns true as str1 has a substring fly in it.
- substring(3) method returns terfly as this is the substring of str1 from index 3.
- substring(2, 5) returns substring of str1 starting from index 2 to index 4 i.e tte.
- replace() replaces all the t with # in str1.
- compare() compares str1 and str2, since it returns a positive number this implies str1 is greater than str2 in lexographical order.
More Examples:
Output:
What are Strings in C++
String in C++ is a way of representing and working with texts and characters. It has two different ways to represent strings: One of them is derived from the C language, which uses character arrays to represent strings. Another one is using objects of standard string class i.e. std::string class defined in C++ STL.
C-Style Character String
The C-style character string is derived from the C programming language to C++. It is can be thought of as a one-dimensional character array that holds a character sequence and is terminated by the null character \0, which signifies that the string has ended.
To initialize and declare C-Style string using Character Array:
Syntax:
When we create a character array, we can either mention each character separately or enter the stream of characters between double-quotes.
For Example:
Output:
Explanation:
- In the example, gm and greet are character arrays of sizes 6 and 25, respectively.
- greet is initialized by creating character array {'H', 'e', 'l', 'l', 'o', '\0'}. \0 is a null character that denotes the termination of the string. gm is initialized using double-quotes.
- It takes null characters implicitly.
What if we don't provide the null character?
In the program above, we explicitly mentioned null character at the end of greet array. However, when the size of the array(which is 6 in this case) is greater than the number of characters within curly braces, the C language implicitly fills the remaining places with the null character.
Example:
Now, consider the following case where the number of characters inside the curly braces is equal to the size of the array. In this case, we cannot determine the end point of greet array and other characters in contiguous memory blocks can also be counted.
Example:
Output:
Explanation:
- We cannot determine the end of the greet char array.
- Since gm characters are present in contiguous memory locations, they are also assumed to be part of the greet char array.
Since char is a primitive data type, strings in C-Style are derived from characters as an array of characters that can be terminated by a null character \0 or are character sequences enclosed within double-quotes.
As we are using an array, its size is supposed to be allocated statically during declaration. The memory to the character array is allocated, and it cannot be modified at runtime. It is faster than the string class as we directly use a character array for strings.
String Class
The C++ language, in its definition, has a way to represent a stream of characters as an object of a class known as std:: string. The string class is based on the OOPs concept. It enables the user to represent the string as an object of the C++ String class(std::string).
To initialize and declare strings using std::string class:
Syntax:
We create an object of string class. Here we do not need to mention size of the string while declaring it.
Example:
Output:
Important Points
Dynamic Memory Allocation
C++ string objects perform automatic allocation and deallocation of memory blocks. The memory management is performed explicitly by constructor methods, assignment operators, and destructors. Thus objects of string class are mutable implying that they can be modified irrespective of the initial size of the string.
For instance, if some string was previously of size 15 while the capacity of the array was 22. Now it is initialized to a new value which is 40 characters long.
The memory management system will allocate a new memory block of size 40 and capacity equal to or greater than 40. The pointer will point to this new array, and the memory blocked by the old array will be restored.
No Array Decay
Array decay is the loss of dimensions or type of the array, and it occurs when we pass the array by value or as a pointer into a function.
As we are using an object of string class instead of an array, it reduces the threat of array decay as compared to C-style strings. As memory allocation is dynamic, it allows manifold operations on strings.
Operations on C++ Strings
Function | Description |
---|---|
strcpy(str1, str2) | Copies all the characters of str2 to str1. Returns a pointer to str1 |
strcat(str1, str2) | Appends str2 at the end of str1. Returns a char pointer pointing to the first character of str1. |
strlen(str1) | Returns the size of str1. |
strcmp(str1, str2) | Compares str1 and str2, if they are equals it returns 0, if str1 is greater than str2, it returns a positive number else returns a negative number. |
strchr(str1, char) | Returns a pointer pointing to the first appearance of character char in str1 or null if not found. |
strrchr(str1, char) | Returns a pointer pointing to the last appearance of character char in str1 or null if not found. |
strstr(str1, str2) | Returns the pointer pointing to the first appearance of str2 in str1. |
strncat(str1, str2, n) | Appends first n characters of str2 at the end of str1. |
strncpy(str1, str2, n) | Copies first n characters of str2 into str1. |
strset(str1, ch) | Sets all the characters of str1 to ch. |
strnset(str1, ch, n) | Sets first n characters of str1 to ch. |
getline(istream& is, string& str) | Takes a stream of characters as input from the user, in the object memory. |
str.push_back(ch) | Adds the character ch at the end of str. |
str.pop_back() | Deletes the last character of str. |
str.begin() | An iterator to the beginning of the given string. Does not return any thing. |
str.capacity() | Returns the size of the currently allocated space for the string. |
str.resize(n) | Changes the capacity of the string to n. |
str.length() | Returns the length of the string str. |
Example:
Output:
Explanation:
- In the above example str1 and str2 are character arrays with ice and cream as values, respectively.
- strcat() combines str1 and str2 and gives the output as icecream also str1 is concat of both the strings i.e. icecream.
- strlen() returns the number of characters in str2 i.e. 5.
- strcmp() returns a positive number as ice is lexicographically greater than cream.
- strchr() returns all the characters starting from first c in str1.
- strrchr() returns all the characters starting from the last appearance of the character e. Thus, it returns eam.
- strcpy() copies the str1 to str2 and str2 becomes icecream.
More Examples:
Output:
- In the example, we ask for a string and store it in str.
- getline() takes the stream of characters until \0 null is found. It is stored in str.
- push_back() pushes '*' at the end of the str, str becomes Scaler*.
- pop_back() pops the last character from str and str again becomes Scaler.
- length() returns the initialized size of the string; here, it is 10.
- resize() changes the size of the string explicitly, and now the length of the string is 23.
Difference Between Strings in Java vs. Strings in CPP
Java String | std::string class in C++ | C-Style String in C++ |
---|---|---|
String is an object of String Class. | String is Object of std::string Class. | String is a character array. |
Strings are immutable, i.e. they cannot be changed once initialized. | Strings are mutable i.e. they can be changed after initialization. | Strings are immutable as we are using an array to represent them. |
String in Java is slower when modified as compared to the StringBuffer class. | C++ string class in STL are slower in implementation than Strings declared using character array. | Strings are faster in implementations as compared to the String class of C++. |
Memory allocation is static as strings are immutable. | Memory allocation is dynamic as we don't have to mention the size of the string. | Memory allocation is static as the size of the character array is to be mentioned during the declaration. |
Strings values can be changed to any size, irrespective of the size of the old value. | Strings can be modified to any other value. | It can be updated, but the size of the new string should be less than or equal to the size mentioned during the declaration. |
Java doesn't require mentioning size during declaration. | No need to specify the size of the string during declaration. | In C-style C++ string, size is to be mentioned for memory allocation as it uses character array for string implementation. |
Conclusion
- Strings are a stream of characters and can be represented by a stream of characters between a pair of double inverted commas, as a character array, or as an object of a class.
- Strings in Java are objects of class String in java.lang package.
- Java String operations are slow because of string immutability in Java. For each modification in an existing string object, it creates a new string object which increases the time complexity of various operations.
- StringBuffer class in Java can be used for faster string operations.
- C++ has two implementations of string, one as an object of String class and another as a character array derived from C programming language.
- String derived from C language is character Array, memory allocation is static. It is faster in implementation as compared to the String class. It does not offer many built-in functions to modify the existing string, and strings are immutable as the character array size is pre-defined.
- Dynamic memory allocation for string objects of std::string class. Efficient memory management and std::string class provide a number of methods to manipulate the strings.