<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://mletkin.net/index.php?action=history&amp;feed=atom&amp;title=Streams%3A_Lokale_Variablen</id>
	<title>Streams: Lokale Variablen - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://mletkin.net/index.php?action=history&amp;feed=atom&amp;title=Streams%3A_Lokale_Variablen"/>
	<link rel="alternate" type="text/html" href="https://mletkin.net/index.php?title=Streams:_Lokale_Variablen&amp;action=history"/>
	<updated>2026-05-19T16:43:02Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in MimiPedia</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>https://mletkin.net/index.php?title=Streams:_Lokale_Variablen&amp;diff=114&amp;oldid=prev</id>
		<title>Ullrich: Die Seite wurde neu angelegt: „Category:Java Beim Streunen durch den Code auf der Suche nach refakturierungswürdigen Häufchen stieß ich auf diese Methode: {{java|code= ControllerResul…“</title>
		<link rel="alternate" type="text/html" href="https://mletkin.net/index.php?title=Streams:_Lokale_Variablen&amp;diff=114&amp;oldid=prev"/>
		<updated>2023-03-09T17:20:45Z</updated>

		<summary type="html">&lt;p&gt;Die Seite wurde neu angelegt: „&lt;a href=&quot;/index.php?title=Kategorie:Java&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Kategorie:Java (Seite nicht vorhanden)&quot;&gt;Category:Java&lt;/a&gt; Beim Streunen durch den Code auf der Suche nach refakturierungswürdigen Häufchen stieß ich auf diese Methode: {{java|code= ControllerResul…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Category:Java]]&lt;br /&gt;
Beim Streunen durch den Code auf der Suche nach refakturierungswürdigen Häufchen stieß ich auf diese Methode:&lt;br /&gt;
{{java|code=&lt;br /&gt;
ControllerResult addAccounts(List&amp;lt;Account&amp;gt; accounts) {&lt;br /&gt;
    AccountCreator creator = new AccountCreator();&lt;br /&gt;
    List&amp;lt;AccountCreationResult&amp;gt; accountList = accounts.stream() //&lt;br /&gt;
        .map(creator::create) //&lt;br /&gt;
        .collect(Collectors.toList());&lt;br /&gt;
    return ControllerResult.result(Status.CREATED).entity(accountList);&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
Für jedes {{java|Account}}-Objekt der Liste wird – mit Hilfe des {{java|AccountCreator}}-Objekts ein Konto angelegt.&lt;br /&gt;
Dessen {{java|create}}-Methode liefert für jeden Account ein {{java|AccountCreationResult}}-Objekt, das das Ergebnis der Anlage beschreibt. Die Ergebnisse werden gesammelt und als Liste zurückgegeben. Soweit, so einfach.&lt;br /&gt;
&lt;br /&gt;
Ich will nicht sagen, daß lokale Variablen grundsätzlich von Übel sind, aber jede Zeile Code die man löschen kann&lt;br /&gt;
ohne die Lesbarkeit zu gefährden ist ein Gewinn. Warum also wird hier überhaupt eine lokale Variable verwendet?&lt;br /&gt;
Das konventionelle Konstrukt – ohne Stream – sähe so aus:&lt;br /&gt;
{{java|code=&lt;br /&gt;
ControllerResult addAccounts(List&amp;lt;Account&amp;gt; accounts) {&lt;br /&gt;
    AccountCreator creator = new AccountCreator();&lt;br /&gt;
    List&amp;lt;AccountCreationResult&amp;gt; accountList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
    for (Account account : accounts) {&lt;br /&gt;
        accountList.add(creator.create(account));&lt;br /&gt;
    }&lt;br /&gt;
    return ControllerResult.result(Status.CREATED).entity(accountList);&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
Offensichtlich ist es sinnvoller, das {{java|Creator}}-Objekt nur einmal &amp;#039;&amp;#039;vor&amp;#039;&amp;#039; dem Eintritt in die Schleife zu erzeugen&lt;br /&gt;
und dann bei jedem Durchlauf wiederzuverwenden, statt für jeden Account einen eigenen Creator zu erzeugen. Wie aber sieht&lt;br /&gt;
das mit der Stream-Lösung aus? Betrachten wir dazu den schematischen Ablauf wenn die Stream-Anweisungen ausgeführt werden:&lt;br /&gt;
{{java|code=accounts.stream()}}&lt;br /&gt;
erzeugt ein neues Stream-Objekt mit einer leeren Liste von Anweisungen, die für jedes Objekt im Stream ausgeführt werden sollen.&lt;br /&gt;
{{java|code=.map(creator::create)}}&lt;br /&gt;
fügt der Anweisungsliste eine Anweisung hinzu, die den {{lambda}}-Ausdruck {{java|creator::create}} enthält. Das ist ein&lt;br /&gt;
Verweis auf die Methode {{java|create()}} des Objektes, das in der lokalen Variable {{java|creator}} steckt.&lt;br /&gt;
{{java|code=.collect(Collectors.toList())}}&lt;br /&gt;
führt eine Schleife aus, die auf jedem Objekt des Streams die Anweisungen der Liste ausführt, die entstehenden&lt;br /&gt;
Ergebnisse in einer Liste sammelt und diese als {{java|List}}-Objekt zurückgibt.&lt;br /&gt;
Die Behauptung, daß das Stream-Objekt eine Anweisungsliste enthält ist extrem vereinfacht ausgedrückt, ist aber –&lt;br /&gt;
was den Ablauf angeht – eine ausreichende Beschreibung. Der entscheidende Punkt ist, daß die Methode {{java|map()}}&lt;br /&gt;
hier nur ein einziges Mal ausgeführt wird, und zwar bevor die Schleife über die Stream-Objekte ausgeführt wird.&lt;br /&gt;
Schreiben wir also:&lt;br /&gt;
{{java|code=&lt;br /&gt;
ControllerResult addAccounts(List&amp;lt;Account&amp;gt; accounts) {&lt;br /&gt;
    List&amp;lt;AccountCreationResult&amp;gt; accountList = accounts.stream() //&lt;br /&gt;
        .map(new AccountCreator(session)::create) //&lt;br /&gt;
        .collect(Collectors.toList());&lt;br /&gt;
    return ControllerResult.result(Status.CREATED).entity(accountList);&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
dann wird tatsächlich – mit dem Debugger leicht nachzuvollziehen – auch nur einziges {{java|AccountCreator}}-Objekt&lt;br /&gt;
erzeugt. Die Objekt-Referenz wird dabei scheinbar nirgendwo gespeichert. Scheinbar deshalb, weil sie natürlich implizit im {{lambda}}-Ausdruck&lt;br /&gt;
{{java|code=new AccountCreator(session)::create}}&lt;br /&gt;
enthalten ist. Wir können also tatsächlich auf die lokale Variable verzichten und das {{java|AccountCreator}}-Objekt&lt;br /&gt;
on-the-fly beim Erzeugen des {{lambda}}-Ausdrucks instantiieren.&lt;br /&gt;
Nun mag der Lambda-Neuling annehmen, daß die {{java|::}}-Notation des Ausdrucks nur syntaktischer Zucker ist und sich&lt;br /&gt;
der Ausdruck auch so schreiben ließe:&lt;br /&gt;
{{java|code=(Account a) -&amp;gt; new AccountCreator(session).create(a);}}&lt;br /&gt;
Achtung! Hier passiert etwas völlig anderes, denn wenn wir diesen {{lambda}}-Ausdruck in unserem Stream&lt;br /&gt;
verwenden wird tatsächlich für jedes Stream-Objekt ein neues Creator-Objekt erzeugt, denn jetzt ist die Objekt-&lt;br /&gt;
Erzeugung mit {{java|new}} Teil des {{lambda}}-Ausdrucks geworden. Warum ist das so?&lt;br /&gt;
&lt;br /&gt;
Für den {{lambda}}-Ausdruck&lt;br /&gt;
{{java|code=(Account a) -&amp;gt; new AccountCreator(session).create(a);}}&lt;br /&gt;
wird ein Objekt einer anonymen Klasse erzeugt mit einer anonymen Methode, deren Body den Ausdruck rechts&lt;br /&gt;
des {{java|-&amp;gt;}}-Operators enthält. Beim Ausführen des {{lambda}}-Audrucks wird nun diese Methode dieses&lt;br /&gt;
Objekts – die eine neues {{java|AccountCreator}}-Objekt erzeugt – ausgeführt. Für den {{lambda}}-Ausdruck&lt;br /&gt;
{{java|code=new AccountCreator(session)::create}}&lt;br /&gt;
hingegen wird ein Objekt der Klasse {{java|AccountCreator}} erzeugt die die Methode {{java|create}} implementiert.&lt;br /&gt;
Bei der Ausführung des {{lambda}}-Ausdrucks wird die Methode {{java|create}} dieses Objekts ausgeführt und es wird kein&lt;br /&gt;
neues {{java|AccountCreator}}-Objekt erzeugt.&lt;/div&gt;</summary>
		<author><name>Ullrich</name></author>
	</entry>
</feed>