Ströme in Java (Ströme in Java), Lektion, Seite 723603
https://www.purl.org/stefan_ram/pub/stroeme_java (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram

Ströme in Java

Schnittstellen mit Typparameter, Zuweisung an Variable

Zuweisung an eine Variable, deren Typ eine funktionale Schnittstelle ist

Main.java

public final class Main
{ public static void main( final java.lang.String[] args )
{ /* a.util.concurrent.Callable< java.lang.Double >callable = () -> 123; // nicht konvertierbar */
/* a.util.concurrent.Callable< java.lang.Double >callable1 =( () -> 123 ); // nicht konvertierbar */
java.util.concurrent.Callable< java.lang.Double >callable = () -> 123.0;
java.util.concurrent.Callable< java.lang.Double >callable1 =( () -> 123.0 );

try
{ java.lang.System.out.println( callable.call() );
java.lang.System.out.println( callable1.call() );
java.lang.System.out.println( ( callable ).call() );
java.lang.System.out.println( ( callable1 ).call() ); }
catch( final java.lang.Exception exception )
{ java.lang.System.err.println( exception ); }
/* a.lang.System.out.println( callable() ); // nicht moeglich */ }}

transcript
123.0
123.0
123.0
123.0

Folgende Programmbeispiel erzeugt ein Objekt der Schnittstelle Supplier.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.util.function.Supplier< java.lang.String >stringSupplier = "abc"::toString;
java.lang.System.out.println( stringSupplier );
java.lang.System.out.println( stringSupplier.get() );
/* a.lang.System.out.println( stringSupplier() ); // nicht moeglich */
/* a.lang.System.out.println( ( "abc"::toString ).get() ); // nicht moeglich */ }}
transcript
Main$$Lambda$1/518248@1ee733d
abc

Mehr zu asList, Methoden mit Typparameter

Eine Liste, die mit asList erhalten wurde, basiert auf einer Reihung. Sie kann daher nicht mit add erweitert werden.

asList ist eine Methode mit einem Typparameter. Das zuvor gezeigte java.util.concurrent.Callable war hingegen eine Schnittstelle mit einem Typparameter.

static< T >List< T >asList( T ... a )

Der Typ T wird bei Aufruf automatisch angepaßt. Er kann auch vom Kontext abhängen:

Main.java
public final class Main
{ public static void main( final java.lang.String args[] ) throws java.lang.Throwable
{ /* a.util.List< java.lang.Double >r =( java.util.Arrays.asList( 2, 3.0 ) ); // nicht moeglich */
java.util.List< java.lang.Number >s =( java.util.Arrays.asList( 2, 3.0 ) );
java.util.List< java.lang.Object >t =( java.util.Arrays.asList( 2, 3.0 ) ); }}
transcript
.

Ein Typargument kann zur Laufzeit oft nicht ermittelt werden, da es nur während der Übersetzung verwendet wird (type erasure):

Main.java
public final class Main
{ public static void main( final java.lang.String args[] ) throws java.lang.Throwable
{ java.util.List< java.lang.Number >s =( java.util.Arrays.asList( 2, 3.0 ) );
java.util.List< java.lang.Object >t =( java.util.Arrays.asList( 2, 3.0 ) );
java.lang.System.out.println( s.getClass() );
java.lang.System.out.println( t.getClass() ); }}
transcript
class java.util.Arrays$ArrayList
class java.util.Arrays$ArrayList

Ein Typargument einer Methode mit einem Typparameter kann auch ausdrücklich angegeben werden:

Main.java
public final class Main
{ public static void main( final java.lang.String args[] ) throws java.lang.Throwable
{ java.util.List< java.lang.Number >s = java.util.Arrays.< java.lang.Number >asList( 2, 3.0 );
java.util.List< java.lang.Object >t = java.util.Arrays.< java.lang.Object >asList( 2, 3.0 ); }}

Die ausdrückliche Angabe eines Typarguments ist nötig, wenn der Compiler keinen passenden Typ findet.

Ströme

asList: varargs-Methode

Main.java
public final class Main
{ public static void main( final java.lang.String args[] )
{ final java.util.List< java.lang.Integer >list = java.util.Arrays.asList( 1, 2, 3 );
java.lang.System.out.println( list.stream().reduce( 0,( x, y )-> x + y )); }}
transcript
6
Main.java
public final class Main
{ public static void main( final java.lang.String args[] )
{ final java.util.List< java.math.BigDecimal >list
= java.util.Arrays.asList
( new java.math.BigDecimal( "3" ),
new java.math.BigDecimal( "4" ),
new java.math.BigDecimal( "5" ) );
java.lang.System.out.println
( list.stream().reduce
( new java.math.BigDecimal( "0" ),
java.math.BigDecimal::add )); }}
transcript
12

Falls in einer inneren Methode bei der Verarbeitung eines Stromes ein Laufzeitfehler auftritt, kann der Stapelbericht dazu für einen Programmierer unübersichtlich sein.

Lotto ohne veränderliche Variablen oder Schleifen

6 aus 49

Main.java

public final class Main
{ public static void main( final java.lang.String[] args )
{

final int total_size = 49;
final int selection_size = 6;

final java.util.List<java.lang.Integer> numbers =
java.util.stream.IntStream.rangeClosed( 1, total_size ).boxed().
collect( java.util.stream.Collectors.toList() );
java.util.Collections.shuffle( numbers );
java.lang.System.out.println( java.util.Arrays.toString( numbers.subList( 0, selection_size ).toArray() )); }}

