Java Language


Strings All Versions

Java SE 1.0
Java SE 1.1
Java SE 1.2
Java SE 1.3
Java SE 1.4
Java SE 5
Java SE 6
Java SE 7
Java SE 8
Java SE 9 (Early Access)

This draft deletes the entire topic.

Introduction

Strings (java.lang.String) are pieces of text stored in your program. They can be used as either a literal delimited by double quotes, or through various constructors.
expand all collapse all

Examples

  • 95

    In order to compare Strings for equality, you should use the String object's equals or equalsIgnoreCase methods.

    For example, the following snippet will determine if the two instances of String are equal on all characters:

    String firstString = "Test123";
    String secondString = "Test" + 123;
    
    if (firstString.equals(secondString)) {
       // Both Strings have the same content.
    }
    

    Live demo

    This example will compare them, independent of their case:

    String firstString = "Test123";
    String secondString = "TEST123";
    
    if (firstString.equalsIgnoreCase(secondString)) {
        // Both Strings are equal, ignoring the case of the individual characters.
    }
    

    Live demo

    Note that equalsIgnoreCase does not let you specify a Locale. For instance, if you compare the two words "Taki" and "TAKI" in English they are equal; however, in Turkish they are different (in Turkish, the lowercase I is ı). For cases like this, converting both strings to lowercase (or uppercase) with Locale and then comparing with equals is the solution.

    String firstString = "Taki";
    String secondString = "TAKI";
    
    System.out.println(firstString.equalsIgnoreCase(secondString)); //prints true
    
    Locale locale = Locale.forLanguageTag("tr-TR");
    
    System.out.println(firstString.toLowerCase(locale).equals(
                       secondString.toLowerCase(locale))); //prints false
    

    Live demo


    Do not use the == operator to compare Strings

    Unless you can guarantee that all strings have been interned (see below), you should not use the == or != operators to compare Strings. These operators actually test references, and since multiple String objects can represent the same String, this is liable to give the wrong answer.

    Instead, use the String.equals(Object) method, which will compare the String objects based on their values. For a detailed explanation, please refer to Pitfall: using == to compare strings.


    Comparing Strings in a switch statement

    Java SE 7

    As of Java 1.7, it is possible to compare a String variable to literals in a switch statement. Make sure that the String is not null, otherwise it will always throw a NullPointerException. Values are compared using String.equals, i.e. case sensitive.

    String stringToSwitch = "A";
    
    switch (stringToSwitch) {
        case "a":
            System.out.println("a");
            break;
        case "A":
            System.out.println("A"); //the code goes here
            break;
        case "B":
            System.out.println("B");
            break;
        default:
            break;
    }
    

    Live demo

    Comparing Strings with constant values

    When comparing a String to a constant value, you can put the constant value on the left side of equals to ensure that you won't get a NullPointerException if the other String is null.

    "baz".equals(foo)
    

    While foo.equals("baz") will throw a NullPointerException if foo is null, "baz".equals(foo) will evaluate to false.

    Java SE 7

    A more readable alternative is to use Objects.equals(), which does a null check on both parameters: Objects.equals(foo, "baz").

    (Note: It is debatable as to whether it is better to avoid NullPointerExceptions in general, or let them happen and then fix the root cause; see here and here. Certainly, calling the avoidance strategy "best practice" is not justifiable.)

    String orderings

    The String class implements Comparable<String> with the String.compareTo method (as described at the start of this example). This makes the natural ordering of String objects case-sensitive order. The String class provide a Comparator<String> constant called CASE_INSENSITIVE_ORDER suitable for case-insensitive sorting.

    Comparing with interned Strings

    The Java Language Specification (JLS 3.10.6) states the following:

    "Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions - are interned so as to share unique instances, using the method String.intern."

    This means it is safe to compare references to string literals using ==. Moreover, the same is true for references to String objects that have been produced using the String.intern() method.

    For example:

    String strObj = new String("Hello!");
    String str = "Hello!";
    
    // The two string references point two strings that are equal
    if (strObj.equals(str)) {
        System.out.println("The strings are equal");
    }
    
    // The two string references do not point to the same object
    if (strObj != str) {
        System.out.println("The strings are not the same object");
    }
    
    // If we intern a string that is equal to a given literal, the result is
    // a string that has the same reference as the literal.
    String internedStr = strObj.intern();
    
    if (internedStr == str) {
        System.out.println("The interned string and the literal are the same object");
    }
    

    Behind the scenes, the interning mechanism maintains a hash table that contains all interned strings that are still reachable. When you call intern() on a String, the method looks up the object in the hash table:

    • If the string is found, then that value is returned as the interned string.
    • Otherwise, a copy of the string is added to the hash table and that string is returned as the interned string.

    If you are careful, it is possible to use interning to allow strings to be compared using ==. However, there are significant problems with doing this; see Pitfall - Interning strings so that you can use == is a bad idea .

  • 22

    The String type provides two methods for converting strings between upper case and lower case:

    These methods both return the converted strings as new String instances: the original String objects are not modified.

    String string = "This is a Random String";
    String upper = string.toUpperCase();
    String lower = string.toLowerCase();
    
    System.out.println(string);   // prints "This is a Random String"
    System.out.println(lower);    // prints "this is a random string"
    System.out.println(upper);    // prints "THIS IS A RANDOM STRING"
    

    Non-alphabetic characters, such as digits and punctuation marks, are unaffected by these methods. Note that these methods may also incorrectly deal with certain Unicode characters under certain conditions.


    Note: These methods are locale-sensitive, and may produce unexpected results if used on strings that are intended to be interpreted independent of the locale. Examples are programming language identifiers, protocol keys, and HTML tags.

    For instance, "TITLE".toLowerCase() in a Turkish locale returns "tıtle", where ı (\u0131) is the LATIN SMALL LETTER DOTLESS I character. To obtain correct results for locale insensitive strings, pass Locale.ROOT as a parameter to the corresponding case converting method (e.g. toLowerCase(Locale.ROOT) or toUpperCase(Locale.ROOT)).

    Although using Locale.ENGLISH is also correct for most cases, the language invariant way is Locale.ROOT.

    A detailed list of Unicode characters that require special casing can be found on the Unicode Consortium website.

    Changing case of a specific character within an ASCII string:

    To change the case of a specific character of an ASCII string following algorithm can be used:

    Steps:

    1. Declare a string.
    2. Input the string.
    3. Convert the string into a character array.
    4. Input the character that is to be searched.
    5. Search for the character into the character array.
    6. If found,check if the character is lowercase or uppercase.
      • If Uppercase, add 32 to the ASCII code of the character.
      • If Lowercase, subtract 32 from the ASCII code of the character.
    7. Change the original character from the Character array.
    8. Convert the character array back into the string.

    Voila, the Case of the character is changed.

    An example of the code for the algorithm is:

    Scanner scanner = new Scanner(System.in);
    System.out.println("Enter the String");
    String s = scanner.next();
    char[] a = s.toCharArray();
    System.out.println("Enter the character you are looking for");
    System.out.println(s);
    String c = scanner.next();
    char d = c.charAt(0);
    
    for (int i = 0; i <= s.length(); i++) {
        if (a[i] == d) {
            if (d >= 'a' && d <= 'z') {
                d -= 32;
            } else if (d >= 'A' && d <= 'Z') {
                d += 32;
            }
            a[i] = d;
            break;
        }
    }
    s = String.valueOf(a);
    System.out.println(s);
    
  • 12

    To check whether a particular String a is being contained in a String b or not, we can use the method String.contains() with the following syntax:

    b.contains(a); // Return true if a is contained in b, false otherwise
    

    The String.contains() method can be used to verify if a CharSequence can be found in the String. The method looks for the String a in the String b in a case-sensitive way.

    String str1 = "Hello World";
    String str2 = "Hello";
    String str3 = "helLO";
    
    System.out.println(str1.contains(str2)); //prints true
    System.out.println(str1.contains(str3)); //prints false
    

    Live Demo on Ideone


    To find the exact position where a String starts within another String, use String.indexOf():

    String s = "this is a long sentence";
    int i = s.indexOf('i');    // the first 'i' in String is at index 2
    int j = s.indexOf("long"); // the index of the first occurrence of "long" in s is 10
    int k = s.indexOf('z');    // k is -1 because 'z' was not found in String s
    int h = s.indexOf("LoNg"); // h is -1 because "LoNg" was not found in String s
    

    Live Demo on Ideone

    The String.indexOf() method returns the first index of a char or String in another String. The method returns -1 if it is not found.

    Note: The String.indexOf() method is case sensitive.

    Example of search ignoring the case:

    String str1 = "Hello World";
    String str2 = "wOr";
    str1.indexOf(str2);                               // -1
    str1.toLowerCase().contains(str2.toLowerCase());  // true
    str1.toLowerCase().indexOf(str2.toLowerCase());   // 6
    

    Live Demo on Ideone

