Use a NumberFormat
subclass.
There are several reasons why Java doesn’t provide the
traditional
printf
/
scanffunctions from the C programming language. First, these
depend on variable-length argument lists, which makes strict type
checking impossible. Second and more importantly, they mix together
formatting and input/output in a very inflexible way. Programs
using
printf
/
scanf
can be very hard to internationalize, for example.
JDK 1.1 introduced a new package,
java.text
, which is full of formatting routines as
general and flexible as anything you might imagine. As with
printf, there is an involved formatting
language, described in the Javadoc page. Consider the presentation of
long
numbers. In North America, the number one thousand twenty-four and a
quarter is written 1,024.25, in most of Europe it is 1 024.25, and in
some other part of the world it might be written 1.024,25. Not to
mention how currencies and percentages get formatted! Trying to keep
track of this yourself would drive the average small software shop
around the bend rather quickly.
Fortunately, the java.text
package includes a
Locale
class, and, furthermore, the Java runtime automatically sets a
default Locale
object based on the user’s
environment; e.g., on the Macintosh and MS-Windows, the user’s
preferences; on Unix, the user’s environment variables. (To
provide a non-default locale, see Section 14.9.) To
provide formatters customized for numbers, currencies, and
percentages, the
NumberFormat
class has static factory
methods that normally return a
DecimalFormat
with the correct pattern already
instantiated. A DecimalFormat
object appropriate
to the user’s locale can be obtained from the factory method
NumberFormat.getInstance( )
and manipulated using set methods. The
method setMinimumIntegerDigits( )
, a bit surprisingly, turns out
to be the easy way to generate a number format with leading
zeros. Here is an
example:
import java.text.*; import java.util.*; /* * Format a number our way and the default way. */ public class NumFormat2 { /** A number to format */ public static final double data[] = { 0, 1, 22d/7, 100.2345678 }; /** The main (and only) method in this class. */ public static void main(String av[]) { // Get a format instance NumberFormat form = NumberFormat.getInstance( ); // Set it to look like 999.99[99] form.setMinimumIntegerDigits(3); form.setMinimumFractionDigits(2); form.setMaximumFractionDigits(4); // Now print using it. for (int i=0; i<data.length; i++) System.out.println(data[i] + " formats as " + form.format(data[i])); } }
This prints the contents of the array using the
NumberFormat
instance form
:
$ java NumFormat2 0.0 formats as 000.00 1.0 formats as 001.00 3.142857142857143 formats as 003.1429 100.2345678 formats as 100.2346 $
You can also construct a
DecimalFormat
with a particular pattern, or change the
pattern dynamically using applyPattern( )
. The
pattern characters are shown in Table 5-2.
Table 5-2. DecimalFormat pattern characters
Character |
Meaning |
---|---|
|
Numeric digit (leading zeros suppressed) |
|
Numeric digit (leading zeros provided) |
|
Locale-specific decimal separator (decimal point) |
|
Locale-specific grouping separator (comma in English) |
|
Locale-specific negative indicator (minus sign) |
|
Shows the value as a percentage |
|
Separates two formats: the first for positive and the second for negative values |
|
Escapes one of the above characters so it appears |
Anything else |
Appears as itself |
The NumFormatTest
program uses
one DecimalFormat
toprint a
number with only two decimal places, and a second to format the
number according to the default locale:
// NumFormatTest.java /** A number to format */ public static final double intlNumber = 1024.25; /** Another number to format */ public static final double ourNumber = 100.2345678; NumberFormat defForm = NumberFormat.getInstance( ); NumberFormat ourForm = new DecimalFormat("##0.##"); // toPattern( ) shows the combination of #0., etc // that this particular local uses to format with System.out.println("defForm's pattern is " + ((DecimalFormat)defForm).toPattern( )); System.out.println(intlNumber + " formats as " + defForm.format(intlNumber)); System.out.println(ourNumber + " formats as " + ourForm.format(ourNumber)); System.out.println(ourNumber + " formats as " + defForm.format(ourNumber) + " using the default format");
This program prints the given pattern and then formats the same number using several formats:
$ java NumFormatTest defForm's pattern is #,##0.### 1024.25 formats as 1,024.25 100.2345678 formats as 100.23 100.2345678 formats as 100.235 using the default format $
18.118.31.67