{"id":7390,"date":"2019-11-06T09:00:42","date_gmt":"2019-11-06T08:00:42","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=7390"},"modified":"2025-04-07T13:05:32","modified_gmt":"2025-04-07T11:05:32","slug":"string-in-int-umwandeln-besonderheiten-fallstricke","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/string-in-int-umwandeln-besonderheiten-fallstricke\/","title":{"rendered":"Java: String in int umwandeln - Besonderheiten und Fallstricke"},"content":{"rendered":"\n<p>Im <a href=\"\/de\/java\/int-in-string-umwandeln-schnellster-weg\/\">vorherigen Artikel<\/a> habe ich euch gezeigt, dass <code>\"\" + i<\/code> die schnellste Methode ist, um in Java ein int in einen String umzuwandeln. Und zwar durchgehend von Java 7 bis Java 14.<\/p>\n\n\n\n<p>Heute erfahrt ihr, was bei der entgegengesetzten Richtung, also beim Parsen von Strings in ints zu beachten ist. Den Quellcode zum Artikel findet ihr in <a href=\"https:\/\/github.com\/SvenWoltmann\/string-to-int-benchmarks\" target=\"_blank\" rel=\"noopener\">meinem GitHub-Repository<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"zahlen-im-dezimalsystem-parsen\">Zahlen im Dezimalsystem parsen<\/h2>\n\n\n\n<p>Schauen wir uns zun\u00e4chst einmal die M\u00f6glichkeiten an, ein String in ein int (bzw. Integer) zu parsen. Bis Java 7 gibt es folgende Varianten:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>int i = Integer.parseInt(s);<\/code> (\u2192 <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Integer.html#parseInt-java.lang.String-\" target=\"_blank\">JavaDoc<\/a>)<\/li>\n\n\n\n<li><code>Integer i = Integer.valueOf(s);<\/code> (\u2192 <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Integer.html#valueOf-java.lang.String-\" target=\"_blank\" rel=\"noopener\">JavaDoc<\/a>)<\/li>\n<\/ul>\n\n\n\n<p>Die zweite Methode ruft intern die erste Methode auf und verpackt das Ergebnis in ein Integer-Objekt.<\/p>\n\n\n\n<p>Der \u00fcbergebene String darf nur Ziffern enthalten, optional mit einem vorangestellten Plus oder Minus-Zeichen. Folgendes ist also erlaubt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Integer.parseInt(\"47\")<\/code><\/li>\n\n\n\n<li><code>Integer.parseInt(\"+86400\")<\/code><\/li>\n\n\n\n<li><code>Integer.parseInt(\"-1\")<\/code><\/li>\n<\/ul>\n\n\n\n<p>Folgende Strings hingehen d\u00fcrfen nicht \u00fcbergeben werden und f\u00fchren zu NumberFormatExceptions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Integer.parseInt(\"\")       \/\/ Leerer String nicht erlaubt<\/code><\/li>\n\n\n\n<li><code>Integer.parseInt(\" 1\")     \/\/ Leerzeichen nicht erlaubt<\/code><\/li>\n\n\n\n<li><code>Integer.parseInt(\"3,14\")   \/\/ Komma nicht erlaubt<\/code><\/li>\n\n\n\n<li><code>Integer.parseInt(\"1.000\")  \/\/ Tausender-Punkt nicht erlaubt<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"hexadezimal-und-binaerzahlen-parsen\">Hexadezimal- und Bin\u00e4rzahlen parsen<\/h2>\n\n\n\n<p>Die zuvor genannten Methoden parsen Dezimalzahlen. Um andere Zahlensysteme zu parsen, stehen folgende \u00fcberladene Methode zur Verf\u00fcgung:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>int i = Integer.parseInt(s, radix);<\/code> (\u2192 <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Integer.html#parseInt-java.lang.String-int-\" target=\"_blank\">JavaDoc<\/a>)<\/li>\n\n\n\n<li><code>Integer i = Integer.valueOf(s, radix);<\/code> (\u2192 <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Integer.html#valueOf-java.lang.String-int-\" target=\"_blank\">JavaDoc<\/a>)<\/li>\n<\/ul>\n\n\n\n<p>Der Parameter <code>radix<\/code> gibt dabei die Basis des Zahlensystems an. Eine hexadezimale Zahl parst man bspw. wie folgt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Integer.parseInt(\"CAFE\", 16)<\/code><\/li>\n<\/ul>\n\n\n\n<p>Und eine Bin\u00e4rzahl so:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Integer.parseInt(\"101111\", 2)<\/code><\/li>\n<\/ul>\n\n\n<div class=\"convertkit-form wp-block-convertkit-form\" style=\"\"><script async data-uid=\"1427197203\" src=\"https:\/\/happycoders.kit.com\/1427197203\/index.js\" data-jetpack-boost=\"ignore\" data-no-defer=\"1\" data-no-optimize=\"1\" nowprocket><\/script><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"signed-vs-unsigned-ints\">Signed vs. unsigned ints<\/h2>\n\n\n\n<p>In allen vorgenannten F\u00e4llen muss die zu parsende Zahl im Bereich <code>Integer.MIN_VALUE<\/code> (= -2<sup>31<\/sup> = -2.147.483.648) bis <code>Integer.MAX_VALUE<\/code> (= 2<sup>31<\/sup>-1 = 2.147.483.647) liegen.<\/p>\n\n\n\n<p>Interessant (um nicht zu sagen: verwirrend) wird es, wenn man z. B. den g\u00fcltigen int-Wert <a rel=\"noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Magic_number_(programming)#Magic_numbers_in_files\" target=\"_blank\">0xCAFEBABE<\/a> in einen Hex-String umwandelt und dann zur\u00fcck in ein int:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">int<\/span> hex = <span class=\"hljs-number\">0xCAFEBABE<\/span>;\nString s = Integer.toHexString(hex);\n<span class=\"hljs-keyword\">int<\/span> i = Integer.parseInt(s, <span class=\"hljs-number\">16<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dieser Versuch f\u00fchrt zu folgendem Fehler:<\/p>\n\n\n\n<p><code>Exception in thread \"main\" java.lang.NumberFormatException: For input string: \"cafebabe\"<\/code><\/p>\n\n\n\n<p>Warum ist das so?<\/p>\n\n\n\n<p>Zun\u00e4chst einmal: Der String <code>s<\/code> enth\u00e4lt wie erwartet \"cafebabe\". Warum kann dieser String nicht zur\u00fcck in ein int umgewandelt werden?<\/p>\n\n\n\n<p>Der Grund ist, dass die <code>parseInt()<\/code>-Methode davon ausgeht, dass die \u00fcbergebene Zahl positiv ist, sofern ihr nicht ein Minuszeichen vorangestellt ist. Konvertiert man \"cafebabe\" ins Dezimalsystem, erh\u00e4lt man 3.405.691.582. Diese Zahl ist gr\u00f6\u00dfer als <code>Integer.MAX_INT<\/code> und kann somit nicht als int dargestellt werden kann.&nbsp;<\/p>\n\n\n\n<p>Warum aber k\u00f6nnen wir die Zahl dann der int-Variablen <code>hex<\/code> zuweisen? Hier spielt uns die Bin\u00e4rdarstellung der Zahlen einen (beabsichtigten) Streich. 0xCAFEBABE entspricht bin\u00e4r 11001010.11111110.10111010.10111110 \u2013 einer 32-stelligen Bin\u00e4rzahl, deren erstes Bit eine 1 ist. Bei einem \u2013 in Java immer vorzeichenbehafteten \u2013 int steht das erste Bit f\u00fcr das Vorzeichen. Steht dort eine 1, ist die Zahl negativ (f\u00fcr Details zur Darstellung negativer Zahlen verweise ich auf <a rel=\"noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Signed_number_representations\" target=\"_blank\">diesen Wikipedia-Artikel<\/a>). Erweitern wir den Code oben wie folgt um Debug-Ausgaben:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">int<\/span> hex = <span class=\"hljs-number\">0xCAFEBABE<\/span>;\nSystem.out.println(<span class=\"hljs-string\">\"hex        = \"<\/span> + hex);\nSystem.out.println(<span class=\"hljs-string\">\"hex binary = \"<\/span> + Integer.toBinaryString(hex));\n\nString s = Integer.toHexString(hex);\nSystem.out.println(<span class=\"hljs-string\">\"s          = \"<\/span> + s);\n\n<span class=\"hljs-keyword\">int<\/span> i = Integer.parseInt(s, <span class=\"hljs-number\">16<\/span>);\nSystem.out.println(<span class=\"hljs-string\">\"i          = \"<\/span> + i);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dann sehen wir, dass <code>hex<\/code> den negativen Wert -889.275.714 enth\u00e4lt (die Tausenderpunkte habe hier der \u00dcbersicht halber eingef\u00fcgt). Hexadezimal wird diese negative Zahl als positiver Wert \"cafebabe\" dargestellt, welcher wiederum durch die <code>parseInt()<\/code>-Methode nicht zur\u00fcckgewandelt werden kann.<\/p>\n\n\n\n<p>Um dies doch noch zu erm\u00f6glichen, wurden in Java 8 folgende Methoden hinzugef\u00fcgt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>int i = Integer.parseUnsignedInt(s);<\/code> (\u2192 <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Integer.html#parseUnsignedInt-java.lang.String-\" target=\"_blank\">JavaDoc<\/a>)<\/li>\n\n\n\n<li><code>int i = Integer.parseUnsignedInt(s, radix);<\/code> (\u2192 <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Integer.html#parseUnsignedInt-java.lang.String-int-\" target=\"_blank\">JavaDoc<\/a>)<\/li>\n<\/ul>\n\n\n\n<p>Diese Methoden erlauben uns Zahlen im Bereich 0 bis 4.294.967.295 (= 0xffffffff hexadezimal bzw. 32 Einsen im Bin\u00e4rsystem) zu parsen. Ab Java 8 k\u00f6nnen wir somit die vorletzte Zeile des obigen Beispiels wie folgt anpassen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">int<\/span> i = Integer.parseUnsignedInt(s, <span class=\"hljs-number\">16<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Als Ausgabe erhalten wir aber nicht etwa 3.405.691.582 \u2013 sondern, da der Java-int nun eben immer signed (vorzeichenbehaftet) ist: -889.275.714, also denjenigen int-Wert, den wir auch erhalten, wenn wir 0xCAFEBABE einem int zuweisen.<\/p>\n\n\n\n<p>Und wie kommen wir an die 3.405.691.582? Dazu m\u00fcssen wir \"cafebabe\" (oder \"CAFEBABE\" \u2013 die Gro\u00df-\/Kleinschreibung ist unbedeutend) in ein long parsen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">long<\/span> l = Long.parseLong(s, <span class=\"hljs-number\">16<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Und wie sieht 3.405.691.582 in Bin\u00e4r- und Hexadezimaldarstellung aus?<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">System.out.println(<span class=\"hljs-string\">\"l binary = \"<\/span> + Long.toBinaryString(l));\nSystem.out.println(<span class=\"hljs-string\">\"l hex    = \"<\/span> + Long.toHexString(l));<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Wir erhalten wiederum die gleichen Darstellungen wie f\u00fcr den int-Wert -889.275.714, also 11001010.11111110.10111010.10111110 und \"cafebabe\". EIn- und dieselbe Bin\u00e4r- bzw. Hexadezimalzahl f\u00fchrt also \u2013 je nachdem, ob sie in einem int oder einem long gespeichert wird \u2013 zu einer unterschiedlichen Dezimalzahl (sofern sie gr\u00f6\u00dfer ist als <code>Integer.MAX_VALUE<\/code>). Im folgenden Abschnitt schauen wir uns das noch einmal an weiteren Beispielen an.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"parseint-vs-parseunsignedint\">parseInt() vs. parseUnsignedInt()<\/h3>\n\n\n\n<p>Um den Unterschied zwischen <code>parseInt()<\/code> und <code>parseUnsignedInt()<\/code> noch einmal zu verdeutlichen, habe ich ein kleines Programm geschrieben, das ihr hier in meinem <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/string-to-int-benchmarks\/blob\/main\/src\/main\/java\/eu\/happycoders\/string2int\/ParseUnsignedTest.java\" target=\"_blank\">GitHub-Repository<\/a> findet, und das verschiedene (Grenz-)Werte mit beiden Methoden parst.<\/p>\n\n\n\n<p>Hier findet ihr das Ergebnis zusammengefasst (die Striche stehen f\u00fcr NumberFormatExceptions):<\/p>\n\n\n\n<div style=\"overflow-x: auto\"><table class=\"wp-block-table is-style-stripes\"><tbody><tr><td><strong>String<\/strong><\/td><td><strong>Bemerkung<\/strong><\/td><td><strong>parseInt()<\/strong><\/td><td>\u2192 <strong>Hex<\/strong><\/td><td><strong>parse<\/strong><br><strong>Unsigned<\/strong><br><strong>Int()<\/strong><\/td><td>\u2192 <strong>Hex<\/strong><\/td><\/tr><tr><td>-2147483649<\/td><td>Integer.MIN_VALUE - 1<\/td><td>\u2014<\/td><td> \u2014 <\/td><td> \u2014 <\/td><td> \u2014 <\/td><\/tr><tr><td>-2147483648<\/td><td>Integer. MIN_VALUE<\/td><td>-2147483648<\/td><td>80000000<\/td><td> \u2014 <\/td><td> \u2014 <\/td><\/tr><tr><td>-1000000000<\/td><td><\/td><td>-1000000000<\/td><td>c4653600<\/td><td> \u2014 <\/td><td> \u2014 <\/td><\/tr><tr><td>-1<\/td><td><\/td><td>-1<\/td><td>ffffffff<\/td><td> \u2014 <\/td><td> \u2014 <\/td><\/tr><tr><td>0<\/td><td><\/td><td>0<\/td><td>0<\/td><td>0<\/td><td>0<\/td><\/tr><tr><td>1000000000<\/td><td><\/td><td>1000000000<\/td><td>3b9aca00<\/td><td>1000000000<\/td><td>3b9aca00<\/td><\/tr><tr><td>2147483647<\/td><td>Integer.MAX_VALUE<\/td><td>2147483647<\/td><td>7fffffff<\/td><td>2147483647<\/td><td>7fffffff<\/td><\/tr><tr><td>2147483648<\/td><td>Integer.MAX_VALUE +1<\/td><td> \u2014 <\/td><td> \u2014 <\/td><td>-2147483648<\/td><td>80000000<\/td><\/tr><tr><td>3000000000<\/td><td><\/td><td> \u2014 <\/td><td> \u2014 <\/td><td>-1294967296<\/td><td>b2d05e00<\/td><\/tr><tr><td>4294967295<\/td><td>2 * Integer.MAX_VALUE + 1<\/td><td> \u2014 <\/td><td> \u2014 <\/td><td>-1<\/td><td>ffffffff<\/td><\/tr><tr><td>4294967296<\/td><td>2 * Integer.MAX_VALUE + 2<\/td><td> \u2014 <\/td><td> \u2014 <\/td><td> \u2014 <\/td><td> \u2014 <\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Hier ist noch einmal sch\u00f6n zu sehen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>im Bereich <code>0<\/code> bis <code>Integer.MAX_VALUE<\/code> liefern <code>parseInt()<\/code> und <code>parseUnsignedInt()<\/code> die gleichen Ergebnisse.<\/li>\n\n\n\n<li><code>parseInt()<\/code> deckt dar\u00fcberhinaus den Bereich bis <code>Integer.MIN_VALUE<\/code> ab und liefert exakt den Wert, der \u00fcbergeben wurde.<\/li>\n\n\n\n<li><code>parseUnsignedInt()<\/code> deckt hingegen den Bereich bis <code>2 * Integer.MAX_VALUE + 1<\/code> mit ab \u2013 das Ergebnis ist jedoch im Bereich \u00fcber <code>Integer.MAX_VALUE<\/code> immer eine negative Zahl. Deren hexadezimale Darstellung entspricht, umgerechnet ins Dezimalsystem, wiederum dem Eingabewert.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"auto-boxing-und-unboxing-des-ergebnisses\">Auto-Boxing und -Unboxing des Ergebnisses<\/h2>\n\n\n\n<p>Wir haben oben gesehen, dass es separate Methoden gibt, um Strings in ein int bzw. ein Integer-Objekt zu konvertieren. Doch was passiert, wenn wir die falsche Methode anwenden?<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>Integer i = Integer.parseInt(\"42\");<\/code><\/li>\n\n\n\n<li><code>int i = Integer.valueOf(\"555\");<\/code><\/li>\n<\/ol>\n\n\n\n<p>Der erste Fall ist nicht besonders elegant, stellt aber kein Problem dar: <code>Integer.parseInt()<\/code> arbeitet intern mit primitiven Werten und das Ergebnis wird \u2013 genau wie bei <code>Integer.valueOf()<\/code> \u2013 letztlich durch Auto-Boxing in ein Integer-Objekt umgewandelt.<\/p>\n\n\n\n<p>Anders sieht es im zweiten Fall aus: hier wird das Ergebnis innerhalb von <code>Integer.valueOf()<\/code> in ein Integer-Objekt umgewandelt und dann bei der Zuweisung an <code>i<\/code> wieder zur\u00fcck in ein int-Primitiv. IntelliJ erkennt das (Eclipse hingegen nicht) und zeigt eine entsprechende Warnung an mit der Empfehlung <code>valueOf()<\/code> durch <code>parseInt()<\/code> zu ersetzen:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing.png\"><img decoding=\"async\" width=\"641\" height=\"134\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing.png\" alt=\"Screenshot der IntelliJ-Warnung bzgl. redundantem Boxing\" class=\"wp-image-7470\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing.png 641w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing-224x47.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing-336x70.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing-504x105.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing-400x84.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/IntelliJ_redundant_boxing-600x125.png 600w\" sizes=\"(max-width: 641px) 100vw, 641px\" \/><\/a><figcaption class=\"wp-element-caption\">IntelliJ warnt vor redundantem Boxing<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Inwieweit der Compiler bzw. Hotspot uns diesen Fehler verzeiht, werden wir im n\u00e4chsten Kapitel, \"Performance\", \u00fcberpr\u00fcfen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"performance-der-string-int-umwandlung\">Performance der String-int-Umwandlung<\/h2>\n\n\n\n<p>Ich habe \u2013 \u00e4hnlich wie im <a href=\"\/de\/java\/int-in-string-umwandeln-schnellster-weg\/#Performance-Messungen_der_int-zu-String-Umwandlung\">letzten Artikel<\/a> \u2013 mit Hilfe des <a rel=\"noopener\" href=\"https:\/\/openjdk.org\/projects\/code-tools\/jmh\/\" target=\"_blank\">Java Microbenchmark Harness<\/a> \u2013 kurz: JMH \u2013 folgende Vergleichsmessungen durchgef\u00fchrt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Geschwindigkeit verschiedener String-zu-int-Umwandlungsmethoden mit Java 8:\n<ul class=\"wp-block-list\">\n<li><code>parseInt()<\/code> mit positiven Zahlen, positiven Zahlen mit vorangestelltem Plus-Zeichen und negativen Zahlen,<\/li>\n\n\n\n<li><code>parseUnsignedInt()<\/code> mit positiven Zahlen und positiven Zahlen mit vorangestelltem Plus-Zeichen,<\/li>\n\n\n\n<li><code>valueOf()<\/code> mit positiven Zahlen,<\/li>\n\n\n\n<li><code>parseInt()<\/code> mit anschlie\u00dfender Konvertierung in ein Integer-Objekt,<\/li>\n\n\n\n<li><code>valueOf()<\/code> mit anschlie\u00dfender Konvertierung in ein int-Primitiv,<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Vergleich der <code>parseInt()<\/code>-Methode \u00fcber alle Java-Versionen von Java 7 bis Java 14.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"performance-der-verschiedenen-string-zu-int-umwandlungsmethoden\">Performance der verschiedenen String-zu-int-Umwandlungsmethoden<\/h3>\n\n\n\n<p>Den Test findet ihr in meinem <a href=\"https:\/\/github.com\/SvenWoltmann\/string-to-int-benchmarks\/blob\/main\/src\/main\/java\/eu\/happycoders\/string2int\/StringToIntMultiBenchmark.java\" target=\"_blank\" rel=\"noopener\">GitHub-Repository<\/a>. Die Testergebnisse liegen im <code>results\/<\/code>-Verzeichnis. Hier das Ergebnis des Vergleichs der verschiedenen Methodenaufrufe unter Java 8:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><tbody><tr><td><strong>Methode<\/strong><\/td><td><strong>Operationen pro Sekunde<\/strong><\/td><td><strong>Konfidenz\u200bintervall (99,9 %)<\/strong><\/td><\/tr><tr><td><code>parseInt()<\/code> positiver Wert<\/td><td>25.157.289<\/td><td>24.959.166 \u2013 25.355.412<\/td><\/tr><tr><td><code>parseInt()<\/code> positiver Wert mit Plus<\/td><td>25.056.427<\/td><td>24.974.885 \u2013 25.137.970<\/td><\/tr><tr><td><code>parseInt()<\/code> negativer Wert<\/td><td>25.143.740<\/td><td>25.039.972 \u2013 25.247.508<\/td><\/tr><tr><td><code>parseUnsignedInt()<\/code> positiver Wert <\/td><td>25.124.027<\/td><td>25.060.833 \u2013 25.187.221<\/td><\/tr><tr><td><code>parseUnsignedInt()<\/code> positiver Wert mit Plus<\/td><td>25.015.082<\/td><td>24.914.320 \u2013 25.115.843<\/td><\/tr><tr><td><code>parseInt()<\/code> mit anschlie\u00dfendem Boxing<\/td><td>24.594.336<\/td><td>24.421.316 \u2013 24.767.355<\/td><\/tr><tr><td><code>valueOf()<\/code> positiver Wert<\/td><td>24.531.187<\/td><td>24.413.040 \u2013 24.649.334<\/td><\/tr><tr><td><code>valueOf()<\/code> mit anschlie\u00dfendem Unboxing<\/td><td>24.325.347<\/td><td>24.183.155 \u2013 24.467.538<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison.png\"><img decoding=\"async\" width=\"778\" height=\"525\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison.png\" alt=\"Performance der String-zu-int-Umwandlungsmethoden unter Java 8\" class=\"wp-image-7549\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison.png 778w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison-224x151.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison-336x227.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison-504x340.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison-672x453.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison-400x270.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-comparison-600x405.png 600w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/a><figcaption class=\"wp-element-caption\">Performance der String-zu-int-Umwandlungsmethoden unter Java 8<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Ihr seht, dass die ersten f\u00fcnf Messergebnisse nahezu identisch sind. Das ist schnell erkl\u00e4rt: der aufgerufene Code ist in allen F\u00e4llen der gleiche. <code>valueOf()<\/code> und <code>parseInt()<\/code> mit anschlie\u00dfendem Boxing sind knapp 2 % langsamer. Dies d\u00fcrfte dem Overhead f\u00fcr das Umwandeln in ein Integer-Objekt entsprechen. <code>valueOf()<\/code> mit anschlie\u00dfendem Unboxing ist noch einmal knapp 1 % langsamer, was bedeutet, dass weder der Compiler noch Hotspot uns den Fehler \"Boxing mit anschlie\u00dfendem Unboxing\" verziehen haben.<\/p>\n\n\n\n<p>Das Parsen negativer Zahlen sollte minimal schneller sein, da intern <em>negative<\/em> Zahlen aufaddiert werden und im Fall einer <em>positiven<\/em> Zahl das Ergebnis mit -1 multipliziert wird. In den Benchmarks lassen sich jedoch keine Unterschiede feststellen. Multiplizieren mit -1 ist offenbar so schnell, dass dies selbst bei 25 Millionen Multiplikationen pro Sekunde nicht ins Gewicht f\u00e4llt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"performance-der-string-zu-int-konvertierung-im-laufe-der-java-versionen\">Performance der String-zu-int-Konvertierung im Laufe der Java-Versionen<\/h3>\n\n\n\n<p>Da im Endeffekt alle Varianten der String-zu-int-Konvertierung <code>Integer.parseInt()<\/code> aufrufen, habe ich mich darauf beschr\u00e4nkt, die Performance des Aufrufs dieser einen Methode \u00fcber die verschiedenen Java-Versionen hinweg zu messen. Ich habe hierf\u00fcr dieselbe Test-Klasse verwendet wie f\u00fcr den vorherigen Test und alle Methoden au\u00dfer <code>integerParsePositiveInt()<\/code> auskommentiert. Den Code habe ich mit den jeweiligen Java-Versionen compiliert und ausgef\u00fchrt. Auch die Ergebnisse dieser Tests findet ihr im <code>results\/<\/code>-Ordner. Hier eine Zusammenfassung der Ergebnisse:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table><tbody><tr><td><strong>Java-Version<\/strong><\/td><td> <strong>Operationen pro Sekunde<\/strong> <\/td><td> <strong>Konfidenz\u200bintervall (99,9 %)<\/strong> <\/td><\/tr><tr><td>Java 7<\/td><td>25.223.117<\/td><td>25.069.748 \u2013 25.376.488<\/td><\/tr><tr><td>Java 8<\/td><td>25.157.289<\/td><td>24.959.166 \u2013 25.355.412 <\/td><\/tr><tr><td>Java 9<\/td><td>22.580.117<\/td><td>22.471.102 \u2013 22.689.132<\/td><\/tr><tr><td>Java 10<\/td><td>22.129.425<\/td><td>21.889.153 \u2013 22.369.698 <\/td><\/tr><tr><td>Java 11<\/td><td>23.657.228<\/td><td>23.494.292 \u2013 23.820.165<\/td><\/tr><tr><td>Java 12<\/td><td>23.604.657<\/td><td>23.385.208 \u2013 23.824.106<\/td><\/tr><tr><td>Java 13<\/td><td>23.626.048<\/td><td>23.473.823 \u2013 23.778.273<\/td><\/tr><tr><td>Java 14<\/td><td>23.599.658<\/td><td>23.440.825 \u2013 23.758.490<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions.png\"><img decoding=\"async\" width=\"778\" height=\"431\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions.png\" alt=\"Performance der String-zu-int-Konvertierung im Laufe der Java-Versionen\" class=\"wp-image-7626\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions.png 778w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions-224x124.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions-336x186.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions-504x279.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions-672x372.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions-400x222.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/String-to-int-performance-all-Java-versions-600x332.png 600w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/a><figcaption class=\"wp-element-caption\">Performance der String-zu-int-Konvertierung im Laufe der Java-Versionen<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Interessanterweise wurde die Methode <code>Integer.parseInt()<\/code> in Java 9 deutlich (knapp 10 %) langsamer, mit Java 10 noch einmal 2 % langsamer und ab Java 11 wieder schneller, bleibt aber seither etwa 5 % hinter der Performance von Java 7 und 8 zur\u00fcck. Um dieses Messergebnis zu best\u00e4tigen, habe ich alle (ohnehin intern 25-fach wiederholten) Benchmark-Tests noch einmal ausgef\u00fchrt \u2013 mit \u00e4hnlichen Ergebnissen. <\/p>\n\n\n\n<p>Auf der Suche nach der Ursache habe ich zun\u00e4chst die Quellcodes von <code>Integer.parseInt()<\/code> aller Java-Versionen verglichen. Versionen 7 und 8 sind identisch. In Java 9 wurde der Code etwas umstrukturiert, z. B. wurden Variablen an anderen Stellen deklariert. Am Algorithmus selbst wurde nichts ver\u00e4ndert. Die minimalen Code-\u00c4nderungen d\u00fcrften keine Auswirkung auf die Performance haben. Von Java 9 bis zum Early Access Release von Java 14 gab es keine weitere \u00c4nderung, bis auf dass in Java 12 die Zahlenbasis (\"radix\") in die Fehlermeldung bei nicht parsbaren Zahlen mit aufgenommen wurde.<\/p>\n\n\n\n<p>Um zu \u00fcberpr\u00fcfen, ob die \u00c4nderungen in Java 9 eine Auswirkung auf die Performance hatten, habe ich die <code>Integer.parseInt()<\/code>-Quellcodes aus Java 8 und 9 kopiert und diese Kopien mit JMH getestet. Beide waren exakt gleich schnell, an den Code-\u00c4nderungen liegt es also nicht. (Dieser Test liegt nicht im GitHub-Repository, da ich nicht wei\u00df, in wie weit ich Java-Quellcodes ver\u00f6ffentlichten darf.)<\/p>\n\n\n\n<p>In einem weiteren Versuch habe ich den <code>Integer.parseInt()<\/code>-Quellcode mit Java 8 compiliert und die resultierende class-Datei mit Java 9 bis 14 ausgef\u00fchrt. Dies hat zu einem \u00e4hnlichen Ergebnis gef\u00fchrt wie der initiale Performance-Test, d. h. Java 9 und 10 wurden langsamer und Java 11 wieder etwas schneller. Der Grund f\u00fcr die unterschiedlichen Geschwindigkeiten muss also innerhalb der JVM liegen. Falls jemand von euch die genaue Ursache kennt, freue ich mich \u00fcber einen aufkl\u00e4renden Kommentar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"zusammenfassung\">Zusammenfassung<\/h2>\n\n\n\n<p>Ich habe in diesem Artikel gezeigt, wie ihr Zahlen im Dezimal- und anderen Zahlensystemen parsen k\u00f6nnt und was der Unterschied ist zwischen <code>parseInt()<\/code> und <code>parseUnsignedInt()<\/code>. Achtet darauf, nicht unn\u00f6tig von int nach Integer zu boxen, oder umgekehrt, oder \u2013 am schlimmsten \u2013 beides hintereinander. Wenn du den Artikel hilfreich findest, freue ich mich, wenn du ihn \u00fcber einen der folgenden Share-Button teilst.<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>Du m\u00f6chtest \u00fcber alle neue Java-Features auf dem Laufenden sein? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>Im heutigen Artikel erf\u00e4hrst du, welche Methoden es gibt, um in Java einen Strings in ein int zu parsen und was du bei der Verwendung dieser Methoden beachten musst.<\/p>\n","protected":false},"author":1,"featured_media":34493,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"none","_seopress_titles_title":"Java: String in int umwandeln - Besonderheiten + Fallstricke","_seopress_titles_desc":"Wie konvertiert man in Java ein String in ein int? Was ist zu beachten? Was ist der Unterschied zwischen parseInt() und parseUnsignedInt()?","_seopress_robots_index":"","_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":13752,"_post_count":0,"footnotes":""},"categories":[64],"tags":[157],"class_list":["post-7390","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-performance-de"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/11\/java-string-to-int.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"Im heutigen Artikel erf\u00e4hrst du, welche Methoden es gibt, um in Java einen Strings in ein int zu parsen und was du bei der Verwendung dieser Methoden beachten musst.","public_identification_id":"48f68debed0e44a79eada5e6f3c8f67a","private_identification_id":"88e6172fbfd240ccb0efc23f3e8a2509","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/7390","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=7390"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/7390\/revisions"}],"predecessor-version":[{"id":42762,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/7390\/revisions\/42762"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/34493"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=7390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=7390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=7390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}