Please consider making a request to improve this example.

Syntax

Syntax

Parameters

Parameters

Remarks

Since Java strings are immutable, all methods which manipulate a String will return a new String object. They do not change the original String. This includes to substring and replacement methods that C and C++ programers would expect to mutate the target String object.


Use a StringBuilder instead of String if you want to concatenate more than two String objects whose values cannot be determined at compile-time. This technique is more performant than creating new String objects and concatenating them because StringBuilder is mutable.

StringBuffer can also be used to concatenate String objects. However, this class is less performant because it is designed to be thread-safe, and acquires a mutex before each operation. Since you almost never need thread-safety when concatenating strings, it is best to use StringBuilder.

If you can express a string concatenation as a single expression, then it is better to use the + operator. The Java compiler will convert an expression containing + concatenations into an efficient sequence of operations using either String.concat(...) or StringBuilder. The advice to use StringBuilder explicitly only applies when the concatenation involves a multiple expressions.


Don't store sensitive information in strings. If someone is able to obtain a memory dump of your running application, then they will be able to find all of the existing String objects and read their contents. This includes String objects that are unreachable and are awaiting garbage collection. If this is a concern, you will need to wipe sensitive string data as soon as you are done with it. You cannot do this with String objects since they are immutable. Therefore, it is advisable to use a char[] objects to hold sensitive character data, and wipe them (e.g. overwrite them with '\000' characters) when you are done.


