{"id":1633,"date":"2012-12-24T13:35:21","date_gmt":"2012-12-24T11:35:21","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=1633"},"modified":"2012-12-25T06:28:26","modified_gmt":"2012-12-25T04:28:26","slug":"abkrzende-schreibweisen-fr-lambda-ausdrcke","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2012\/12\/abkrzende-schreibweisen-fr-lambda-ausdrcke\/","title":{"rendered":"Abk&uuml;rzende Schreibweisen f&uuml;r Lambda-Ausdr&uuml;cke"},"content":{"rendered":"<p>Lambda-Ausdr\u00fccke haben wie Methoden m\u00f6gliche Parameter und R\u00fcckgabe. Die Java-Grammatik f\u00fcr die Schreibweise von Lambda-Ausdr\u00fccken sieht ein paar syntaktische Abk\u00fcrzungen vor, dir wir uns nun anschauen wollen.<\/p>\n<p><strong>Typinferenz<\/strong><\/p>\n<p>Der Java-Compiler kann viele Typen aus dem Kontext ablesen, was Typ-Inferenz genannt wird. Wir kennen so etwas vom Diamanten, wenn wir schreiben List&lt;String&gt; list = new ArrayList&lt;&gt;();.<\/p>\n<p>Statt<\/p>\n<p>Comparator&lt;String&gt; c = (<b>String s1, String s2<\/b>) -&gt; { return s1.trim().compareTo( s2.trim() ); };<\/p>\n<p>erlaubt der Compiler auch die Abk\u00fcrzung:<\/p>\n<p>Comparator&lt;String&gt; c = (<b>s1, s2<\/b>) -&gt; { return s1.trim().compareTo( s2.trim() ); };<\/p>\n<p>Die Parameterliste enth\u00e4lt also deklarierte Parametertypen oder inferred-Typen. Eine Mischung ist nicht erlaubt, der Compiler blockt so etwas wie (String s1, s2) oder (s1, String s2) mit einem Fehler ab.<\/p>\n<p><strong>Lambda-Rumpf ist entweder einzelner Ausdruck oder Block<\/strong><\/p>\n<p>Besteht der Rumpf eines Lambda-Ausdrucks nur aus einem einzelnen Ausdruck, kann eine verk\u00fcrzte Schreibweise die Block-Klammern und das Semikolon einsparen. Statt<\/p>\n<p>&#8218;(&#8218; <i>Parameter<\/i> &#8218;)&#8216; &#8218;-&gt;&#8216; &#8218;{&#8218; <i>Anweisungen<\/i>; &#8218;}&#8216;<\/p>\n<p>hei\u00dft es dann<\/p>\n<p>&#8218;(&#8218; Parameter &#8218;)&#8216; &#8218;-&gt;&#8216; Ausdruck<\/p>\n<p>Lambda-Ausdr\u00fccke mit einer return\u2013Anweisung im Rumpf kommen h\u00e4ufig vor (es entspricht den typischen Funktionen). Da ist es eine willkommene Verk\u00fcrzung, wenn die abgek\u00fcrzte Syntax f\u00fcr Lambda-Ausdr\u00fccke lediglich den Ausdruck fordert, der dann die R\u00fcckgabe bildet.<\/p>\n<p>Drei Beispiele:   <\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"306\">\n<p><b>Lange Schreibweise<\/b><\/p>\n<\/td>\n<td valign=\"top\" width=\"306\">\n<p><b>Abk\u00fcrzung<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"306\">\n<p>(s1, s2) -&gt; { return s1.trim().compareTo( s2.trim() ); }<\/p>\n<\/td>\n<td valign=\"top\" width=\"306\">\n<p>(s1, s2) -&gt; s1.trim().compareTo( s2.trim() )<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"306\">\n<p>(a, b) -&gt; { return a + b; }<\/p>\n<\/td>\n<td valign=\"top\" width=\"306\">\n<p>(a, b) -&gt; a + b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"306\">\n<p>() -&gt; { System.out.println(); }<\/p>\n<\/td>\n<td valign=\"top\" width=\"306\">\n<p>() -&gt; System.out.println()<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Ausdr\u00fccke k\u00f6nnen in Java auch zu void ausgewertet werden, sodass ohne Probleme ein Aufruf wie System.out.println() in der kompakten Schreibweise ohne Block gesetzt werden kann.<\/p>\n<p>Ob Lambda-Ausdr\u00fccke eine R\u00fcckgabe geben, dr\u00fccken zwei Begriffe aus:<\/p>\n<p>\u00b7 Der Rumpf kann in Anweisungen enden, die nichts zur\u00fcck geben. Das nennt sich void-kompatibel.<\/p>\n<p>\u00b7 Der Rumpf beendet den Block mit einer return-Anweisung, die einen Wert zur\u00fcckgibt. Das nennt sich Wert-kompatibel.<\/p>\n<p>Eine Mischung aus void- und Wert-kompatibel ist nicht erlaubt und f\u00fchrt wie bei Methoden zu einem Compilerfehler.<a href=\"file:\/\/\/C:\/Users\/Christian\/Dropbox\/Insel\/todo\/#_ftn1_4908\" name=\"_ftnref1_4908\">[1]<\/a><\/p>\n<p><strong>Einzelner Identifizierer statt Parameterliste und Klammern<\/strong><\/p>\n<p>Besteht die Parameterliste nur aus einem einzelnen Identifizierer und ist der Typ durch Typ-Inferenz klar, k\u00f6nnen die runden Klammen wegfallen.    <\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"33%\">\n<p><b>Lange Schreibweise<\/b><\/p>\n<\/td>\n<td valign=\"top\" width=\"33%\">\n<p><b>Typen inferred<\/b><\/p>\n<\/td>\n<td valign=\"top\" width=\"33%\">\n<p><b>Vollst\u00e4ndig abgek\u00fcrzt<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"33%\">\n<p>(Sting s) -&gt; s.length() <\/p>\n<\/td>\n<td valign=\"top\" width=\"33%\">\n<p>(s) -&gt; s.length() <\/p>\n<\/td>\n<td valign=\"top\" width=\"33%\">\n<p>s -&gt; s.length()<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"33%\">\n<p>(int i) -&gt; Math.abs( i )<\/p>\n<\/td>\n<td valign=\"top\" width=\"33%\">\n<p>(i) -&gt; Math.abs( i )<\/p>\n<\/td>\n<td valign=\"top\" width=\"33%\">\n<p>i -&gt; Math.abs( i )<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Kommen alle Abk\u00fcrzungen zusammen, l\u00e4sst sich etwa die H\u00e4lfe einsparen. Aus (int i) -&gt; { return Math.abs( i ); } wird dann i -&gt; Math.abs( i ).<\/p>\n<hr align=\"left\" size=\"1\" width=\"33%\" \/>\n<p><a href=\"file:\/\/\/C:\/Users\/Christian\/Dropbox\/Insel\/todo\/#_ftnref1_4908\" name=\"_ftn1_4908\">[1]<\/a> Wohl aber gibt es wie bei { throw new RuntimeException(); } Ausnahmen, bei denen Lambda-Ausdr\u00fccke beides sind.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lambda-Ausdr\u00fccke haben wie Methoden m\u00f6gliche Parameter und R\u00fcckgabe. Die Java-Grammatik f\u00fcr die Schreibweise von Lambda-Ausdr\u00fccken sieht ein paar syntaktische Abk\u00fcrzungen vor, dir wir uns nun anschauen wollen. Typinferenz Der Java-Compiler kann viele Typen aus dem Kontext ablesen, was Typ-Inferenz genannt wird. Wir kennen so etwas vom Diamanten, wenn wir schreiben List&lt;String&gt; list = new ArrayList&lt;&gt;();. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11,66],"tags":[],"class_list":["post-1633","post","type-post","status-publish","format-standard","hentry","category-insel","category-java-8"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=1633"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1633\/revisions"}],"predecessor-version":[{"id":1635,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1633\/revisions\/1635"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=1633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=1633"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=1633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}