Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
1
Java 8: Mary Had a Little Lambda
! ? krit. poznamky jo jojo PJV25
2
Java 8: “Mary Had a Little Lambda”
std std tutorial slabe Zavádí prvky funkcionálního programování. Zvyšuje se expresivní síla jazyka, ale API ji omezují. Nově zavedené util.streamy představují agregované operace a podporují paralelismus - tedy efektivnější zpracování. Využívají interní iterace, jimiž lze rozdělit data více vláknům vykonávaných případně více procesory. K ovládání operací se využívají LE jako argumenty metod. Interní iterace umožňují reordering, zkrat, paralelismus a lenost. Inversion of control: Hollywood principle: " Don't call us, we'll call you " . PJV25
3
Java 8 / nové kousky java.time .chrono .format .temporal .zone
java.util.function: obsahuje pouze funkcionální interfejsy Bi+, Int+, Double+, Long+ Consumer, Function, Predicate, Supplier, UnaryOperator, BinaryOperator java.util.stream: Collector, BaseStream<…>, Stream<T>, CloseableStream ?? ( Int | Long | Double )Stream, Collectors, StreamSupport , DelegatingStreams ?? java.util: PrimitiveIterator, Spliterator Base64, Spliterators, StringJoiner Optional ( Int | Long | Double | <T> ) ( Int | Long | Double )SummaryStatistics, PJV25
4
Java 8 / nové triky Efektivně finální je ta proměnná jež se nemění – byť není final. Nové symboly: -> šipka, typová inference ( vnesení, úsudek, vyvození ) :: reference metod a konstruktorů Další užití klíčových slov: default a super Podstatné rozšíření možnosti interfejsu: Jednak o static metody, jednak o default nestatické konkrétní metody. Rozlišují se tzv. SAM ( Single Abstract Method ) interfejsy mající právě jednu abstraktní metodu ( krom generálních ) - tzv. funkcionální interfejs - slouží jako cílový typ pro Lambda Expression a reference metod. Mívá anotaci @FunctionalInterface - což není nutné leč vhodné. Např. tyto interfejsy jsou funkcionální: java.lang.Runnable ( neobohacený ) java.lang.Comparable<T> ( neobohacený ) java.util.Comparator <T> ( značně obohacený ) java.awt.event.ActionListener ( neobohacený ) java.util.function.Consumer <T> ( nový balíček ) PJV25
5
JSR-335 Closures Closure ( uzávěr ) umožňuje vytvářet reference funkcí a předávat je jako parametry a tedy metody jsou schopné přiložit snímek svého kontextu. PJV25
6
Lambda výraz ( LE = Lambda Expression )
LE je objekt typu určený funkcionálním interfejsem, zvaný target type, jenž se hledá inferencí z kontextu: na shodu počtu a typů parametrů na kompatibilitu návratového typu na kompatibilitu výrazem vyhazovaných vyjímek LE má >=0 parametrů explicitně deklarovaných či odvozených z kontextu, parametry jsou v závorkách separovány čárkou, pro jediný parametr závorek netřeba. Tělo LE obsahuje >= 0 příkazů ve složených závorkách. Pro jediný příkaz závorek netřeba. Návratový typ anonymní funkce je týž jako tělo výrazu. Při více příkazech je návratový typ anonymní funkce je týž jako typ hodnoty vracené returnem anebo void je-li bez returnu. PJV25
7
Syntax LE _ > ( ) nulární [ T ] p T – typ explicitně či inferencí
( [ T1 ] p1 [ , [ T2 ] p2, … ] ) p - parametr šipka („arrow token“) e výraz { … ; return e ; } pro metodu-funkci { … ; m( … ) ; [ return; ] } pro void metodu { [ return; ] } prázdné LE jsou realizovány jako anonymní třídy: zmírňují vertikální rozsah zdrojového kódu. lépe vyjadřují this a nedovolují zastiňování proměnných – na rozdil od anonymních tříd. Lokální proměnné referované v LE musejí být [efektivně] final break a continue lze užít jen uvnitř - neovliňují vnější cykly nebo switch _ > PJV25
8
Příklady inference LE new Thread( ( ) -> { System.out.println( ) ; } ).start( ); // vede k new Thread( new Runnable( ) { public void run( ) { System.out.println( ) ; } } ).start( ); ActionListener al = u -> { long w = u.getWhen( ); [ return; ] }; // vede k: ActionListener al = new ActionListener( ) { public void actionPerformed( ActionEvent u ) { long w = u.getWhen( ); [ return; ] } }; Runnable ActionEvent získáno inferencí PJV25
9
Příklady inference LE Comparator<Double> coD = ( s1, s2 ) -> s1.compareTo( s2 ); // vede k: Comparator<Double> coD = new Comparator<Double> ( ) { public int compare( Double s1, Double s2 ) { return s1.compareTo( s2 ); } } // Comparator je obohacen o 9 static a 7 default metod Comparator<Float> coF = ( s1, s2 ) -> Float.compare( s1, s2 ); Comparator<Float> coF = new Comparator<Float> ( ) { public int compare( Float s1, Float s2 ) { return Float.compareTo( s1, s2 ); získáno inferencí PJV25
10
Příklady řazení String[ ] p = { "B", "A", "C" }; Arrays.sort( p, ( Comparators.reversal ); Arrays.sort( p, ( a, b ) -> a.compareTo( b ) ); Arrays.sort( p, String::compareTo ); Arrays.sort( p, Comparators::descending ); Arrays.sort( p, ( new Comparators( ) { } )::normal ); Comparators cs = new Comparators( ) { }; // předchozí případ jinak Comparator<String> c = cs::normal; Arrays.sort( p, c.reversed( ) ); // reversed() viz Comparator kde: interface Comparators { // vlastní příhodný interfejs static Comparator<String> reversal = ( a, b ) -> - a.compareTo(b); static int ascending(String a, String b) { return +a.compareTo(b); } static int descending(String a, String b) { return -a.compareTo(b); } default int normal(String a, String b) { return a.compareTo(b); } } PJV25
11
Reference metod Symbol :: referuje metodu [ne]statickou anebo konstruktor takto: [ Typ id = ] ( Typ | objekt ~ this | ) :: jménoMetody jménoKonstruktoru [ [ ] ] :: new Příklad: interface Converter<T,R> { public R convert( T t ); static final Converter<Integer, Integer> CF = C -> 9 * C / ; // Celsius -> Fahrenheit static final Converter<Number, Double> KMHtoMSEC = v -> v.doubleValue( ) * 1000 / 3600; // km/hod -> m/sec } Converter<String, Integer> S_I = Integer::valueOf; int i = S_I.convert("123"); double f = Converter.CF.convert( 20 ); double v = Converter.KMHtoMSEC.convert( 36 ); PJV25
12
Reference metod Symbol :: referuje metodu či konstruktor coby argument takto: Typ :: jménoStatickéMetody ( objekt | this ) :: jménoInstančníMetody jménoKonstruktoru [ [ ] … ] :: new PJV25
13
Reference metod Příklad: String[ ] p = { "Z", "Y", "X" }; Arrays.sort( p, String :: compareTo ); // vede k: Arrays.sort( p, ( string, anotherString )->string.compareTo(anotherString) ); Arrays.sort( p, new Comparator<String>( ) { public int compare( String _this, String anotherString ) { return _this.compareTo( anotherString ); } } ); PJV25
14
Reference Symbol :: je zástupka za LE, metoda či konstruktor se však tím nevolá. button1.addActionListener( MyFrame::ms ); // ms je void static ( ev -> { MyFrame.m(ev); } ); button2.addActionListener( MyFrame.this::mn ); // mn je void ( ev -> { MyFrame.this.mn(ev); } ); // při překladu se však dosadí retrurn byť je ms či mn void PJV25
15
Default metody Interfejs může definovat default nestatické konkrétní metody. Implementující třídy nemusejí tyto metody překrýt. Rozšiřující interfejs může překrýt abstract metodu default metodou a i opačně. Defaultní metody nejsou přístupné z LE. Při konfliktu dvou defaultních metod …m(…), lze vybrat jednu z nich takto: class Z implements A, B { public … m(…) { return A.super.m(…); } } PJV25
16
Příklad Řešení kvadratické rovnice pro reálné kořeny. Pro komplexní kořeny vrací NaN. Quad q1 = ( a, b, c ) -> ( -b + sqrt( b*b - 4*a*c ) ) / ( 2*a ); // tak Quad q2 = ( a, b, c ) -> ( -b - Quad.dis( a, b, c ) ) / ( 2*a ); // či tak double x1 = q1.solve( 2.0, 5.0, -3.0 ), x2 = q2.solve( 2.0, 5.0, -3.0 ); interface Quad { public double solve( double a, double b, double c ); public static double dis( double a, double b, double c) { // diskriminant return Math.sqrt( b*b - 4*a*c ); } PJV25
17
Obohacení java.util v 1.8 Optional SplitIterators OptionalInt Iterator
IntConsumer LongConsumer Iterator SplitIterator <E> <T> LongSummary Statistics SplitIterators OptionalInt PrimitiveIterator <T> IntSummary Statistics DoubleConsumer DoubleSummary Statistics Base64 Int alter Long Double PJV25
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.