All String instances are created on the heap, even instances that correspond to string literals. The special thing about string literals is that the JVM ensures that all literals that are equal (i.e. that consists of the same characters) are represented by a single String object (this behavior is specified in JLS). This is implemented by JVM class loaders. When a class loader loads a class, it scans for string literals that are used in the class definition, each time it sees one, it checks if there is already a record in the string pool for this literal (using the literal as a key). If there is already an entry for the literal, the reference to a String instance stored as the pair for that literal is used. Otherwise, a new String instance is created and a reference to the instance is stored for the literal (used as a key) in the string pool. (Also see string interning).

The string pool is held in the Java heap, and is subject to normal garbage collection.

Java SE 7

In releases of Java before Java 7, the string pool was held in a special part of the heap known as "PermGen". This part was only collected occasionally.

Java SE 7

In Java 7, the string pool was moved off from "PermGen".

Note that string literals are implicitly reachable from any method that uses them. This means that the corresponding String objects can only be garbage collected if the code itself is garbage collected.


Up until Java 8, String objects are implemented as a UTF-16 char array (2 bytes per char). There is a proposal in Java 9 to implement String as a byte array with an encoding flag field to note if the string is encoded as bytes (LATIN-1) or chars (UTF-16).

Still have a question about Strings? Ask Question

Topic Outline