Home
12Strings & Big Numbers
12

Topic 12 of 13 · Lectures 22–23

Strings & Big Numbers

The String class, the string pool and immutability, comparing and processing strings, StringBuilder, and doing arithmetic on numbers far too large for long.

← → move between slides · F full screen · M slide list

Before we start

Why this matters

What is 30 factorial? A long gives you −8,764,578,968,847,253,504. Clearly wrong — so how do banks and cryptography handle numbers with hundreds of digits?

One answer is to store the digits in a String and do the arithmetic yourself, digit by digit, exactly as you learnt at school. Java’s BigInteger does the same thing internally.

First we study String itself: why == can lie, why strings never change, and the methods you will use in almost every program.

Outline · Lectures 22–23

Topics in this chapter

Select a topic to jump to the slide that explains it.

  1. The String class and the string pool
  2. Comparing strings
  3. String operations
  4. StringBuilder and StringBuffer
  5. Big number manipulation using String

Concept 1 of 5

The String class and the string pool

Literals are shared from the pool; new String(...) always creates a separate object.

The String class and the string pool

String a = "Hi";               // pool
String b = "Hi";               // same pooled object
String c = new String("Hi");   // new heap object
char[] cs = {'J', 'a', 'v', 'a'};
String d = new String(cs);     // "Java"
String e = String.valueOf(42); // "42"
  • String is a class, but literals get special treatment: identical literals share one object in the string pool.
  • Strings are immutable: no method changes a String; methods return a new one.
  • Immutability makes strings safe to share between variables and threads.

Step through the code

Trace: pool, heap and ==

Watch which variables share an object. a + "!" builds a brand-new String — the original "Hi" is untouched.

Step through the code

Trace: pool, heap and == (cont.)

Concept 2 of 5

Comparing strings

String a = "apple", b = "Apple";
a == b                    // compares references
a.equals(b)               // false: content, case-sensitive
a.equalsIgnoreCase(b)     // true
a.compareTo(b)            // 32  ('a' 97 − 'A' 65)
"apple".compareTo("banana")  // -1  ('a' − 'b')
"app".compareTo("apple")     // -2  (length 3 − 5)
  • Never use == to compare text; use equals.
  • compareTo returns negative, 0 or positive for dictionary order: it subtracts the first differing characters, or the lengths if one is a prefix of the other.
  • Guard against null with "yes".equals(input) instead of input.equals("yes").

Concept 3 of 5

String methods at a glance

MethodExampleResult
length()"Hello".length()5
charAt(i)"Hello".charAt(1)'e'
indexOf / lastIndexOf"banana".indexOf("an") / lastIndexOf("an")1 / 3
substring(a, b)"Hello".substring(1, 4)"ell" (b excluded)
toUpperCase / toLowerCase"Java".toUpperCase()"JAVA"
trim / strip" hi ".trim()"hi"
replace"a-b-c".replace("-", "+")"a+b+c"
contains / startsWith / endsWith"report.pdf".endsWith(".pdf")true
split"a,b,,c".split(","){"a", "b", "", "c"}
join / repeatString.join("-", "a", "b") / "ab".repeat(3)"a-b" / "ababab"
toCharArray / valueOf"hi".toCharArray() / String.valueOf(3.5){'h','i'} / "3.5"

Interactive

String method playground

Code example

Processing text

String s = "Green University of Bangladesh";

int vowels = 0;
for (char ch : s.toLowerCase().toCharArray())
    if ("aeiou".indexOf(ch) >= 0) vowels++;

String[] words = s.split(" ");
String initials = "";
for (String w : words) initials += w.charAt(0);

String p = "madam";
boolean pal = new StringBuilder(p).reverse().toString().equals(p);

System.out.println(vowels + " " + words.length + " " + initials + " " + pal);
System.out.println(s.replace("Bangladesh", "BD").toUpperCase());
Output
10 4 GUoB true
GREEN UNIVERSITY OF BD

Step through the code

Trace: split() and += on Strings

Every += creates a new String. Watch the old ones lose their last reference and become garbage.

Step through the code

Trace: split() and += on Strings (cont.)

Concept 4 of 5

StringBuilder

StringBuilder sb = new StringBuilder("GUB");
sb.append(" CSE").append(201);   // "GUB CSE201"
sb.insert(3, ",");               // "GUB, CSE201"
sb.reverse();                    // "102ESC ,BUG"
sb.setCharAt(0, '9');            // "902ESC ,BUG"
sb.deleteCharAt(sb.length() - 1);// "902ESC ,BU"
String result = sb.toString();
  • StringBuilder is a mutable sequence of characters: its methods change the same object.
  • Joining strings with + in a loop creates a new String every time — slow for long loops.
  • StringBuffer is the older, synchronized (thread-safe) version.

Step through the code

Trace: String + in a loop vs StringBuilder

Count the objects on the heap: every s + i leaves an abandoned String behind, while the builder reuses one object.

Step through the code

Trace: String + in a loop vs StringBuilder (cont.)

Concept 5 of 5

Big numbers stored as Strings

TypeLargest value
int2,147,483,647 (10 digits)
long9,223,372,036,854,775,807 (19 digits)
String of digitsas many digits as memory allows
  • Store each number as a String of digits; the last character is the ones digit.
  • Work from right to left: a.charAt(i) - '0' converts a digit character to its value.
  • Keep a carry (addition) or borrow (subtraction), and build the answer with a StringBuilder, reversing at the end.
