Docstoc

strings

Document Sample
strings Powered By Docstoc
					COMP2059 – Sun Certified Java Programmer

Strings     (p412-424)

Example - Comparing Strings

Remember: The == operator tests for equality between two object references. The equals() method
that every class inherits from Object should be overridden to test for object equality; in Strings it
tests if the values are the same (case sensitively). The similar equalsIgnoreCase() method of the
String class also tests if the values are the same but case insensitively.

Try out the following code and explain the output you get from it:

01   public class Equal {
02         public static void       main(String[] args) {
03               String name1       = "Fred";
04               String name2       = "Fred";
05               String name3       = new String("Fred");
06               String name4       = name2;
07               String name5       = "fred";
08
09                  System.out.println("name1("+ name1 + "):name2(" + name2 + ")");
10                  if (name1 == name2)
11                        System.out.println("\t== says same");
12                  else System.out.println("\t== says different");
13                  if (name1.equals(name2))
14                        System.out.println("\tequals() says same");
15                  else System.out.println("\tequals() says different");
16                  if (name1.equalsIgnoreCase(name2))
17                        System.out.println("\tequalsIgnoreCase() says same");
18                  else System.out.println("\tequalsIgnoreCase() says different");
19
20                  System.out.println("name1("+ name1 + "):name3(" + name3 + ")");
21                  if (name1 == name3)
22                        System.out.println("\t== says same");
23                  else System.out.println("\t== says different");
24                  if (name1.equals(name3))
25                        System.out.println("\tequals() says same");
26                  else System.out.println("\tequals() says different");
27                  if (name1.equalsIgnoreCase(name3))
28                        System.out.println("\tequalsIgnoreCase() says same");
29                  else System.out.println("\tequalsIgnoreCase() says different");
30
31                  System.out.println("name1("+ name1 + "):name4(" + name4 + ")");
32                  if (name1 == name4)
33                        System.out.println("\t== says same");
34                  else System.out.println("\t== says different");
35                  if (name1.equals(name4))
36                        System.out.println("\tequals() says same");
37                  else System.out.println("\tequals() says different");
38                  if (name1.equalsIgnoreCase(name4))
39                        System.out.println("\tequalsIgnoreCase() says same");
40                  else System.out.println("\tequalsIgnoreCase() says different");
41
42                  System.out.println("name1("+ name1 + "):name5(" + name5 + ")");
43                  if (name1 == name5)
44                        System.out.println("\t== says same");
45                  else System.out.println("\t== says different");
46                  if (name1.equals(name5))
47                        System.out.println("\tequals() says same");
48                  else System.out.println("\tequals() says different");
49                  if (name1.equalsIgnoreCase(name5))
50                        System.out.println("\tequalsIgnoreCase() says same");
51                  else System.out.println("\tequalsIgnoreCase() says different");
52          }
53   }



Exercise - Post Code Checker
Write a simple Java application that takes a postcode as a command line argument and outputs a
message to say whether it is in Paisley of not.


Example - Processing a string one character at a time
Strings in Java are not arrays of characters (ie different from C strings). However it is still
relatively simple to process them one character at a time if required:

01   public class OneChar {
02         public static void main(String[] args) {
03               String str1 = "Break glass in emergency";
04               String str2 = "";
05               for (int i = 0;i < str1.length(); i++) {
06                     str2 = str1.charAt(i) + str2;
07               }
08               System.out.println(str2);
09         }
10   }



StringBuffer and StringBuilder
Exercise - Palindromes
Palindromes are words or phrases that are spelt the same forwards as backwards (eg noon). Use
String and StringBuilder (reverse method) to write a very simple palindrome tester. Try it out with
the burger flipper's motto: "stressed no tips spit on desserts".


Tokenizing
Tokenizing is the process of splitting text into small pieces (called tokens). The splitting is done at
delimiters in the text. There are two common ways of tokenizing: the String split() method, and the
Scanner class.

Example – Using the String split() Method to Reverse a string by word
01   public class Reverse {
02         public static void main(String[] args) {
03               String str = "one two three four five six";
04               String[] results = str.split(" ");
05               for (int i = (results.length - 1); i >= 0; i--) {
06                        System.out.print(results[i] + " ");
07                  }
08                  System.out.println();
09          }
10   }

