Strings

Unraveling The Mysteries


Creating Strings

Literals via assignment or passing:
String msg = "Hello";System.out.println("Hello");

String constructor:
String msg = new String("Hello");System.out.println(new String("Hello"));

The String Pool

When creating strings via literals, Java uses a cache called the String Pool.

These are the same object!
String msg = "Hello";String msg2 = "Hello";
msg == msg2; // evaluates to true

But these are not:
String msg = new String("Hello");
String msg2 = new String("Hello");
msg == msg2; // evaluates to false

Other Ways to Create Strings

Construct from char array:
char[] msgChars = new char[]{'H', 'e', 'l', 'l', 'o'};String msg = new String(msgChars);

Construct from StringBuilder/Buffer:
StringBuilder sbld = new StringBuilder("String Builder");String s1 = new String(sbld);StringBuffer sbuf = new StringBuffer("String Buffer");String s2 = new String(sbuf);

Null String reference:
 String nullStr = null;

How many different String objects?


 class StringCreator {
    public static void main(String... args) {
        String summer = new String("Summer");     // line 1
        String summer2 = "Summer";                // line 2
        System.out.println("Summer");             // line 3
        System.out.println("autumn");             // line 4
        System.out.println("autumn" == "summer"); // line 5
        String autumn = new String("Summer");     // line 6
    }
}

Answer

5

  • Line 1 creates a new  String object with the value "Summer" . This object is not placed in the String constant pool.
  • Line 2 creates a new  String object with the value "Summer" and places it in the String constant pool.
  • Line 3 doesn't need to create any new  String object. It reuses the String object with the value "Summer" that already existed in the String constant pool.
  • Line 4 creates a new String object with the value "autumn" and places it in the String constant pool.
  • Line 5 reuses the String value "autumn" from the String constant pool. It creates a String object with the value "summer" in the String constant pool (note the difference in the case of letters—Java is case sEnSitIVe and "Summer" is not same as "summer").
  • Line 6 creates a new String object with the value "Summer".

Strings are IMMORTAL IMMUTABLE

 You can't change them once they're created!

Implemented by using a private final field in the String class for internal storage, and having no mutator methods:

 private final char[] value;

There's a String.toCharArray() method, but this makes a copy of the array before returning it.

Strings are zero-based

Just like arrays, the first character is number 0.

String has useful methods

A few:
  • charAt(int index)
  • indexOf(int ch) / indexOf(String str)
  • substring(int beginIdx) / substring(int beginIdx, int endIdx);
    • Second arg is end, not length!
    • Length of result is (endIdx - beginIdx) -- char at endIdx is not included!
  • trim()
  • replace(old, new) - takes chars or strings
  • length()
  • startsWith(String prefix) / endsWith(String suffix)

String Methods

Remember, Strings are immutable! All these instance methods return a new String, and leave the original one untouched.

Because of this, you can chain method calls together, like so:
String result = " Sunday ".replace(' ', 'Z').trim().concat("M n");
System.out.println(result); // SundayZZM n

4.1 p186

What is the correct output?

String letters = "ABCAB";System.out.println(letters.substring(0, 2).startsWith('A'));
  1. true
  2. false
  3. AB
  4. ABC
  5. Compilation Error

Answer

true

Concatenation

Strings get special treatment: the + and += operators are overloaded for the String class.

These use a StringBuilder behind the scenes to do the work.

You can concatenate Strings with numbers, but remember, + is evaluated left to right.  String conversion only happens when one of the operands is a String.
System.out.println(11 + 31 + "ANSWER"); // prints 42ANSWERSystem.out.println(11 + (31 + "ANSWER")); // prints 1131ANSWER

Concatenation, Cont.

Remember, += is shorthand.  These two code blocks are equivalent:
String str1 = "a";str1 += "b";

String str2 = "a";str2 = str2 + "b";

Comparing Strings

== compares references.  It can sometimes work due to the String pool, so be careful!

In general, you should use the equals() method to compare Strings.  Don't worry about optimizations - equals() has a short-circuit method to return true instantly if the Strings are actually the same reference.


The Mighty StringBuilder

Since Strings are immutable, doing concatenation generates a bunch of temporary Strings.  This is horrible:
String bunchOfAs = "";for(int i = 0; i < 100; i++) {    bunchOfAs += "a";}
StringBuilder is mutable, and designed for when you need to build up a string piece by piece.
StringBuilder aBuilder = new StringBuilder;for(int i = 0; i < 100; i++) {    aBuilder.append("a");}String bunchOfAs = aBuilder.toString();

Building StringBuilders

  • new StringBuilder();
    • Creates an empty StringBuilder
  • new StringBuilder(StringBuilder other)
    • Initialize from another StringBuilder
  • new StringBuilder(int capacity)
    • If you know you're going to be building a large String, you can make things a bit faster by telling StringBuilder.
    • The default capacity, at least in the Oracle JRE, is 16 characters.
  • new StringBuilder(String initial)
    • Create a StringBuilder which starts with an initial value

StringBuilder Methods

  • append()
    • Has overloads to allow appending anything
    • append(Object obj) will use the value of obj.toString(), which may be overriden
  • insert()
    • Like append, but lets you specify where to add things
  • delete(int beginIdx, int endIdx) / deleteCharAt(int idx)
    • Two-param variant delete up to, but not including, endIdx
  • reverse()
    • Reverses the contents of the StringBuilder in-place
  • replace()
    • Replaces a portion of the value of the StringBuilder
  • subSequence()
    • Works basically the same as substring()

StringBuilder vs StringBuffer

StringBuffer is thread-safe.  You can safely use the same instance in multiple threads at the same time.  However, this adds some overhead.

StringBuilder is a bit faster, but not safe to share between multiple threads unless you use your own synchronization.

Strings

By mitchellmebane

Strings

  • 455