static String add(String a, String b) {
    StringBuilder sb = new StringBuilder();
    int i = a.length() - 1, j = b.length() - 1, carry = 0;
    while (i >= 0 || j >= 0 || carry > 0) {
        int d1 = i >= 0 ? a.charAt(i--) - '0' : 0;
        int d2 = j >= 0 ? b.charAt(j--) - '0' : 0;
        int sum = d1 + d2 + carry;
        sb.append(sum % 10);
        carry = sum / 10;
    }
    return sb.reverse().toString();
}

Interactive

Big-number addition, column by column

Code example

Multiplying big numbers

static String multiply(String a, String b) { int[] r = new int[a.length() + b.length()]; for (int i = a.length() - 1; i >= 0; i--) for (int j = b.length() - 1; j >= 0; j--) { int p = (a.charAt(i) - '0') * (b.charAt(j) - '0') + r[i + j + 1]; r[i + j + 1] = p % 10; // this column r[i + j] += p / 10; // carry to the left } StringBuilder sb = new StringBuilder(); for (int d : r) if (!(sb.length() == 0 && d == 0)) sb.append(d); return sb.length() == 0 ? "0" : sb.toString(); } System.out.println(multiply("123456789", "987654321")); System.out.println(multiply("12345678901234567890", "98765432109876543210"));
Output
121932631112635269
1219326311370217952237463801111263526900

Digit i of a times digit j of b lands in column i + j + 1 of the result — the same shifted rows you write on paper.

Code example

The library way: BigInteger and BigDecimal

import java.math.*;

BigInteger f = BigInteger.ONE;
for (int i = 2; i <= 30; i++) f = f.multiply(BigInteger.valueOf(i));
System.out.println("30! = " + f);
System.out.println("2^100 = " + BigInteger.TWO.pow(100));

System.out.println(0.1 + 0.2);
BigDecimal x = new BigDecimal("0.1"), y = new BigDecimal("0.2");
System.out.println(x.add(y));
Output
30! = 265252859812191058636308480000000
2^100 = 1267650600228229401496703205376
0.30000000000000004
0.3
  • BigInteger: integers of any size. BigDecimal: exact decimal arithmetic for money.
  • Both are immutable, like String: f.multiply(...) returns a new object.

Worked example 1 of 3

Worked example 1

What is printed? String s = "java"; s.toUpperCase(); System.out.println(s);
Show the solution
java. toUpperCase returns a new String that is thrown away. Write s = s.toUpperCase();.

Worked example 2 of 3

Worked example 2

Count the words in a sentence that may contain several spaces between words.
Show the solution
String t = "  OOP   is   fun ";
String[] w = t.trim().split("\\s+");     // one or more spaces
System.out.println(w.length);            // 3

Worked example 3 of 3

Worked example 3

Add "999" and "1" with the string algorithm. Show each column.
Show the solution
  1. 9 + 1 + 0 = 10 → write 0, carry 1
  2. 9 + 0 + 1 = 10 → write 0, carry 1
  3. 9 + 0 + 1 = 10 → write 0, carry 1
  4. carry 1 left → write 1
Reverse "0001" → "1000".

Practice

Practice (1 of 2)

Try each one on paper first, then check your answer.

1. Why does new String("a") == "a" give false?
Show the answer
new String creates a separate object on the heap; == compares references, and the literal is the pooled object.
2. Write a method that checks whether a String is a palindrome, ignoring case.
Show the answer
static boolean isPal(String s) {
    s = s.toLowerCase();
    for (int i = 0, j = s.length() - 1; i < j; i++, j--)
        if (s.charAt(i) != s.charAt(j)) return false;
    return true;
}
3. What does "Programming".substring(3, 7) return?
Show the answer
"gram" (indexes 3, 4, 5, 6).

Practice

Practice (2 of 2)

Try each one on paper first, then check your answer.

4. Give the result of "cat".compareTo("car").
Show the answer
2 ('t' 116 − 'r' 114).
5. Write subtract(String a, String b) for a ≥ b ≥ 0.
Show the answer
static String subtract(String a, String b) {
    StringBuilder sb = new StringBuilder();
    int borrow = 0;
    for (int i = a.length() - 1, j = b.length() - 1; i >= 0; i--, j--) {
        int d = a.charAt(i) - '0' - borrow - (j >= 0 ? b.charAt(j) - '0' : 0);
        borrow = d < 0 ? 1 : 0;
        sb.append(d < 0 ? d + 10 : d);
    }
    String r = sb.reverse().toString().replaceFirst("^0+(?!$)", "");
    return r;
}
6. When should you use StringBuilder instead of String?
Show the answer
When you build a string step by step, especially inside loops, to avoid creating many temporary String objects.

Check yourself

Quiz

Summary

Summary

  • String literals share objects in the string pool; new String always creates a new object.
  • Strings are immutable — methods return new strings; compare text with equals, order with compareTo.
  • Key methods: length, charAt, indexOf, substring, split, replace, trim, toUpperCase.
  • StringBuilder is mutable and efficient for building strings in loops.
  • Numbers of any size can be stored as digit strings and added or multiplied column by column; BigInteger/BigDecimal do it for you.