Try out this example that uses the String split() method. In line 3 a String object is created. In line 4
the split() method is called on that string with a space passed as the delimeter. The split method
returns an array of strings. This array will be in the order they were split out of the original string.
Lines 5 - 7 form a loop that reads the entire array from end to beginning and outputting the strings
read. Hence the word order is reversed.

The split() method gets rather more interesting when you consider that the argument that you pass it
a regular expression string. That is, the argument can be any string that is a valid regular expression
(look up the Pattern class in JavaDocs to see a definition of available regular expression patterns).

The regular expression syntax for having multiple characters as delimeters is to group them
together in square brackets, eg [ ,.:] will split the string on a space, comma, full-stop, or colon.
Try experimenting with the above example:

01   public class Reverse {
02         public static void main(String[] args) {
03               String str = "one two,three.four:five+six";
04               String[] results = str.split(" ,.:");
05               for (int i = (results.length - 1); i >= 0; i--) {
06                     System.out.print(results[i] + " ");
07               }
08               System.out.println();
09         }
10   }

Work out what the output of the above is before you try it out.


Example - Using the Scanner Class
01   import java.util.Scanner;
02   class ScanDem {
03         public static void main(String[] args) {
04               boolean b;
05               int i;
06               String o;
07               Scanner s = new Scanner(args[0]);
08               s.useDelimiter("[,;]");
09               while (s.hasNext()) {
10                      if (s.hasNextInt()) {
11                            i = s.nextInt();
12                            System.out.println("int = " + i);
13                      } else if (s.hasNextBoolean()) {
14                            b = s.nextBoolean();
15                            System.out.println("boolean = " + b);
16                      } else {
17                            o = s.next();
18                            System.out.println("other = " + o);
18                      }
20               }
21         }
22   }
This example takes the first command line argument and tokenizes it using either a comma or a
semi-colon as the delimiter. Tokens are extracted as either int, boolean, or String.

Line 7 creates a Scanner object, passing it a String (the command line argument) to be tokenized.
Scanner objects can also be created with files or streams.

Line 8 sets the delimiter(s) to use. The default delimiter is whitespace, but this can be changed
using the useDelimiter() method. Here the regex string [,;] sets it to use commas and semi-
colons.

Scanner has a hasNext() method that returns true if there are any more tokens. This method
doesn't actually remove the token from the Scanner object. It is useful for setting up a loop to get all
of the tokens one after another. Lines 9 - 20 form such a loop.

Scanner also has a number of hasNextXXX() methods, where XXX is a primitive type. Line 10 uses
hasNextInt() to check if the Scanner object has another token and that token can be formatted to
an int. Line 13 uses hasNextBoolean() to check if the Scanner object has another token and that
token can be formatted to a boolean.

