1 of 13

Learning Java: �A Test-Driven Approach

Chapter 1.2: Strings

2 of 13

What are strings?

Strings, simply put, are a sequence of immutable characters. They are indexed starting from zero!

​

Example: Declare a string variable as "Hello":

​

String s1 = "Hello";

​

​

The string literal, "Hello", is represented as such, meaning the character 'e' is at index 1 rather than 2.

Character

'H'

'e'

'l'

'l'

'o'

Index

0

1

2

3

4

3 of 13

String operation: concatenation.

Strings overload the '+' operator, in a process called concatenation.

​

Example: Combine the string s1 with the string literal ", world!" into a new string variable called s2:

​

String s2 = s1 + ", world!";

​

Concatenation performs 'type coercion,' i.e., collapses types to strings.

This is performed left to right, as outlined by these examples.

​

1 + "hello" => "1hello"

1 + "hello" + 2 => "1hello2"

1 + 2 + "hello" => "3hello"

"hello" + 1 + 2 => "hello12"

�

4 of 13

Various string methods.

5 of 13

String method examples.

s.substring(i, j): Returns substring from index i up to and not including j.��s.substring(i): Returns the substring from index i up to the end of the string.

"hello".substring(2); => "llo"

Equivalent to "hello".substring(2, 5);

"hello".substring(1,3); => "el"

​

s.indexOf(t): Returns the index of the first occurrence of t in s.

"hello".indexOf("l"); => 2

"hello".lastIndexOf("l"); => 3

"hello".indexOf("f"); => -1

This method is case sensitive.

​

6 of 13

String method examples.

s.contains(t): returns whether t is a substring of s.

"hello".contains("ello"); => true

"hello".contains("hi"); => false

This method is case sensitive.

​

s.length(): returns the number of characters in s. Note that spaces count as characters.

"hello !".length(); => 8

"".length(); => 0

​

s.charAt(i): returns the character at index i of s.

"hello".charAt(2) => "l";

"hello".charAt("hello".length() – 1) => 'o';

​

​

7 of 13

Where to use .equals():

Strings are immutable, meaning that to create a distinct string, you must use new String(...);

​

Example:

String s1 = "hello";

String s2 = new String("hello");

s1 == s2 // false

s1.equals(s2) // true!

​

.equals() is therefore used for character equality, while == is for object equality.

​

Never use == for string equality, even though strings are immutable. Always use .equals().�

8 of 13

Where to use .equals():

But why does ��String s1 = "hello";

String s2 = "hello";

s1 == s2 resolve to true?

​

Java performs string cache optimization.

​

Because strings are immutable, why not

let s1 and s2 point to the same string in

memory?

​

Two distinct references is inefficient!

​

So, s1 and s2 point to the same object in memory; remember that == compares object equality.

9 of 13

Where to use .equals():

Another example of Java's string optimization:

​

String s1 = "hello" + ", world";

String s2 = "hello, world";

s1 == s2 resolves to true.

​

Java sees that the concatenation of the two literals in s1 is the same as the literal in s2.

  • It performs a compile-time optimization.

​

But:

String s1 = "hello";

String s2 = ", world";

String s3 = s1 + s2;

String s4 = "hello, world";

s1 == s4 resolves to false.

​

Java cannot optimize the concatenation of two variables.�

10 of 13

How .compareTo() works.

s1.compareTo(s2) returns a lexicographical comparison of two strings.

​

Lexicographical is a fancy term meaning "ordered."

​

Every character is actually a number, as referenced from an ASCII table.

​

The value returned by compareTo is the ordering of s1 with respect to s2.

  • A negative number implies s1 comes before s2.
  • A positive number implies s1 comes after s2.
  • Zero means s1 is equal to s2.

​

Examples:

"hello".compareTo("hiya"); // returns < 0

"alumni".compareTo("alphabet"); // returns > 0

"people".compareTo("people"); // returns == 0

11 of 13

How .compareTo() works.

How do we know the ordering of strings?

  • For simple strings with the same case and only letters, it's easy, just compare letter by letter. E.g., "hello".compareTo("hiya"), e comes before i, meaning the method returns < 0.�
  • For strings with other characters, it's not as easy.

​

  • Acronym for remembering rules of thumb: SNUL
    • Special characters (e.g., +, *, %) are less than…
    • Numbers (e.g., 0, 1, 2) are less than…
    • Uppercase letters (e.g., 'A', 'F') are less than…
    • Lowercase letters (e.g., 'a', 'f').

​

  • Not a perfect rule: we would consider the underscore ('_') to be special, but it comes after the uppercase letters. View an ASCII table for more detail.

12 of 13

How .compareTo() works.

We can use arithmetic & logical operations over characters.

​

Example:

'A' + '0' = 65 + 48

= 113

= 'q'

​

‘A’ + 32 = 97

= 'a'

​

'Q' < '6' = false

​

To convert between characters and numbers, use casts, or use 'c' – 0.

​

Example:

int x = (int) 'A'; // x = 65

char c = (char) 65; // c = 'A'

int y = 'c' – 0 ; // y = 65

13 of 13

How .compareTo() works.

Do not feel the need to memorize the entire ASCII table; just remember a few key characters/equivalences, such as:

​

'A' = 65,

'a' = 97,

" " (blank space) = 32,

'0' = 48

​

Do you understand why '9' - '0' = 9?

'9' - '0' = 57 - 48

= 9

​