Newer
Older
<chapter annotations="slide" version="5.1"
xml:id="sd1_workingWithNumbers_chap"
xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:ns="http://docbook.org/ns/transclusion"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<title>Working with Numbers</title>
<section xml:id="sd1_numbers_sect_boxAndUnbox">
<title>Boxing and Unboxing</title>
<figure xml:id="sd1_numbers_fig_stack">
<title><classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Stack.html">Stack</classname>
of integer values</title>
<informaltable border="0">
<td valign="top"><programlisting language="java">final Stack<Integer> values = new Stack<>();
values.push(3);
values.push(1);
values.push(10);
while (!values.empty()) {
final int i = values.pop();
System.out.println(i);
}</programlisting></td>
<td valign="top"><screen>10
1
3</screen></td>
</tr>
</informaltable>
</figure>
<figure xml:id="sd1_numbers_fig_collectionProperties">
<title><xref linkend="glo_Java"/> collection features</title>
<itemizedlist>
<listitem>
<para>Supports searching of objects based on:</para>
<itemizedlist>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#equals(java.lang.Object)">public
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html">Object</classname>
obj)</para>
</listitem>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode()">public
int hashCode()</methodname></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>Objects only, no primitive types!</para>
</listitem>
</itemizedlist>
</figure>
<figure xml:id="sd1_numbers_fig_stackBehindTheScenes">
<title>Behind the scenes</title>
<informaltable border="0">
<colgroup width="48%"/>
<colgroup width="50%"/>
<tr>
<td valign="top"><programlisting language="java">final Stack<Integer> values =
new Stack<>();
values.push(3);
values.push(1);
values.push(10);
while (!values.empty()) {
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
getClass().getTypeName());
}</programlisting></td>
<td valign="top"><screen>java.lang.Integer
java.lang.Integer
java.lang.Integer</screen></td>
</tr>
</informaltable>
</figure>
<figure xml:id="sd1_numbers_fig_boxingAndUnboxing">
<title><link
xlink:href="https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html">Boxing
and unboxing</link></title>
<informaltable border="0">
<colgroup width="50%"/>
<colgroup width="50%"/>
<tr>
<td valign="top"><programlisting language="none">int iPrimitive <co
linkends="sd1_numbers_fig_boxingAndUnboxing-1"
xml:id="sd1_numbers_fig_boxingAndUnboxing-1-co"/> = 7;
Integer iInteger = <co linkends="sd1_numbers_fig_boxingAndUnboxing-2"
xml:id="sd1_numbers_fig_boxingAndUnboxing-2-co"/>
iPrimitive;
int iPrimitiveFromInteger = <co linkends="sd1_numbers_fig_boxingAndUnboxing-3"
iInteger;</programlisting></td>
<td valign="top"><programlisting language="none">int iPrimitive <co
linkends="sd1_numbers_fig_conventional-1"
xml:id="sd1_numbers_fig_conventional-1-co"/> = 7;
Integer iInteger = <co linkends="sd1_numbers_fig_conventional-2"
xml:id="sd1_numbers_fig_conventional-2-co"/>
Integer.valueOf(iPrimitive);
int iPrimitiveFromInteger = <co linkends="sd1_numbers_fig_conventional-3"
iInteger.intValue();</programlisting></td>
</tr>
</informaltable>
<informaltable role="slideExclude" border="1">
<colgroup width="50%"/>
<colgroup width="50%"/>
<tr>
<th>Boxing and unboxing</th>
<th><quote>Conventional</quote> <xref linkend="glo_Java"/></th>
</tr>
<tr>
<td valign="top"><calloutlist>
<callout arearefs="sd1_numbers_fig_boxingAndUnboxing-1-co"
xml:id="sd1_numbers_fig_boxingAndUnboxing-1">
<para>Defining a primitive <code language="java">int</code>
value.</para>
</callout>
<callout arearefs="sd1_numbers_fig_boxingAndUnboxing-2-co"
xml:id="sd1_numbers_fig_boxingAndUnboxing-2">
<para>Creating an instance of <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html">Integer</classname>
by means of boxing.</para>
</callout>
<callout arearefs="sd1_numbers_fig_boxingAndUnboxing-3-co"
xml:id="sd1_numbers_fig_boxingAndUnboxing-3">
<para>Assigning an <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html">Integer</classname>'s
value to a primitive <code language="java">int</code> by means
of unboxing.</para>
</callout>
</calloutlist></td>
<td valign="top"><calloutlist>
<callout arearefs="sd1_numbers_fig_conventional-1-co"
xml:id="sd1_numbers_fig_conventional-1">
<para>Defining a primitive <code language="java">int</code>
value.</para>
</callout>
<callout arearefs="sd1_numbers_fig_conventional-2-co"
xml:id="sd1_numbers_fig_conventional-2">
<para>Creating a new instance of <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html">Integer</classname>
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html#valueOf-int-">Integer
valueOf(int i)</methodname>.</para>
</callout>
<callout arearefs="sd1_numbers_fig_conventional-3-co"
xml:id="sd1_numbers_fig_conventional-3">
<para>Assigning an <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html">Integer</classname>'s
value to a primitive <code language="java">int</code> using the
<methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html#intValue--">int
intValue()</methodname> instance method.</para>
</callout>
</calloutlist></td>
</tr>
</informaltable>
<figure xml:id="sd1_numbers_fig_stackBoxUnboxVsConventional">
<informaltable border="0">
<colgroup width="50%"/>
<colgroup width="50%"/>
<tr>
<td valign="top"><programlisting language="java">final Stack<Integer> values
= new Stack<>();
values.push(Integer.valueOf(3));
values.push(Integer.valueOf(1));
values.push(Integer.valueOf(10));
while (!values.empty()) {
}</programlisting></td>
<td valign="top"><programlisting language="java">final Stack<Integer> values =
new Stack<>();
values.push(3);
values.push(1);
values.push(10);
while (!values.empty()) {
}</programlisting></td>
</tr>
</informaltable>
</figure>
</section>
<section xml:id="sd1_numbers_sect_numberParsing">
<title>Number Parsing</title>
<figure xml:id="sd1_numbers_fig_parseIntegerString">
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html">Integer</classname>
user input</title>
<informaltable border="0">
<colgroup width="65%"/>
<colgroup width="35%"/>
<tr>
<td valign="top"><programlisting language="java">String userInput = "dummyValue";
try (final Scanner scanner =
System.out.print("Enter an integer:");
userInput = scanner.nextLine();
System.out.println("You entered " + value);
} catch (final NumberFormatException e) {
System.out.println("Sorry, but '" +
userInput + "' is not an integer.");
}</programlisting></td>
<td valign="top"><screen>Enter an integer:-34
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
Sorry, but 'five' is
not an integer.</screen></td>
</tr>
</informaltable>
</figure>
<qandaset defaultlabel="qanda" xml:id="sd1_numbers_qanda_whyDummyString">
<title>Why using <code language="java">String userInput =
"dummyValue"</code>?</title>
<qandadiv>
<qandaentry>
<question>
<para>The former listing initializes the <code
language="java">userInput</code> variable using a default value
<code language="java">"dummyValue"</code>. Why is that?</para>
<orderedlist>
<listitem>
<para>The variable <code language="java">userInput</code> is
being assigned inside the <code language="java">try
{...}</code> block before being used in any assignment.</para>
</listitem>
<listitem>
<para>The <methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Scanner.html#nextLine--">Scanner.nextLine()</methodname>
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/NumberFormatException.html">NumberFormatException</classname>.
Thus the only way to enter the <code language="java">catch
{...}</code> clause is by executing of <code
language="java">Integer.parseInt(userInput)</code> yielding a
<classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/NumberFormatException.html">NumberFormatException</classname>
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
. But this execution happens <emphasis>after</emphasis>
assigning <code language="java">userInput =
scanner.nextLine()</code>.</para>
</listitem>
</orderedlist>
<para>So the dummy assignment <code language="java">String
userInput = "dummyValue"</code> seems to be redundant. Is that
true?</para>
</question>
<answer>
<para>Actually the <xref linkend="glo_Java"/> compiler is not
clever enough analyzing the <code language="java">try {...}</code>
block. It cannot detect the impossibility of an uninitialized
<code language="java">userInput</code> variable inside the <code
language="java">catch {...}</code> clause.</para>
<para>Since the possibility of am uninitialized <code
language="java">userInput</code> variable using just <code
language="java">String userInput;</code> causes a compile time
error <code>Variable 'userInput' might not have been
initialized</code>.</para>
<para>Thus <code language="java">String userInput = null</code>
would be appropriate as well since the value will actually never
be used.</para>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<figure xml:id="sd1_numbers_fig_parseIntegerToRadix">
<title>Parsing binary representation</title>
<informaltable border="0">
<colgroup width="50%"/>
<colgroup width="50%"/>
<tr>
<td valign="top"><programlisting language="java">final int value =
System.out.println("Value: " + value);</programlisting><screen>Value: 13</screen></td>
<td valign="top"><programlisting language="java">final int value =
Integer.parseInt("201", 2);
System.out.println("Value: " + value)</programlisting><screen>Exception in thread "main"
java.lang.NumberFormatException:
For input string: "201"
...
at de.hdm_stuttgart.sd1...</screen></td>
</tr>
</informaltable>
</figure>
<figure xml:id="sd1_numbers_fig_parseMethods">
<title>Standard parse methods</title>
<informaltable border="0">
<colgroup width="50%"/>
<colgroup width="50%"/>
<tr>
<td valign="top"><itemizedlist>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Byte.html#parseByte-java.lang.String-">parseByte()</methodname></para>
</listitem>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Short.html#parseShort-java.lang.String-">parseShort()</methodname></para>
</listitem>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html#parseInt-java.lang.String-">parseInt()</methodname></para>
</listitem>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Long.html#parseLong-java.lang.String-">parseLong()</methodname></para>
</listitem>
</itemizedlist></td>
<td valign="top"><itemizedlist>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Float.html#parseFloat-java.lang.String-">parseFloat()</methodname></para>
</listitem>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Double.html#parseDouble-java.lang.String-">parseDouble()</methodname></para>
</listitem>
<listitem>
<para><methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Boolean.html#parseBoolean-java.lang.String-">parseBoolean()</methodname></para>
</listitem>
</itemizedlist></td>
</tr>
</informaltable>
</figure>
<qandaset defaultlabel="qanda" xml:id="sd1_numbers_qanda_parseShortResult">
<title>Parsing <code language="java">short</code> values</title>
<qandadiv>
<qandaentry>
<question>
<para>Which outcome do you expect? Try to answer without prior
execution.</para>
<programlisting language="java">System.out.println(Short.parseShort("32767"));
System.out.println(Short.parseShort("32768"));</programlisting>
<para>Explain the result.</para>
</question>
<answer>
<para><code language="java"
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Short.html#MAX_VALUE">MAX_VALUE</code>
for primitive type <code language="java"
xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-B">short</code>
is <inlineequation>
<m:math display="inline">
<m:mrow>
<m:msup>
<m:mi>2</m:mi>
<m:mrow>
<m:mi>16</m:mi>
<m:mo>-</m:mo>
<m:mi>1</m:mi>
</m:mrow>
</m:msup>
<m:mo>-</m:mo>
<m:mi>1</m:mi>
</m:mrow>
</m:math>
</inlineequation> which equals 32767. Thus 32786 is no longer
assignment compatible. So the first line will execute well but the
second one yields a <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/NumberFormatException.html">NumberFormatException</classname>
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
at runtime :</para>
<screen>Value:32767
Exception in thread "main" java.lang.NumberFormatException:
Value out of range. Value:"32768" Radix:10 at
java.lang.Short.parseShort(Short.java:120)
at java.lang.Short.parseShort(Short.java:144)
at de.hdm_stuttgart.sd1.ParseShortTooBig.main(ParseShortTooBig.java:8)</screen>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<qandaset defaultlabel="qanda" xml:id="sd1_numbers_qanda_parseHexadecimal">
<title>Parsing <code language="java">short</code> values in hexadecimal
representation</title>
<qandadiv>
<qandaentry>
<question>
<para>An image processing application yields the following type of
data:</para>
<programlisting language="java">String[] values = {"C9", "AF3", "B"}; // Hexadecimal string values</programlisting>
<para>We are looking for a class method parsing these hex values
and converting them to <code language="java">short</code>:</para>
<programlisting language="java">/**
* Convert a numerical value given as hexadecimal string to
* its counterpart of type short. Example:
*
* "2B" equals 2 * 16 + 11 == 43
*
* @param input String containing hexadecimal value.
* @return the parsed short value.
*/
public static short getHexadecimal(final String input) {
...
return ...;
}</programlisting>
<para>The provided sample data may then be processed like:</para>
<programlisting language="java">final String[] values = {"C9", "AF3", "B"};
for (final String value: values) {
System.out.println(value + ": " + getHexadecimal(value));
}</programlisting>
<para>Result:</para>
<screen>C9: 201
AF3: 2803
B: 11</screen>
<tip>
<para>Have a look to the binary parse example and think about
representations.</para>
</tip>
</question>
<answer>
<para>Hexadecimal representation uses a radix value of 16 to be
passed to <methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Short.html#parseShort-java.lang.String-int-">short
parseShort(String s, int radix)</methodname>:</para>
<programlisting language="java">/**
* Convert a numerical value given as hexadecimal string to
* its counterpart of type short. Example:
*
* "2B" equals 2 * 16 + 11 == 43
*
* @param input String containing hexadecimal value.
* @return the parsed short value.
*/
public static short getHexadecimal(final String input) {
return Short.parseShort(input, 16);
}</programlisting>
</answer>
<answer>
<para><code language="java"
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Short.html#MAX_VALUE">MAX_VALUE</code>
for primitive type <code language="java"
xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-B">short</code>
is <inlineequation>
<m:math display="inline">
<m:mrow>
<m:msup>
<m:mi>2</m:mi>
<m:mrow>
<m:mi>16</m:mi>
<m:mo>-</m:mo>
<m:mi>1</m:mi>
</m:mrow>
</m:msup>
<m:mo>-</m:mo>
<m:mi>1</m:mi>
</m:mrow>
</m:math>
</inlineequation> which equals 32767. Thus 32786 is no longer
assignment compatible. So the first line will execute well but the
second one yields a <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/NumberFormatException.html">NumberFormatException</classname>
at runtime :</para>
<screen>Value:32767
Exception in thread "main" java.lang.NumberFormatException:
Value out of range. Value:"32768" Radix:10 at
java.lang.Short.parseShort(Short.java:120)
at java.lang.Short.parseShort(Short.java:144)
at de.hdm_stuttgart.sd1.ParseShortTooBig.main(ParseShortTooBig.java:8)</screen>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
</section>
<section xml:id="sd1_numbers_sect_NumberFormatting">
<title>Number Formatting</title>
<figure xml:id="sd1_numbers_fig_locale">
<title>Excerpt from <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Locale.html">java.util.Locale</classname></title>
<para>A Locale object represents a specific geographical, political, or
cultural region.</para>
<para>An operation that requires a Locale to perform its task is called
locale-sensitive and uses the Locale to tailor information for the
user.</para>
<para>For example, displaying a number is a locale-sensitive operation:
Numbers should be formatted according to the customs and conventions of
the user's native country, region, or culture.</para>
</figure>
<figure xml:id="sd1_numbers_fig_localeProperties">
<title><classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Locale.html">Locale</classname>
properties</title>
<itemizedlist>
<listitem>
<para>Language</para>
</listitem>
<listitem>
<para>Encoding</para>
</listitem>
<listitem>
<para>Country</para>
</listitem>
<listitem>
<para>Extensible</para>
</listitem>
</itemizedlist>
</figure>
<figure xml:id="sd1_numbers_fig_constructNumberFormat">
<title>Get a <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/text/NumberFormat.html">NumberFormat</classname>
<informaltable border="0">
<tr>
<td valign="top"><programlisting language="none">final NumberFormat standard = new DecimalFormat();
System.out.println(standard.format(<emphasis role="red">1234.5678</emphasis>));
final NumberFormat de =
DecimalFormat.getInstance(Locale.GERMANY);
System.out.println(de.format(<emphasis role="red">1234.5678</emphasis>));</programlisting></td>
<td valign="top"><screen><emphasis role="red">1234.5678</emphasis>
<emphasis role="red">1.234,568</emphasis></screen></td>
</tr>
</informaltable>
</figure>
<figure xml:id="sd1_numbers_fig_customFormat">
<title>Create a custom formatter</title>
<programlisting language="java">final DecimalFormatSymbols unusualSymbols =
new DecimalFormatSymbols(Locale.getDefault());
unusualSymbols.setDecimalSeparator(<emphasis role="red">'|'</emphasis>);
unusualSymbols.setGroupingSeparator(<emphasis role="red">'^'</emphasis>);
final String strange = "#,##0.###";
final DecimalFormat weirdFormatter = new DecimalFormat(strange, unusualSymbols);
weirdFormatter.setGroupingSize(4);
System.out.println(weirdFormatter.format(12345.678));</programlisting>
<screen>1<emphasis role="red">^</emphasis>2345<emphasis role="red">|</emphasis>678</screen>
</figure>
<qandaset defaultlabel="qanda"
xml:id="sd1_numbers_qanda_getAvailableLocales">
<title><classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Locale.html">Locale</classname>
definitions</title>
<qandadiv>
<qandaentry>
<question>
<para>Each <xref linkend="glo_JRE"/> ships with a set of available
<classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Locale.html">Locale</classname>
definitions. Write a simple program to get the following
list:</para>
<screen>160 locales available:
Locale: Arabic(ar_AE)
Locale: Arabic(ar_JO)
Locale: Arabic(ar_SY)
Locale: Croatian(hr_HR)
...
Locale: Indonesian(in_ID)
Locale: English(en_GB)</screen>
<tip>
<para>Read the documentation of <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Locale.html">Locale</classname>
to find appropriate methods.</para>
</tip>
</question>
<answer>
<programlisting language="java">System.out.println(Locale.getAvailableLocales().length + " locales available:");
for (final Locale l: Locale.getAvailableLocales()) {
System.out.println("Locale: " + l.getDisplayLanguage() + "(" + l + ")");
}</programlisting>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<qandaset defaultlabel="qanda"
xml:id="sd1_numbers_qanda_formatIntDoubleDate">
<title>Formatting <code language="java">int</code>, <code
language="java">double</code> and <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/time/LocalDate.html">LocaleDate</classname></title>
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
<qandadiv>
<qandaentry>
<question>
<para>Implement the following three overloaded class
methods:</para>
<programlisting language="java">/**
* Print an int value using the given locale. Example:
*
* Using Locale.GERMANY a value of 1234567 should appear as "1.234.567"
*
* @param value The value to be formatted.
* @param locale The locale to be used.
*/
static public void print(final int value, final Locale locale) {...}</programlisting>
<programlisting language="java">/**
* Print a double value using the given locale. Example:
*
* Using Locale.GERMANY a value of -123.456789 should appear as "-123,457"
*
* @param value The value to be formatted.
* @param locale The locale to be used.
*/
static public void print(final double value, final Locale locale) {...}</programlisting>
<programlisting language="java">/**
* Print a {@link LocalDate} value using the given locale. Example:
*
* Using Locale.GERMANY the 22-nd of december 2024 should appear as "22. Dezember 2024".
*
* @param value The value to be formatted.
* @param locale The locale to be used.
*/
static public void print(final LocalDate date, final Locale locale) {...}</programlisting>
<para>You may use them as:</para>
<programlisting language="java">for (final Locale locale : new Locale[]{Locale.GERMANY, Locale.JAPAN, Locale.US}) {
System.out.println("Locale " + locale.getDisplayCountry());
print(1234567, locale);
print(-123.456789, locale);
print(LocalDate.of(2024, Month.DECEMBER, 22), locale);
System.out.println("----------------------\n");
}</programlisting>
<para>The expected output reads:</para>
<screen>Locale Germany
1.234.567
-123,457
22. Dezember 2024
----------------------
Locale Japan
1,234,567
-123.457
2024/12/22
----------------------
Locale United States
1,234,567
-123.457
December 22, 2024
----------------------</screen>
<tip>
<itemizedlist>
<listitem>
<para>Read the <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/text/NumberFormat.html">NumberFormat</classname>
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/text/NumberFormat.html#getInstance-java.util.Locale-">static
NumberFormat getInstance(Locale inLocale)</methodname> in
particular. Also note its multiply overloaded
<methodname>String format(...)</methodname> methods partly
suiting your data type requirements.</para>
</listitem>
<listitem>
<para>Regarding dates you may want to consider <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/time/format/DateTimeFormatter.html">DateTimeFormatter</classname>
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/time/format/DateTimeFormatter.html#ofLocalizedDate-java.time.format.FormatStyle-">static
DateTimeFormatter ofLocalizedDate(FormatStyle
dateStyle)</methodname> method. Then read about class
<classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/time/format/FormatStyle.html">FormatStyle</classname>
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/time/format/DateTimeFormatter.html#withLocale-java.util.Locale-">DateTimeFormatter
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
withLocale(Locale locale)</methodname> method.</para>
</listitem>
</itemizedlist>
</tip>
</question>
<answer>
<para>Implementing the first two methods is relatively
simple:</para>
<programlisting language="java">/**
* Print an int value using the given locale. Example:
*
* Using Locale.GERMANY a value of 1234567 should appear as "1.234.567"
*
* @param value The value to be formatted.
* @param locale The locale to be used.
*/
static public void print(final int value, final Locale locale) {
final NumberFormat numberFormat = NumberFormat.getInstance(locale);
System.out.println(numberFormat.format(value));
}</programlisting>
<programlisting language="java">/**
* Print a double value using the given locale. Example:
*
* Using Locale.GERMANY a value of -123.456789 should appear as "-123,457"
*
* @param value The value to be formatted.
* @param locale The locale to be used.
*/
static public void print(final double value, final Locale locale) {
final NumberFormat numberFormat = NumberFormat.getInstance(locale);
System.out.println(numberFormat.format(value));
}</programlisting>
<para>Processing dates is a bit cumbersome:</para>
<programlisting language="java">/**
* Print a {@link LocalDate} value using the given locale. Example:
*
* Using Locale.GERMANY the 22-nd of december 2024 should appear as "22. Dezember 2024".
*
* @param value The value to be formatted.
* @param locale The locale to be used.
*/
static public void print(final LocalDate date, final Locale locale) {
final DateTimeFormatter dateFormat =
DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withLocale(locale);
System.out.println(dateFormat.format(date));
}</programlisting>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<figure xml:id="sd1_numbers_fig_polymorphicNumberParsing">
<title>Polymorphic number parsing</title>
<programlisting language="java">final NumberFormat de = NumberFormat.getInstance(Locale.GERMANY),
us = NumberFormat.getInstance(Locale.US);
de.parse("103.234"), de.parse("400.000,234"),
us.parse("103.234"), us.parse("400.000,234"),};
for (final Number n: values) {
System.out.println(n + "(" + n.getClass().getTypeName() + ")");
} catch (ParseException e) { ... }</programlisting>
400000.234(java.lang.Double)
103.234(java.lang.Double)
400(java.lang.Long)</screen>
</section>
<section xml:id="sd1_numbers_sect_WorkingwithMoney">
<title>Working with Money</title>
<figure xml:id="sd1_numbers_fig_floatLimitedPreceision">
<title>Limited <code language="java">float</code> precision</title>
<programlisting language="java">final float result = 0.99f - 0.1f -0.1f -0.1f;
System.out.println(result);</programlisting>
<screen>0.68999994</screen>
</figure>
<figure xml:id="sd1_numbers_fig_doubleLimitedPreceision">
<title>Limited <code language="java">double</code> precision</title>
<programlisting language="java">final double result = 0.99 - 0.1 -0.1 -0.1;
System.out.println(result);</programlisting>
<screen>0.6900000000000001</screen>
</figure>
<figure xml:id="sd1_numbers_fig_usingBigDecimal">
<title>Using <classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/math/BigDecimal.html">BigDecimal</classname></title>
<programlisting language="java">final BigDecimal zero_dot_99 = new BigDecimal("0.99");
final BigDecimal zero_dot_1 = new BigDecimal("0.1");
BigDecimal result = zero_dot_99.
subtract(zero_dot_1).
subtract(zero_dot_1).
subtract(zero_dot_1);
System.out.println(result);</programlisting>
<screen>0.69</screen>
</figure>
<figure xml:id="sd1_numbers_fig_usingBigDecimalFeatures">
<title><classname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/math/BigDecimal.html">BigDecimal</classname>
features</title>
<itemizedlist>
<listitem>
<para>Higher memory allocation hosting higher precision.</para>
</listitem>
<listitem>
<para>Immutable instances</para>
</listitem>
<listitem>
<para>Calculation performance penalty.</para>
</listitem>
<listitem>
<para>Clumsy interface.</para>
</listitem>
</itemizedlist>
</figure>
</section>
<section xml:id="sd1_numbers_sect_GeneratingRandomNumbers">
<title>Generating Random Numbers</title>
<figure xml:id="sd1_numbers_fig_random">
<title>Using <methodname
xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Math.html#random--">static
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
double random()</methodname></title>
<programlisting language="java">for (int i = 0; i < 10; i++) {
System.out.println(Math.random());
}</programlisting>
<screen>0.4754286988826202
0.0060114391743414375
...
0.9047785351372987
0.2516070321935864</screen>
</figure>
<figure xml:id="sd1_numbers_fig_randomSeed">
<title>Seeding a pseudo random generator</title>
<programlisting language="java">try(final Scanner scanner = new Scanner(System.in)) {
System.out.print("Enter an integer seed:");
final long seed = scanner.nextLong();
Random generator = new Random(seed);
for (int i = 0; i < 10; i++) {
System.out.print(generator.nextBoolean() + " ");
}
}</programlisting>
<screen>Enter an integer seed:4237549835735
false true true true false false false true false true</screen>