slanted W3C logo

Day 13 — Strings I

In today's lecture we start to look at the String class.

Strings represent text (a sequence of characters) and are widely used in Java programs. Because they are so widely used, the Java language lets a client perform actions with String objects that cannot be performed with other types of objects.

String Literals

A String literal consists of zero or more characters enclosed in double quotes; for example:

"hello"
"416-736-2100"
"computer science and engineering"

Creating String Objects

String is a class; therefore, you can create objects of type String. It is possible to use a constructor:

public static void main(String[] args)
{
   String s = new String("YorkU");
}

but this main method actually has 2 String objects.

  main
 
s ⇒ 900
 
  ¦
String class
 
  ¦
800 String object
"YorkU"
  ¦
900 String object
"YorkU"

String Literals are Objects

In Java, String literals are objects. In the line of code:

String s = new String("YorkU");

the literal "YorkU" refers to an (unnamed) String object, and s refers to a separate String object.

String Objects are Immutable

The String class defines zero mutator methods; thus, the sequence of characters in a String can never be changed.

Immutability is a very powerful software engineering tool. In particular, you usually do not need to make a copy of an immutable object.

Because a String literal refers to a String object, and because String objects are immutable, you usually do not need to use the copy constructor. You should prefer

String s = "YorkU";

instead of

String s = new String("YorkU");

String Literals are Interned

Java guarantees that if you use the same String literal more than once, only one String object is created. The String class is responsible for maintaining a pool of unique String objects corresponding to the literals used in the program (Java calls this interning).

Interning

Because of interning, the following main method has only 1 unique String object:

public static void main(String[] args)
{
   String s = "YorkU";
   String t = "YorkU";
   String u = "YorkU";
}
  main
 
s ⇒ 800
t ⇒ 800
u ⇒ 800
 
  ¦
String class
 
  ¦
800 String object
"YorkU"

String as a Sequence

You can think of a String as being an ordered sequence of individual char values. Each char in the String object has an integer index starting from zero.

Commonly Used Accessors: length

int length()

Returns the length of this string.

String s = "YorkU";
String t = "York"
String u = "Yor";
String v = "Yo";
String w = "Y";
String x = "";
output.printf("%d %d %d %d %d %d%n",
              s.length(),
              t.length(),
              u.length(),
              v.length(),
              w.length(),
              x.length());

The code fragment prints 5 4 3 2 1 0.

Commonly Used Accessors: charAt

char charAt(int index)

Returns the char value at the specified index. An index ranges from 0 to length() - 1. The first char value of the sequence is at index 0, the next at index 1, and so on.

Throws IndexOutOfBoundsException if the index argument is negative or not less than the length of this string.

String s = "YorkU";

char c = s.charAt(0);
output.print(c);

c = s.charAt(s.length() - 1);
output.println(c);

The code fragment prints YU.

Examples with length and charAt

Count the number of 'e' characters in a String s:

count = 0
for the first to last index i in s
   c = character at index i
   if c == 'e'
      count++
String s = "Ada Lovelace";
char target = 'e';
int count = 0;
for (int i = 0;
     i < s.length();
     i++)
{
   if (s.charAt(i) == target)
   {
      count++;
   }
}

Comparators

A comparator method compares two Strings or finds features in a String.

indexOf Example

Finding the index idx of the first 'e' in a String s:

idx = -1
for the first to last index i in s
   c = character at index i
   if c == 'e'
      idx = i
      done
String s = "Ada Lovelace";
char target = 'e';
int idx = -1;
for (int i = 0;
     i < s.length() && idx < 0;
     i++)
{
   if (s.charAt(i) == target)
   {
      idx = i;
   }
}

Or delegate to String and use indexOf:

int idx = s.indexOf(target);

lastIndexOf Example

Finding the index idx of the last 'a' in a String s:

last = -1
for the last to first index i in s
   c = character at index i
   if c == 'a'
      last = i
      done
String s = "Ada Lovelace";
char target = 'a';
int idx = -1;
for (int i = s.length() - 1;
     i >= 0 && idx < 0;
     i--)
{
   if (s.charAt(i) == target)
   {
      idx = i;
   }
}

Or delegate to String and use lastIndexOf:

int idx = s.lastIndexOf(target);

equals Example

Compare two String objects referred to by s and t for equality of state:

if s and t have different lengths
   eq = false
else
   for the first to last index i in s
      cs = character at index i in s
      ct = character at index i in t
      if cs != ct
         eq = false
         done
boolean eq = (s.length() == t.length());
for (int i = 0; eq && i < s.length(); i++)
{
   if (s.charAt(i) != t.charAt(i))
   {
      eq = false;
   }
}

Or delegate to String and use equals:

boolean eq = s.equals(t);