• No results found

Characters and Strings

In document Java (Page 76-80)

The char type is a primitive - a simple value, not an object. A char literal is enclosed in single quotes like 'x' (not double quotes like "x" which is a string). So

char myChar='a';

System.out.println(myChar);

A char is internally represented as a 16 bit number, being the Unicode (Google) code for a character.

The first of these are the same as the older 7 bit ASCII code set. For example, 65 to 90 are the letters A to Z:

char c;

for (int code=65; code<91; code++) {

c=(char)code; // type cast the number to the equivalent char System.out.print(code+" "+c+" : ");

}

outputs:

65 A : 66 B : 67 C : 68 D : 69 E : 70 F : 71 G : 72 H : 73 I : 74 J : 75 K : 76 L : 77 M : 78 N : 79 O : 80 P : 81 Q : 82 R : 83 S : 84 T : 85 U : 86 V : 87 W : 88 X : 89 Y : 90 Z :

We can also have a char literal as its Unicode value, in hex, directly:

char uniChar = '\u0030'; // hex 30 = decimal 48 = digit zero

The visual appearance will depend on which character it is, and which font is currently being used.

Some (most) fonts cannot display all 65000 Unicode characters.

On Windows, the CharMap utility is useful for finding characters and their codes.

The first 32 ASCII characters are usually treated as 'control characters' in the sense of controlling the output rather then displaying normal symbols. These are mostly historical, being used to control the position of the head of a teletype machine. But some are still useful:

char uniChar = 10; // line feed

System.out.println(uniChar); // produces 2 new lines

The line feed can also be represented as an 'escape sequence':

char uniChar = '\n'; // new line System.out.println(uniChar);

Strings

A char is a primitive type representing one character. A String in Java is a sequence of zero or more characters. Strings are objects, instances of the class String.

For example:

String s = "Hello from Java"; // make a string System.out.println(s); // output it

s="line one \n line two"; // two lines

s="one "+"two"; // + concatenates = joins, strings int x=4;

s="x = "+x; // s is 'x = 4'

s=""; // s is a string with no characters s=null; // s is null - not the same as ""

The String class has many useful methods.

We can invoke a method (make it happen) on an object by using the syntax

<object name>.<method>()

Some methods take parameters, others do not.

Here are a few examples

String s = "Hello from Java"; // make a string int n = s.length(); // length of string = 15 // getting parts of a string

char c=s.charAt(1); // 'e'. Character at some position - first char is position 0 String s1=s.substring(1, 3); // s1 is "el". Part of a string

s.contains("from"); // true. Does it contain another string s.equals("Hello from Leicester"); // false. Compares two strings

s.indexOf("from"); // 6. Location of one string in the other. -1 if not there s.startsWith("Hello"); // true

s.replace("Java", "C++"); // returns "Hello from C++"

String[] words= s.split(" "); // words is an array of 3 strings "Hello", "from" and "Java"

Exercise Try this out.

There are several ways to convert between numbers and strings. For example:

int i;

double d;

String s3 = Integer.toString(i);

String s4 = Double.toString(d);

and the other way round:

String s1="28";

String s2="1.24";

int i = Integer.parseInt(s1);

double d=Double.parseDouble(s2);

When a string is changed into a number, there is the chance that the string is not a valid number - such as 1.2.3. In this case a NumberFormatException will be thrown, which you can catch:

String s="1.2.3";

double d;

try{

d=Double.parseDouble(s);

}

catch (NumberFormatException nfe) {

System.out.println("Its gone horribly wrong");

// put code here to fix things }

But in Java strings are unusual objects, in that Strings are immutable

This means a String object, once created, cannot be changed. It often looks like we are changing a string object, when in fact we are creating a new one and setting a reference to it. For example

String s="ABC";

s = s+"DEF"; // makes a new string, from ABC and DEF

Sometimes this does not matter much. Sometimes it does - for example:

String s = "A";

for (int i=0; i<1000; i++) s+="A";

This creates 1001 String objects. It loses all but 1 reference to them, so it creates 1000 garbage objects.

Consequently it is sometimes better to use some alternatives.

Arrays of char

An array of char is the same as an array of anything else - we can certainly change its elements. The String class has a method toCharArray which creates an array of the chars from a String, and there is a String constructor which takes a char array as argument. For example, the following turns a String to an array of chars, then swaps characters to reverse the array:

String s = "What a fine mess";

char[] array = s.toCharArray();

int size = array.length;

for (int i = 0; i < size/2; i++) { char temp = array[i];

array[i] = array[size - i - 1];

array[size - i - 1] = temp;

}

String reverse = new String(array);

System.out.println(reverse); // ssem enif a tahW

The point of this is avoiding creating a large number of intermediate String objects.

StringBuilder and StringBuffer

A StringBuilder is in effect a mutable String. The class has a reverse() method, so this is even easier than with a char array:

String s = "What a fine mess";

StringBuilder sb = new StringBuilder(s);

sb = sb.reverse();

String reverse = new String(sb);

System.out.println(reverse);

StringBuffer is the same as a StringBuilder, except that it is thread-safe - wich means that your program is running several threads which might access the same data at the same time, StringBuffer will ensure it will work correctly - while StringBuilder will not. On the other hand, it will be slightly slower.

So, no threads => use StringBuilder. Threads, use StringBuffer.

Exercise

Write a static recursive method which reverses a String. The header should be static String reverse(String s)

It should follow this pseudo-code:

if the length of s is one, return s

else return reverse(s with first char omitted) + first char of s Test it works.

How efficient is this?

Re-write it using StringBuilder instead.

In document Java (Page 76-80)