Once you've got your Formatter instance, I'm going to make the rather silly leap to assuming you want to use it. The best way to do this is through the format( ) method.
NOTE
A sink is a term used to refer to where output goes tosort of a collection bin. Often this is some output mechanism, like an Output-Stream, or an object that can later output what is in the sink, such as StringBuffer.
First, let's deal with the easy stuffthis new class has some simple methods to let you find out how it's configured:
// Return the locale for this Formatter public Locale locale( ); // Returns the last thrown IOException by the sink public IOException ioException( ); // Returns the sink for output public Appendable out( );
There is also a close( ) method, which, unsurprisingly, closes the formatter when you're done with output (which is particularly important when you're holding onto file resources).
The most interesting methods are the two versions of format( ):
// Notice the varargs for multiple object arguments public Formatter format(String format, Object... args); // Same as above, but with a Locale public Formatter format(Locale l, String format, Object... args);
While these methods return the object they're working on, it's common to not assign this return value, and merely discard it instead. This method works, as shown here (in a simple example):
StringBuilder sb = new StringBuilder( ); Formatter formatter = new Formatter(sb); formatter.format("Remaining account balance: $%.2f", balance);
NOTE
If you're unclear on how varargs or the Object... notation works, check out Chapter 5.
This example would output the value in the balance variable, as a floating point number, with two decimal places allowed. For those of you used to methods like printf( ) in C, this is no big deal. For those of you who didn't grow up on a steady diet of structs, this is still probably a bit odd.
First, the String to output is passed inno big deal here. However, within that String are several items that are dynamicnot known until run-time. In the previous example, the dynamic item is the value of balance. Anytime you need to insert dynamic data like that, the % indicates that a value will be supplied, in the argument list (remember Object...), to be inserted into the String. The characters after the % indicate how that value should be formatted:
%[argument][flags][width][.precision]type
The only requirement here is type , so the example you saw previously could be written in its simplest format as shown here:
formatter.format("Remaining account balance: $%f", balance);
NOTE
If uppercase and lowercase versions are listed (%s, %S), the uppercase variant produces the same output as the lowercase variant, except that all lowercase letters are converted to uppercase.
Table 9-1 is a rundown of all the available types. Note that these are actually conversion typesif the value supplied is not in the specified format, a conversion is attempted.
Conversion symbol | Description |
---|---|
%% | Escape sequence to allow printing of % in a String. |
%a, %A | Formats the value as a floating-point number in exponential notation, using base-16 for the decimal part, and base-10 for the exponent part. Arguments must be Float, Double, or BigDecimal. |
%b, %B | Formats the value as either "true" or "false" (or "TRUE" or "FALSE", for %B). For boolean values, this works as expected. For all other values, any non-null value is "true", while null values are "false". |
%c, %C | Formats the value supplied as a single character. Supplied value must be a Byte, Short, Character, or Integer. |
%d | Formats the value as a base-10 integer. Arguments must be Byte, Short, Integer, Long, or BigInteger. |
%e, %E | Formats the value as a base-10 floating-point number, using exponential notation. Arguments must be Float, Double, or BigDecimal. |
%f | Formats the value as a floating-point number in base-10, without exponential notation. Arguments must be Float, Double, or BigDecimal. |
%g, %G | Formats the value as a base-10 floating point number, with no more than 6 significant digits (if precision is not supplied). Arguments must be Float, Double, or BigDecimal. |
%h, %H | Formats the value as a hexadecimal representation of the value's hashcode. |
%n | Outputs the line separator for the platform. |
%o | Formats the value as a base-8 octal integer. Arguments must be Byte, Short, Integer, Long, or BigInteger. |
%s, %S | Formats the value supplied as a String, usually through calling toString( ) on the object. |
%t, %T | The prefix for all date/time conversions. All date/time types listed in Table 9-2) requires a Date, Calendar, or Long argument. Note that the t or T determines uppercase/lowercase, rather than the case of the letter following the t/T. |
%x, %X | Formats the value as a base-16 hexadecimal integer. Arguments must be Byte, Short, Integer, Long, or BigInteger. |
Because date/time are a bit of a special case, they are listed in their own table, Table 9-2.
Conversion symbol | Description |
---|---|
%tA | The locale-specific full name of the day of the week |
%ta | The locale-specific abbreviation of the day of the week |
%tB | The locale-specific full name of the month |
%tb | The locale-specific abbreviation for the month |
%tC | The century, from 00 to 99 (by dividing by 100) |
%tc | The complete date and time |
%tD | The date in short numeric form |
%td | The day of the month, as a two-digit number01 to 31 |
%tE | The date as milliseconds since midnight, UTC, on Jan. 1st, 1970 |
%te | The day of the month, without leading zeroes1 to 31 |
%tF | The numeric day in ISO8601 format |
%tH | Two-digit hour of the day, using a 24-hour clock00 to 23 |
%th | The abbreviated month name (identical to %tb) |
%tI | Two-digit hour of the day using a 12-hour clock01 to 12 |
%tj | Three digit day of the year001 to 366 |
%tk | Hour of the day on a 24-hour clock0 to 23 |
%tL | Three-digit milliseconds within the second000 to 999 |
%tl | Hour of the day on a 12-hour clock1 to 12 |
%tM | Two-digit minute within the hour00 to 59 |
%tm | Two-digit month of the year01 to 12 (01 to 13 for lunar calendars) |
%tN | Nanosecond within the second, expressed as nine digits |
%tp | Locale-specific morning or afternoon indicator |
%tR | The hour and minute on a 24-hour clock |
%tr | The hour, minute, and second on a 24-hour clock |
%tS | Two-digit seconds within the minute00 to 59 |
%ts | Seconds since the beginning of the epoch |
%tT | Time in hours, minutes, and seconds, using a 24-hour format |
%tY | Four-digit (at least) year |
%ty | Last two digits of the year00 to 99 |
%tZ | Abbreviation for the timezone |
%tZ | The timezone as a numeric offset from GMT |
I know that's a lot of dry detail, especially for a down-and-dirty book such as this, but now you've got all the conversion codes at your fingertips.
You can add an optional precision indicator to your format string:
formatter.format("Remaining account balance: $%.2f", balance);
By adding .2, it indicates that the value of balance should be given two decimal places of precision, ensuring you get a number like 2510.00 instead of 2510. .2 in this case fills the precision spot in the syntax list. Here are a few rules that apply:
For %e, %E, and %f, the default precision is 6.
For %g and %G, the precision is the total number of significant digits to be displayed.
For %s, %h, and %b (and their uppercase variants), the precision determines the maximum characters output.
|
Trailing zeros are always added as needed, to match the specified (or default) precision, for numeric types.
In addition to precision, the total minimum number of characters to be produced can be set through width :
formatter.format("Remaining account balance: $%6.2f", balance);
Here, the balance will be shown with at least six digits of total characters. If the formatted output is less than the specified width, zeroes are added as padding on the left (values are right-justified). A width can be specified for any conversion type other than %n (which isn't a true conversion type anywayit's a line separator).
|
By default, calls to format( ) (and printf( ), detailed in "Using the printf( ) Convenience Method") match each conversion with the arguments supplied to the method, in order, one after another. However, you can optionally change that behavior with an argument indicator:
formatter.format("Remaining account balance: $%6.2f"+ "(Today's total balance: $%<8.2f)", balance);
Here, the < argument is used to indicate that the previous argument should be used (again), rather than continuing on. This is a clever way to reuse arguments without listing them in the argument list multiple times. It also allows the same argument to be formatted in different ways:
formatter.format("Date: %tD%nTime: %<tr%n", System.currentTimeMillis( ));
You can also explicitly refer to an argument by its position, using the syntax [arg-number]$. Thus, you could refer to the second argument in the list with %2$.
The final option you have is to specify one or more flags, which are non-numeric characters that appear just before width and precision indicators:
formatter.format("Remaining account balance: $%(,6.2f"+ "(Today's total balance: $%(,<8.2f)", balance);
In this example, two flags are used: the parenthetical ((), and the comma indicator (,). The parenthetical indicates that negative values should be placed in parentheses, and the comma instructs the formatter to insert commas (or any other local-specific grouping separator) between digits. So, output from these instructions would look like $(8,134.28), or $(008,134.28), depending on the width specified. Table 9-3 has the complete list of valid flags.
Flag | Description |
---|---|
- | Indicates that the formatted value should be left-justified, based on width . |
# | Indicates that the formatted output should appear in alternate form. For %o, this means a leading 0. For %x and %X, output will include a leading 0x (0X). For %s and %S, the flag is passed on to the object's formatTo( ) method. |
+ | Indicates that numeric output should always include a sign (+ or -). |
' ' | The space value (which is hard to show in a book) indicates that non-negative values should be prefixed with a space. This is generally used for alignment with negative numbers. |
( | Indicates that negative numbers should appear in parentheses. |
0 | Indicates that numeric values should be padded on the left. |
, | Indicates that the locale-specific grouping character should be used for numeric values. |
NOTE
The # flag only works in conjunction with %s and %S if the argument implements java.util. Formattable.
It's worth saying that with all of this talk of formatting, nothing is output until you actually use your sink:
System.out.println(sb.toString( ));
It's easy to do lots of great formatting work, and then forget to actually output the results. There are also several other ways to output formatted strings like this, covered in the following recipes.
NOTE
If you've chosen a stream as your sink, then the output occurs as you format it .