</>CodexBash
Java
JavaBeginner10 min

Strings and StringBuilder

String methods for length, characters, substrings, searching and splitting, why strings never change, building text efficiently with StringBuilder, and comparing correctly.

Indexing and slicing a stringstep 1/5
p
0
y
1
t
2
h
3
o
4
n
5
s = pythonlen = 6
Each character has a position, starting at 0. A string of length 6 has positions 0 to 5.

Reading a string#

String s = "programming";
s.length()          // 11
s.charAt(0)         // 'p'
s.charAt(s.length() - 1)   // 'g'
s.isEmpty()         // false

Positions run from 0 to length() - 1. charAt(11) throws StringIndexOutOfBoundsException.

Pieces and searching#

s.substring(3, 7)       // "gram": from 3 up to, not including, 7
s.substring(7)          // "ming"
s.indexOf("gram")       // 3, or -1 if not found
s.indexOf('m')          // 6
s.contains("gram")      // true
s.startsWith("pro")     // true
s.endsWith("ing")       // true

Changing case, trimming, replacing#

"  Hi There  ".trim()          // "Hi There"
"Hi".toUpperCase()             // "HI"
"Hi".toLowerCase()             // "hi"
"banana".replace('a', 'o')     // "bonono"

Splitting and joining#

String[] parts = "a,b,c".split(",");             // ["a", "b", "c"]
String[] words = "one two   three".split("\\s+"); // any run of whitespace
String joined = String.join("-", "a", "b", "c");  // "a-b-c"

split takes a regular expression, which is why whitespace is written "\\s+" and a full stop must be escaped: split("\\.").

Strings never change#

Every method above returns a new string. The original is untouched:

String s = "hello";
s.toUpperCase();          // result thrown away
System.out.println(s);    // still "hello"
s = s.toUpperCase();      // keep the result

That is why building a string with + inside a loop is slow: each + creates a new string and copies everything so far. For a thousand pieces, that is a lot of copying.

StringBuilder#

When you build text piece by piece, use a StringBuilder, which can change:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
    sb.append(i).append(' ');
}
String result = sb.toString();      // "0 1 2 3 4 "

new StringBuilder("hello").reverse().toString();   // "olleh"
sb.insert(0, "start ");
sb.deleteCharAt(sb.length() - 1);
sb.setCharAt(0, 'S');

reverse gives the quickest palindrome check: compare a string with its reverse using equals.

Comparing strings#

a.equals(b)                  // same characters: use this
a.equalsIgnoreCase(b)        // ignoring case
a.compareTo(b)               // negative, 0 or positive: alphabetical order

Never a == b for content: that asks whether they are the same object.

Walking the characters#

int vowels = 0;
for (char c : s.toCharArray()) {
    if ("aeiouAEIOU".indexOf(c) >= 0) vowels++;
}

Or by position, with s.charAt(i), when you need the index too.

Key points#

  • length(), charAt(i), substring(a, b) and indexOf cover most reading.
  • Strings never change; methods return new strings, so keep the result.
  • Build text in loops with StringBuilder, then call toString().
  • Compare with equals, never ==.

Next: decisions with if and switch.

Practise it

The same idea, in the order it is worth meeting it.

  1. Not startedIs it a palindromeEasy
  2. Not startedCancel out neighbouring pairsEasy
Create a free account to track your progress