Protokoll
[31, 11, 15, 40, 47, 44]
transcript
[46, 22, 25, 31, 26, 32]
transcript
[5, 20, 24, 2, 15, 14]
Aussprachehinweis
closed clozd

Vokalgrapheme zählen

public final class Main
{ public static void main( final java.lang.String args[] )
{ java.lang.System.out.println
( "aba".codePoints().
filter( x -> "aeiou".indexOf( x )>= 0 ).
count() ); }}

Vorteil: filter geht universell für alle möglichen Ströme (egal, ob diese aus einem Text oder einer Liste kommen), man muß nicht jeweils spezielle Methoden erlernen, einmal für String und einmal für Liste.

Parallele Ströme

Die parallelen Ströme sind die Motivation für die Einführung von Methodenausdrücken in Java!

Java  wird Operationen auf einem Strom, der nicht ausdrücklich als parallel gekennzeichnet ist, nicht von sich aus parallelisieren. Stromoperationen werden nur parallelisiert, wenn der Strom mit »parallelStream()« oder »stream().parallel()« oder auf eine gleichwertige Weise erzeugt wurde.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.util.List< java.lang.Integer >list = java.util.Arrays.asList( 1, 2, 3 );
java.lang.System.out.println( list.parallelStream().map( x -> x * x ).reduce( 0,( x, y )-> x + y )); }}
transcript
14

Die Parallelisierung eines Stroms kann Programme in bestimmten Fällen auch verlangsamen (etwa, wenn es schon viele Threads gibt).

Es reicht nicht immer, einfach nur »stream« durch »parallelStream« zu ersetzen, manchmal muß man auch noch andere Operationen an die Parallelverarbeitung anpassen:

public final class Main
{ public static void main( final java.lang.String[] args )
{ java.util.Arrays.asList( "E", "J", "B", "B", "D", "H", "" ).
parallelStream().
filter( x -> !x.isEmpty() ).
distinct().
sorted().
forEachOrdered( java.lang.System.out::println ); }}

Die Verwendung von »forEachOrdered« statt »forEach« führt zum gewünschten Verhalten, aber kann auch dafür sorgen, daß keine Parallelverarbeitung stattfindet.

forEach

Main.java
public final class Main
{
public static void p( final java.lang.String text )
{ java.lang.System.out.println( text ); }
public static void trg( final java.lang.String wort )
{ p( "Tomaten" ); p( "Rotkohl Gruenkohl" ); p( wort ); }
public static void main( final java.lang.String[] args )
{ trg( "Gurken" ); trg( "Spinat" ); trg( "Kohlrabi" ); }}
transcript
Tomaten
Rotkohl Gruenkohl
Gurken
Tomaten
Rotkohl Gruenkohl
Spinat
Tomaten
Rotkohl Gruenkohl
Kohlrabi
Main.java
public final class Main
{
public static void p( final java.lang.String text )
{ java.lang.System.out.println( text ); }
public static void trg( final java.lang.String wort )
{ java.util.Arrays.asList( "Tomaten", "Rotkohl Gruenkohl", wort ).forEach( Main::p ); }
public static void main( final java.lang.String[] args )
{ java.util.Arrays.asList( "Gurken", "Spinat", "Kohlrabi" ).forEach( Main::trg ); }}
transcript
Tomaten
Rotkohl Gruenkohl
Gurken
Tomaten
Rotkohl Gruenkohl
Spinat
Tomaten
Rotkohl Gruenkohl
Kohlrabi

Der Compiler schließt auf den Typ der Liste und wählt so die passende Überladung von println.

Main.java
public final class Main
{
public static void main( final java.lang.String[] args )
{ java.util.Arrays.asList( "hello, ", "world" ).
forEach( java.lang.System.out::println ); }}
transcript
hello, 
world

In dem folgenden Beispiel wäre auch java.lang.System.out::println möglich

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
throws java.lang.Exception
{ java.util.Arrays.asList
( new java.io.File( "." ).getCanonicalPath(),
new java.io.File( "" ).getCanonicalPath(),
java.lang.System.getProperty( "user.dir" ),
java.nio.file.Paths.get( "" ).toAbsolutePath().normalize() )
.forEach( cCorrente -> java.lang.System.out.println( cCorrente )); }}
transcript
C:\
C:\
C:\
C:\

?   Typen (1)

Welchen Typ hat der Ausdruck »java.lang.System.out.getClass()«?

?   Typen (2)

Welchen Typ hat das Objekt »java.lang.System.out.getClass()«?

?   Typen (3) *

Können Sie die Ausgabe des folgenden Programms voraussagen, ohne es zu starten?

Main.java
public final class Main 
{ final public static void main( final java.lang.String[] args ) 
{ java.lang.System.out.println( "Alpha".getClass().getClass() );  
java.lang.System.out.println( "Alpha".getClass().toString().getClass() ); }}

Main.java

public final class Main

{

public static boolean identbody( final int c )

{ return c != 'Z' && java.lang.Character.isJavaIdentifierPart( c ); }

public static void println

( final java.util.function.Function<Integer,Boolean> pred )

{ java.util.stream.IntStream.rangeClosed( 32, 126 ).

filter( pred::apply ).

forEach( c -> java.lang.System.out.print(( char )c ));

java.lang.System.out.println(); }

public static void main( final java.lang.String[] args )

{ println( java.lang.Character::isJavaIdentifierStart );

println( Main::identbody ); }}

transcript

$ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz

$0123456789ABCDEFGHIJKLMNOPQRSTUVWXY_abcdefghijklmnopqrstuvwxyz

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723603 stefan_ram:723603 Ströme in Java Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723603, slrprddef723603, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/stroeme_java