The hasNextXXX() methods do not take tokens out of the scanner. The set of methods nextXXX()
do this. Line 11 uses nextInt() to remove a previously identified int token (throws an
InputMismatchException if the token isn't an int). Similarly line 14 uses nextBoolean().

Line 17 uses next() to remove the next token no matter what it represents and return it as a string.

Experiment with this code example. Try modifying it to tokenize a string that contains several
floating-point numbers.


Finding Text
The Java Pattern and Matcher classes make finding little bits of text in big bits of text easy.

First you create a Pattern object that represents what you are looking for. You define what you are
looking for using a regex string. The Pattern object is created by compiling the regex string (using
Pattern's compile() method).

Next you create a Matcher object that will match the pattern against some given input. This is done
by calling the matcher() method of the pattern object, passing it the text to be searched.

Here is example code (renamed) from the study guide p483:

01   import java.util.regex.*;
02
03   public class Finding {
04         public static void main(String[] args) {
05               Pattern p = Pattern.compile(args[0]);
06               Matcher m = p.matcher(args[1]);
07               boolean b = false;
08               System.out.println("Pattern is " + m.pattern());
09               while (b = m.find()) {
10                     System.out.println(m.start() + " " + m.group());
11                  }
12          }
13    }

This application takes two command-line arguments. The first is the regex string that defines what
is being searched for; the second is a string to be searched. Use this application to see what various
regex strings define, try the following add some of your own):

Regex           Specifies:
fred




[fred]




.




...




\d+




Dates, Numbers, and Currency                      (p457-471)
Example - Formatting Dates and Times
01   import java.util.*;
02   import java.text.*;
03
04   public class DateFormat1 {
05         public static void main(String[] args) {
06               Calendar c = Calendar.getInstance();
07               c.set(2007, 2, 14, 14, 30, 00);
08               Date d = c.getTime();
09               DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
10               System.out.println(df.format(d));
11               DateFormat tf = DateFormat.getTimeInstance(DateFormat.FULL);
12               System.out.println(tf.format(d));
13               DateFormat dtf = DateFormat.getDateTimeInstance(DateFormat.FULL,
14                                                    DateFormat.FULL);
15               System.out.println(dtf.format(d));
16         }
17   }
18

The code above uses the DateFormat class (from java.text) to format a date.

Line 6 gets a Calendar object. A constructor can't be used for Calendar because the object you get
is actually of a subclass of Calendar determined by the version of your JVM. Hence the
getInstance() method is used to get the object that can be polymorhically referenced as a
Calendar.

Line 7 sets the date and time of the Calendar object. See the JavaDocs for the Calendar class for a
list of the overloaded set() methods. Line 8 converts the Calendar object to a Date object (which
stores milliseconds since 1st Jan 1970). This Date object is then formatted in different ways.

Lines 9 + 10 output a formatted date. Lines 11 + 12 output a formatted time. Lines 13 - 15 output a
formatted date and time. In each case the FULL format is used. Experiment with the other available
formats (SHORT, MEDIUM, LONG).

Example - Internationalising Dates and Times
Different cultures format dates, times, and numbers differently. Java identifies cultures using the
Locale class. A Locale is specified as a language and a country pair. For example English/USA is a
different locale from English/UK. A Locale object can be constructed using language and country
codes, or just a language code in which case you get the default for the country. Classes that format
dates, times, and numbers can optionally be passed Locale objects when they are created.

01   import java.util.*;
02   import java.text.*;
03
04   public class DateFormat2 {
05         public static void main(String[] args) {
06               Calendar c = Calendar.getInstance();
07               c.set(2007, 2, 14, 14, 30, 00);
08               Date d = c.getTime();
09               Locale locDE = new Locale("de", "ch");
10               DateFormat dfDE = DateFormat.getDateInstance(DateFormat.FULL,
11                                                               locDE);
12               System.out.println(dfDE.format(d));
13               Locale locFR = new Locale("fr");
14                  DateFormat dfFR = DateFormat.getDateInstance(DateFormat.FULL,
15                                                                  locFR);
16                  System.out.println(dfFR.format(d));
17          }
18   }

The above formats a date in Swiss German and in French. Explore the world!


Example - Internationalising Numbers
01   import java.util.*;
02   import java.text.*;
03
04   public class NumberFormat1 {
05         public static void main(String[] args) {
06               double d = 1234.56789;
07               Locale locDE = new Locale("de");
08               NumberFormat nf = NumberFormat.getInstance(locDE);
09               nf.setMaximumFractionDigits(4);
10               System.out.println(nf.format(d));
11         }
12   }

This example shows that German speaking people use a comma as the decimal separator and a dot
as the thousands separator, ie the opposite to English speaking people!

Here we use an instance of NumberFormat to format our numbers. It can be created using a Locale
object, similarly to DateFormat above. The default number of digits after the decimal point is 3, but
this can be changed using the setMaximumFractionDigits() method (line 9). Note that numbers
are rounded rather than truncated.

Note that the JavaDocs for NumberFormat only list format() methods that take longs or doubles.
These are all that are needed as any other arthmetic primitive can be promoted to either long or
double.


Example - Internationalising Currency
01   import java.util.*;
02   import java.text.*;
03
04   public class CurrencyFormat1 {
05         public static void main(String[] args) {
06               double d = 1234.56789;
07               Locale locDE = new Locale("de");
08               NumberFormat nf = NumberFormat.getCurrencyInstance(locDE);
09               System.out.println(nf.format(d));
10         }
11   }

This example is very similar to the number formatting example. Currency is automatically rounded
to 2 decimal places and a currency symbol is prepended. In this case it would be the euro symbol (if
only my command prompt was set up to display it properly!).

				
DOCUMENT INFO