9.2 Writing Formatted Output
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.NOTEA 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.
9.2.1 How do I do that?
First, let's deal with the easy stuffthis new class has some simple methods
to let you find out how it's configured:
There is also a close( ) method, which, unsurprisingly, closes the formatter
// 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( );
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( ):
While these methods return the object they're working on, it's common
// 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);
to not assign this return value, and merely discard it instead. This
method works, as shown here (in a simple example):
NOTEIf you're unclear
StringBuilder sb = new StringBuilder( );
Formatter formatter = new Formatter(sb);
formatter.format("Remaining account balance: $%.2f", balance);
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
9.2.1.1 Types
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);
NOTEIf 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. |
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 |
such as this, but now you've got all the conversion codes at your fingertips.
9.2.1.2 Precision
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.
9.2.1.3 Width
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).
|
9.2.1.4 Argument
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:
Here, the < argument is used to indicate that the previous argument
formatter.format("Remaining account balance: $%6.2f"+
"(Today's total balance: $%<8.2f)", balance);
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:
You can also explicitly refer to an argument by its position, using the
formatter.format("Date: %tD%nTime: %<tr%n", System.currentTimeMillis( ));
syntax [arg-number]$. Thus, you could refer to the second argument in
the list with %2$.
9.2.1.5 Flags
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:
In this example, two flags are used: the parenthetical ((), and the comma
formatter.format("Remaining account balance: $%(,6.2f"+
"(Today's total balance: $%(,<8.2f)", balance);
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. |
works in conjunction
with %s and
%S if the
argument
implements
java.util.
Formattable.
9.2.1.6 Output
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.NOTEIf you've chosen a
stream as your
sink, then the
output occurs as
you format it .