Number formats also handle input. When used for input, a number format converts a string in the appropriate format to a binary number, achieving more flexible conversions than you can get with the methods in the type wrapper classes (like `Integer.parseInt( )`). For instance, a percent format `parse( )` method can interpret 57% as 0.57 instead of 57. A currency format can read (12.45) as -12.45.

There are three `parse( )` methods in the `NumberFormat` class. All do roughly the same thing:

public Number parse(String text) throws ParseException public abstract Number parse(String text, ParsePosition parsePosition) public final Object parseObject(String source, ParsePosition parsePosition)

The first `parse( )` method attempts to parse a number from the given text. If the text represents an integer, its returned as an instance of `java.lang.Long`. Otherwise, its returned as an instance of `java.lang.Double`. If a string contains multiple numbers, only the first one is returned. For instance, if you parse "32 meters" youll get the number 32 back. Java throws away everything after the number finishes. If the text cannot be interpreted as a number in the given format, a `ParseException` is thrown.

The second `parse( )` method specifies where in the text parsing starts. The position is given by a `ParsePosition` object. This is a little more complicated than using a simple `int` but does have the advantage of allowing one to read successive numbers from the same string. The third `parse( )` method merely invokes the second. Its declared to return `Object` rather than `Number` so that it can override the method of the same signature in `java.text.Format`. If you know you
e working with a `NumberFormat` rather than a `DateFormat` or some other nonnumeric format, theres no reason to use it.

The `java.text.ParsePosition` class has one constructor and two public methods:

public ParsePosition(int index) public int getIndex( ) public void setIndex(int index)

This whole class is just a wrapper around a position, which is set by the constructor and the `setIndex( )` method and returned by the `getIndex( )` method. As a `NumberFormat` parses a string, it updates the associated `ParsePosition`s index. Thus, when passed into a `parse( )` method, the `ParsePosition` contains the index where parsing will begin. When the `parse( )` method returns, the `ParsePosition` contains the index immediately after the last character parsed. If parsing fails, the parse position is unchanged.

Some number formats can only read integers, not floating-point numbers. The `isParseIntegerOnly( )` method returns `TRue` if this is the case or `false` otherwise.

public boolean isParseIntegerOnly( ) public void setParseIntegerOnly(boolean value)

The `setParseInteger( )` method lets you specify that the format should only parse integers. If a decimal point is encountered, parsing should stop.

Example 21-8 is a simple program of the sort thats common in CS 101 courses. The assignment is to write a program that reads a number entered from the command line and prints its square root. Successive numbers are read until a negative number is entered, at which point the program halts. Although this is a very basic exercise, its relatively complex in Java because Java separates string parsing from basic I/O. Nonetheless, while it may not be suitable for the first weeks homework, students should be able to handle it by the end of the semester.

import java.text.*; import java.io.*; public class RootFinder { public static void main(String[] args) { Number input = null; try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); NumberFormat nf = NumberFormat.getInstance( ); while (true) { System.out.println("Enter a number (-1 to quit): "); String s = br.readLine( ); try { input = nf.parse(s); } catch (ParseException ex) { System.out.println(s + " is not a number I understand."); continue; } double d = input.doubleValue( ); if (d < 0) break; double root = Math.sqrt(d); System.out.println("The square root of " + s + " is " + root); } } catch (IOException ex) {System.err.println(ex);} } } |

Heres a sample run:

$java RootFinderEnter a number (-1 to quit): 87 The square root of 87 is 9.327379053088816 Enter a number (-1 to quit): 3.151592 The square root of 3.151592 is 1.7752723734683644 Enter a number (-1 to quit): 2,345,678 The square root of 2,345,678 is 1531.5606419596973 Enter a number (-1 to quit): 2.998E+8 The square root of 2.998E+8 is 1.7314733610425546 Enter a number (-1 to quit): 299800000 The square root of 299800000 is 17314.733610425545 Enter a number (-1 to quit): 0.0 The square root of 0.0 is 0.0 Enter a number (-1 to quit): four four is not a number I understand. Enter a number (-1 to quit): 4 The square root of 4 is 2.0 Enter a number (-1 to quit): (12) (12) is not a number I understand. Enter a number (-1 to quit): -1

These results tell you a few things about Javas default number format in the locale where I ran it (U.S. English). First, it doesn understand exponential notation. The square root of 2.998E+8 is not 1.7314733610425546; its 1.7314733610425546E+4. The number format parsed up to the first character it didn recognize (E) and stopped, thus returning the square root of 2.998 instead. You can also see that this number format doesn understand negative numbers represented by parentheses or words like "four." On the other hand, it can parse numbers with thousands separators like 2,345,678. This is more than the I/O libraries in most other languages can do. With the appropriate, nondefault number format, Java could parse (12), four, and 2.998E+8 as well.