CodeGym /Java Blog /Random /Isang paliwanag ng mga expression ng lambda sa Java. Sa m...
John Squirrels
Antas
San Francisco

Isang paliwanag ng mga expression ng lambda sa Java. Sa mga halimbawa at gawain. Bahagi 1

Nai-publish sa grupo
Para kanino ang artikulong ito?
  • Ito ay para sa mga taong nag-iisip na alam na nila ang Java Core, ngunit walang ideya tungkol sa mga expression ng lambda sa Java. O baka may narinig na sila tungkol sa mga expression ng lambda, ngunit kulang ang mga detalye
  • Ito ay para sa mga taong may tiyak na pag-unawa sa mga expression ng lambda, ngunit natatakot pa rin sa mga ito at hindi sanay na gamitin ang mga ito.
Isang paliwanag ng mga expression ng lambda sa Java.  Sa mga halimbawa at gawain.  Bahagi 1 - 1Kung hindi ka magkasya sa isa sa mga kategoryang ito, maaari mong makita ang artikulong ito na nakakainip, may depekto, o sa pangkalahatan ay hindi ang iyong tasa ng tsaa. Sa kasong ito, huwag mag-atubiling lumipat sa iba pang mga bagay o, kung bihasa ka sa paksa, mangyaring gumawa ng mga mungkahi sa mga komento kung paano ko mapapabuti o madagdagan ang artikulo. Ang materyal ay hindi inaangkin na may anumang akademikong halaga, pabayaan ang pagiging bago. Sa kabaligtaran: Susubukan kong ilarawan ang mga bagay na kumplikado (para sa ilang tao) nang simple hangga't maaari. Isang kahilingan na ipaliwanag ang Stream API ang nagbigay inspirasyon sa akin na isulat ito. Naisip ko ito at nagpasya na ang ilan sa aking mga halimbawa ng stream ay hindi mauunawaan nang walang pag-unawa sa mga expression ng lambda. Kaya magsisimula tayo sa mga expression ng lambda. Ano ang kailangan mong malaman upang maunawaan ang artikulong ito?
  1. Dapat mong maunawaan ang object-oriented programming (OOP), lalo na:

    • mga klase, bagay, at ang pagkakaiba sa pagitan nila;
    • mga interface, kung paano sila naiiba sa mga klase, at ugnayan sa pagitan ng mga interface at mga klase;
    • mga pamamaraan, kung paano tawagan ang mga ito, mga abstract na pamamaraan (ibig sabihin, mga pamamaraan na walang pagpapatupad), mga parameter ng pamamaraan, mga argumento ng pamamaraan at kung paano ipasa ang mga ito;
    • mga modifier sa pag-access, mga static na pamamaraan/variable, panghuling pamamaraan/variable;
    • inheritance ng mga klase at interface, multiple inheritance of interfaces.
  2. Kaalaman sa Java Core: mga generic na uri (generics), mga koleksyon (listahan), mga thread.
Well, punta na tayo dito.

Isang maliit na kasaysayan

Ang mga expression ng Lambda ay dumating sa Java mula sa functional programming, at doon mula sa matematika. Sa Estados Unidos sa kalagitnaan ng ika-20 siglo, ang Alonzo Church, na mahilig sa matematika at lahat ng uri ng abstraction, ay nagtrabaho sa Princeton University. Si Alonzo Church ang nag-imbento ng lambda calculus, na sa una ay isang hanay ng mga abstract na ideya na ganap na walang kaugnayan sa programming. Mathematicians tulad ng Alan Turing at John von Neumann nagtrabaho sa Princeton University sa parehong oras. Nagsama-sama ang lahat: Gumawa ang Simbahan ng lambda calculus. Binuo ni Turing ang kanyang abstract computing machine, na kilala ngayon bilang "Turing machine". At iminungkahi ni von Neumann ang isang arkitektura ng kompyuter na naging batayan ng mga modernong kompyuter (tinatawag na ngayong "arkitekturang von Neumann"). Noong panahong iyon, Alonzo Church' Ang mga ideya ay hindi naging napakakilala ng mga gawa ng kanyang mga kasamahan (maliban sa larangan ng purong matematika). Gayunpaman, ilang sandali pa ay naging interesado si John McCarthy (nagtapos din sa Princeton University at, sa panahon ng aming kuwento, isang empleyado ng Massachusetts Institute of Technology) sa mga ideya ng Simbahan. Noong 1958, nilikha niya ang unang functional programming language, LISP, batay sa mga ideyang iyon. At 58 taon na ang lumipas, ang mga ideya ng functional programming ay tumagas sa Java 8. Wala pang 70 taon ang lumipas... Sa totoo lang, hindi ito ang pinakamatagal para sa isang mathematical na ideya na mailapat sa pagsasanay. isang empleyado ng Massachusetts Institute of Technology) ay naging interesado sa mga ideya ng Simbahan. Noong 1958, nilikha niya ang unang functional programming language, LISP, batay sa mga ideyang iyon. At 58 taon na ang lumipas, ang mga ideya ng functional programming ay tumagas sa Java 8. Wala pang 70 taon ang lumipas... Sa totoo lang, hindi ito ang pinakamatagal para sa isang mathematical na ideya na mailapat sa pagsasanay. isang empleyado ng Massachusetts Institute of Technology) ay naging interesado sa mga ideya ng Simbahan. Noong 1958, nilikha niya ang unang functional programming language, LISP, batay sa mga ideyang iyon. At 58 taon na ang lumipas, ang mga ideya ng functional programming ay tumagas sa Java 8. Wala pang 70 taon ang lumipas... Sa totoo lang, hindi ito ang pinakamatagal para sa isang mathematical na ideya na mailapat sa pagsasanay.

Ang puso ng bagay

Ang lambda expression ay isang uri ng function. Maaari mong isaalang-alang ito bilang isang ordinaryong pamamaraan ng Java ngunit may natatanging kakayahan na maipasa sa iba pang mga pamamaraan bilang isang argumento. Tama iyan. Naging posible na ipasa hindi lamang ang mga numero, string, at pusa sa mga pamamaraan, kundi pati na rin sa iba pang mga pamamaraan! Kailan kaya natin ito kailangan? Makakatulong ito, halimbawa, kung gusto nating magpasa ng ilang paraan ng callback. Ibig sabihin, kung kailangan natin ang pamamaraang tinatawag natin upang magkaroon ng kakayahang tumawag ng ibang paraan na ipinapasa natin dito. Sa madaling salita, kaya may kakayahan kaming magpasa ng isang callback sa ilalim ng ilang partikular na sitwasyon at ibang callback sa iba. At upang ang aming pamamaraan na tumatanggap ng aming mga callback ay tumawag sa kanila. Ang pag-uuri ay isang simpleng halimbawa. Ipagpalagay na nagsusulat kami ng ilang matalinong algorithm sa pag-uuri na ganito ang hitsura:

public void mySuperSort() { 
    // We do something here 
    if(compare(obj1, obj2) > 0) 
    // And then we do something here 
}
Sa ifpahayag, tinatawag namin ang compare()pamamaraan, pagpasa sa dalawang bagay na ihahambing, at gusto naming malaman kung alin sa mga bagay na ito ang "mas malaki". Ipinapalagay namin na ang "mas malaki" ay nauuna bago ang "mas maliit". Naglagay ako ng "mas malaki" sa mga quote, dahil nagsusulat kami ng isang unibersal na pamamaraan na malalaman kung paano pag-uri-uriin hindi lamang sa pataas na pagkakasunud-sunod, kundi pati na rin sa pababang pagkakasunud-sunod (sa kasong ito, ang "mas malaki" na bagay ay talagang magiging "mas maliit" na bagay. , at kabaliktaran). Upang itakda ang partikular na algorithm para sa aming pag-uuri, kailangan namin ng ilang mekanismo upang maipasa ito sa aming mySuperSort()pamamaraan. Sa ganoong paraan, makokontrol natin ang ating pamamaraan kapag tinawag ito. Siyempre, maaari tayong magsulat ng dalawang magkahiwalay na pamamaraan - mySuperSortAscend()atmySuperSortDescend()— para sa pag-uuri sa pataas at pababang pagkakasunud-sunod. O maaari naming ipasa ang ilang argumento sa pamamaraan (halimbawa, isang boolean variable; kung totoo, pagkatapos ay ayusin sa pataas na pagkakasunud-sunod, at kung mali, pagkatapos ay sa pababang pagkakasunud-sunod). Ngunit paano kung gusto nating ayusin ang isang bagay na kumplikado tulad ng isang listahan ng mga string array? Paano mySuperSort()malalaman ng aming pamamaraan kung paano ayusin ang mga string array na ito? Sa laki? Sa pamamagitan ng pinagsama-samang haba ng lahat ng mga salita? Marahil ayon sa alpabeto batay sa unang string sa array? At paano kung kailangan nating pag-uri-uriin ang listahan ng mga array ayon sa laki ng array sa ilang mga kaso, at ayon sa pinagsama-samang haba ng lahat ng salita sa bawat array sa ibang mga kaso? Inaasahan ko na narinig mo na ang tungkol sa mga comparator at sa kasong ito ay ipapasa lang namin sa aming paraan ng pag-uuri ang isang comparator object na naglalarawan sa nais na algorithm ng pag-uuri. Dahil ang pamantayansort()pamamaraan ay ipinatupad batay sa parehong prinsipyo bilang mySuperSort(), gagamitin ko sort()sa aking mga halimbawa.

String[] array1 = {"Dota", "GTA5", "Halo"}; 
String[] array2 = {"I", "really", "love", "Java"}; 
String[] array3 = {"if", "then", "else"}; 

List<String[]> arrays = new ArrayList<>(); 
arrays.add(array1); 
arrays.add(array2); 
arrays.add(array3); 

Comparator<;String[]> sortByLength = new Comparator<String[]>() { 
    @Override 
    public int compare(String[] o1, String[] o2) { 
        return o1.length - o2.length; 
    } 
}; 

Comparator<String[]> sortByCumulativeWordLength = new Comparator<String[]>() { 

    @Override 
    public int compare(String[] o1, String[] o2) { 
        int length1 = 0; 
        int length2 = 0; 
        for (String s : o1) { 
            length1 += s.length(); 
        } 

        for (String s : o2) { 
            length2 += s.length(); 
        } 

        return length1 - length2; 
    } 
};

arrays.sort(sortByLength);
Resulta:

  1. Dota GTA5 Halo
  2. if then else
  3. I really love Java
Dito ang mga array ay pinagsunod-sunod ayon sa bilang ng mga salita sa bawat array. Ang isang array na may mas kaunting mga salita ay itinuturing na "mas maliit". Kaya naman nauuna. Ang isang array na may higit pang mga salita ay itinuturing na "mas malaki" at inilalagay sa dulo. Kung magpapasa tayo ng ibang comparator sa sort()pamamaraan, gaya ng sortByCumulativeWordLength, magkakaroon tayo ng ibang resulta:

  1. if then else
  2. Dota GTA5 Halo
  3. I really love Java
Ngayon ang mga array ay pinagsunod-sunod ayon sa kabuuang bilang ng mga titik sa mga salita ng array. Sa unang hanay, mayroong 10 letra, sa pangalawa — 12, at sa pangatlo — 15. Kung mayroon lamang tayong isang comparator, hindi na natin kailangang magdeklara ng hiwalay na variable para dito. Sa halip, maaari lang tayong lumikha ng hindi kilalang klase sa mismong oras ng tawag sa sort()pamamaraan. Isang bagay na tulad nito:

String[] array1 = {"Dota", "GTA5", "Halo"}; 
String[] array2 = {"I", "really", "love", "Java"}; 
String[] array3 = {"if", "then", "else"}; 

List<String[]> arrays = new ArrayList<>(); 

arrays.add(array1); 
arrays.add(array2); 
arrays.add(array3); 

arrays.sort(new Comparator<String[]>() { 
    @Override 
    public int compare(String[] o1, String[] o2) { 
        return o1.length - o2.length; 
    } 
}); 
Makukuha namin ang parehong resulta tulad ng sa unang kaso. Gawain 1. Isulat muli ang halimbawang ito upang pag-uri-uriin nito ang mga array hindi sa pataas na pagkakasunud-sunod ng bilang ng mga salita sa bawat array, ngunit sa pababang pagkakasunud-sunod. Alam na natin ang lahat ng ito. Alam namin kung paano ipasa ang mga bagay sa mga pamamaraan. Depende sa kung ano ang kailangan namin sa ngayon, maaari naming ipasa ang iba't ibang mga bagay sa isang pamamaraan, na pagkatapos ay i-invoke ang pamamaraan na aming ipinatupad. Nagtatanong ito: bakit sa mundo kailangan natin ng lambda expression dito?  Dahil ang lambda expression ay isang bagay na may eksaktong isang paraan. Tulad ng isang "bagay na pamamaraan". Isang paraan na nakabalot sa isang bagay. Mayroon lamang itong bahagyang hindi pamilyar na syntax (ngunit higit pa sa paglaon). Tingnan natin muli ang code na ito:

arrays.sort(new Comparator<String[]>() { 
    @Override 
    public int compare(String[] o1, String[] o2) { 
        return o1.length - o2.length; 
    } 
});
Dito namin kinukuha ang aming listahan ng mga arrays at tinawag ang sort()pamamaraan nito, kung saan ipinapasa namin ang isang comparator object na may iisang compare()paraan (hindi mahalaga sa amin ang pangalan nito — kung tutuusin, ito lang ang paraan ng object na ito, kaya hindi kami maaaring magkamali). Ang pamamaraang ito ay may dalawang parameter na gagamitin namin. Kung nagtatrabaho ka sa IntelliJ IDEA, malamang na nakita mo itong nag-aalok ng makabuluhang paikliin ang code tulad ng sumusunod:

arrays.sort((o1, o2) -> o1.length - o2.length);
Binabawasan nito ang anim na linya sa isang solong maikli. 6 na linya ay muling isinulat bilang isang maikli. May nawala, ngunit ginagarantiya ko na hindi ito mahalaga. Ang code na ito ay gagana nang eksakto sa parehong paraan tulad ng sa isang hindi kilalang klase. Gawain 2. Maghula sa muling pagsulat ng solusyon sa Gawain 1 gamit ang isang lambda expression (kahit hindi bababa sa, hilingin sa IntelliJ IDEA na i-convert ang iyong anonymous na klase sa isang lambda expression).

Pag-usapan natin ang tungkol sa mga interface

Sa prinsipyo, ang isang interface ay isang listahan lamang ng mga abstract na pamamaraan. Kapag lumikha kami ng isang klase na nagpapatupad ng ilang interface, dapat ipatupad ng aming klase ang mga pamamaraan na kasama sa interface (o kailangan nating gawing abstract ang klase). Mayroong mga interface na may maraming iba't ibang pamamaraan (halimbawa,  List), at may mga interface na may isang paraan lamang (halimbawa, Comparatoro Runnable). May mga interface na walang iisang paraan (tinatawag na mga marker interface tulad ng Serializable). Ang mga interface na mayroon lamang isang paraan ay tinatawag ding mga functional na interface . Sa Java 8, minarkahan pa sila ng isang espesyal na anotasyon:@FunctionalInterface. Ang mga single-method na interface na ito ang angkop bilang mga uri ng target para sa mga expression ng lambda. Tulad ng sinabi ko sa itaas, ang isang lambda expression ay isang paraan na nakabalot sa isang bagay. At kapag naipasa natin ang naturang bagay, mahalagang ipinapasa natin ang solong pamamaraang ito. Lumalabas na wala kaming pakialam kung ano ang tawag sa pamamaraan. Ang tanging bagay na mahalaga sa amin ay ang mga parameter ng pamamaraan at, siyempre, ang katawan ng pamamaraan. Sa esensya, ang isang lambda expression ay ang pagpapatupad ng isang functional na interface. Saanman tayo makakita ng interface na may iisang pamamaraan, ang isang hindi kilalang klase ay maaaring muling isulat bilang isang lambda. Kung ang interface ay may higit o mas kaunti sa isang paraan, hindi gagana ang isang lambda expression at sa halip ay gagamit kami ng anonymous na klase o kahit isang instance ng isang ordinaryong klase. Ngayon ay oras na upang maghukay ng kaunti sa mga lambdas. :)

Syntax

Ang pangkalahatang syntax ay katulad nito:

(parameters) -> {method body}
Iyon ay, ang mga panaklong nakapalibot sa mga parameter ng pamamaraan, isang "arrow" (nabubuo ng isang gitling at mas malaki kaysa sa tanda), at pagkatapos ay ang katawan ng pamamaraan sa mga tirante, gaya ng lagi. Ang mga parameter ay tumutugma sa mga tinukoy sa paraan ng interface. Kung ang mga uri ng variable ay maaaring malinaw na matukoy ng compiler (sa aming kaso, alam nito na nagtatrabaho kami sa mga string array, dahil ang aming Listobject ay nai-type gamit ang String[]), hindi mo na kailangang ipahiwatig ang kanilang mga uri.
Kung ang mga ito ay hindi maliwanag, pagkatapos ay ipahiwatig ang uri. Kukulayan ito ng IDEA ng gray kung hindi ito kailangan.
Maaari kang magbasa nang higit pa sa Oracle tutorial na ito at sa ibang lugar. Ito ay tinatawag na " target na pagta-type ". Maaari mong pangalanan ang mga variable kahit anong gusto mo — hindi mo kailangang gumamit ng parehong mga pangalan na tinukoy sa interface. Kung walang mga parameter, ipahiwatig lamang ang mga walang laman na panaklong. Kung mayroon lamang isang parameter, ipahiwatig lamang ang pangalan ng variable nang walang anumang panaklong. Ngayong naiintindihan na natin ang mga parameter, oras na para talakayin ang katawan ng lambda expression. Sa loob ng mga kulot na braces, sumusulat ka ng code tulad ng gagawin mo para sa isang ordinaryong paraan. Kung ang iyong code ay binubuo ng isang linya, maaari mong ganap na alisin ang mga kulot na brace (katulad ng mga if-statement at for-loops). Kung may ibinalik ang iyong single-line na lambda, hindi mo kailangang isama ang areturnpahayag. Ngunit kung gagamit ka ng mga kulot na brace, dapat mong tahasang isama ang isang returnpahayag, tulad ng gagawin mo sa isang ordinaryong paraan.

Mga halimbawa

Halimbawa 1.

() -> {}
Ang pinakasimpleng halimbawa. At ang pinaka walang kabuluhan :), dahil wala itong ginagawa. Halimbawa 2.

() -> ""
Isa pang kawili-wiling halimbawa. Wala itong kailangan at ibinabalik ang isang walang laman na string ( returnay tinanggal, dahil hindi ito kailangan). Narito ang parehong bagay, ngunit may return:

() -> { 
    return ""; 
}
Halimbawa 3. "Hello, World!" gamit ang lambdas

() -> System.out.println("Hello, World!")
Wala itong kailangan at wala nang ibinabalik (hindi namin mailalagay returnbago ang tawag sa System.out.println(), dahil ang println()uri ng pagbabalik ng pamamaraan ay void). Pinapakita lang nito ang pagbati. Ito ay perpekto para sa isang pagpapatupad ng Runnableinterface. Ang sumusunod na halimbawa ay mas kumpleto:

public class Main { 
    public static void main(String[] args) { 
        new Thread(() -> System.out.println("Hello, World!")).start(); 
    } 
}
O tulad nito:

public class Main { 
    public static void main(String[] args) { 
        Thread t = new Thread(() -> System.out.println("Hello, World!")); 
        t.start();
    } 
}
O maaari nating i-save ang expression ng lambda bilang isang Runnablebagay at pagkatapos ay ipasa ito sa Threadconstructor:

public class Main { 
    public static void main(String[] args) { 
        Runnable runnable = () -> System.out.println("Hello, World!"); 
        Thread t = new Thread(runnable); 
        t.start(); 
    } 
}
Tingnan natin ang sandali kung kailan na-save ang isang lambda expression sa isang variable. Sinasabi sa amin ng Runnableinterface na ang mga bagay nito ay dapat may isang public void run()pamamaraan. Ayon sa interface, ang runpamamaraan ay walang mga parameter. At wala itong ibinabalik, ibig sabihin, ang uri ng pagbabalik nito ay void. Alinsunod dito, lilikha ang code na ito ng isang bagay na may paraan na hindi kumukuha o nagbabalik ng anuman. Ito ay ganap na tumutugma sa paraan Runnableng interface run(). Iyon ang dahilan kung bakit nagawa naming ilagay ang lambda expression na ito sa isang Runnablevariable.  Halimbawa 4.

() -> 42
Muli, wala itong kailangan, ngunit ibinabalik nito ang numerong 42. Ang nasabing lambda expression ay maaaring ilagay sa isang Callablevariable, dahil ang interface na ito ay may isang paraan lamang na mukhang ganito:

V call(),
nasaan  V ang uri ng pagbabalik (sa aming kaso,  int). Alinsunod dito, maaari naming i-save ang isang lambda expression tulad ng sumusunod:

Callable<Integer> c = () -> 42;
Halimbawa 5. Isang lambda expression na kinasasangkutan ng ilang linya

() -> { 
    String[] helloWorld = {"Hello", "World!"}; 
    System.out.println(helloWorld[0]); 
    System.out.println(helloWorld[1]); 
}
Muli, ito ay isang lambda expression na walang mga parameter at isang voiduri ng pagbabalik (dahil walang returnpahayag).  Halimbawa 6

x -> x
Dito kukuha kami ng xvariable at ibabalik ito. Pakitandaan na kung mayroon lamang isang parameter, maaari mong alisin ang mga panaklong sa paligid nito. Narito ang parehong bagay, ngunit may mga panaklong:

(x) -> x
At narito ang isang halimbawa na may tahasang pahayag ng pagbabalik:

x -> { 
    return x;
}
O tulad nito na may mga panaklong at isang return statement:

(x) -> { 
    return x;
}
O may tahasang indikasyon ng uri (at sa gayon ay may mga panaklong):

(int x) -> x
Halimbawa 7

x -> ++x
Kinukuha xat ibinabalik namin ito, ngunit pagkatapos lamang magdagdag ng 1. Maaari mong muling isulat ang lambda na iyon tulad nito:

x -> x + 1
Sa parehong mga kaso, tinanggal namin ang mga panaklong sa paligid ng parameter at katawan ng pamamaraan, kasama ang returnpahayag, dahil opsyonal ang mga ito. Ang mga bersyon na may panaklong at isang return statement ay ibinigay sa Halimbawa 6. Halimbawa 8

(x, y) -> x % y
Kinukuha namin xat yibinabalik ang natitirang bahagi ng xsa pamamagitan ng y. Ang mga panaklong sa paligid ng mga parameter ay kinakailangan dito. Opsyonal lang ang mga ito kapag may isang parameter lang. Narito ito na may tahasang indikasyon ng mga uri:

(double x, int y) -> x % y
Halimbawa 9

(Cat cat, String name, int age) -> {
    cat.setName(name); 
    cat.setAge(age); 
}
Kumuha kami ng isang Catbagay, isang Stringpangalan, at isang int na edad. Sa mismong pamamaraan, ginagamit namin ang nakapasa na pangalan at edad upang magtakda ng mga variable sa pusa. Dahil ang aming catobject ay isang uri ng sanggunian, babaguhin ito sa labas ng lambda expression (kukuha nito ang ipinasang pangalan at edad). Narito ang isang bahagyang mas kumplikadong bersyon na gumagamit ng katulad na lambda:

public class Main { 

    public static void main(String[] args) { 
        // Create a cat and display it to confirm that it is "empty" 
        Cat myCat = new Cat(); 
        System.out.println(myCat);
 
        // Create a lambda 
        Settable<Cat> s = (obj, name, age) -> { 
            obj.setName(name); 
            obj.setAge(age); 

        }; 

        // Call a method to which we pass the cat and lambda 
        changeEntity(myCat, s); 

        // Display the cat on the screen and see that its state has changed (it has a name and age) 
        System.out.println(myCat); 

    } 

    private static <T extends HasNameAndAge>  void changeEntity(T entity, Settable<T> s) { 
        s.set(entity, "Smokey", 3); 
    }
}

interface HasNameAndAge { 
    void setName(String name); 
    void setAge(int age); 
}

interface Settable<C extends HasNameAndAge> { 
    void set(C entity, String name, int age); 
}

class Cat implements HasNameAndAge { 
    private String name; 
    private int age; 

    @Override 
    public void setName(String name) { 
        this.name = name;
    }

    @Override
    public void setAge(int age) {
        this.age = age; 
    } 

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' + 
                ", age=" + age + 
                '}';
    }
}
Resulta:

Cat{name='null', age=0}
Cat{name='Smokey', age=3}
Tulad ng nakikita mo, ang Catbagay ay may isang estado, at pagkatapos ay nagbago ang estado pagkatapos naming gamitin ang lambda expression. Ang mga expression ng Lambda ay perpektong pinagsama sa mga generic. At kung kailangan nating lumikha ng isang Dogklase na nagpapatupad din ng HasNameAndAge, maaari nating gawin ang parehong mga operasyon sa Dogpamamaraan main() nang hindi binabago ang expression ng lambda. Gawain 3. Sumulat ng functional na interface na may paraan na kumukuha ng numero at nagbabalik ng boolean value. Sumulat ng pagpapatupad ng naturang interface bilang isang lambda expression na nagbabalik ng true kung ang naipasa na numero ay nahahati sa 13. Gawain 4.Sumulat ng isang functional na interface na may isang paraan na tumatagal ng dalawang mga string at nagbabalik din ng isang string. Sumulat ng pagpapatupad ng naturang interface bilang isang lambda expression na nagbabalik ng mas mahabang string. Gawain 5. Sumulat ng isang functional na interface na may paraan na kumukuha ng tatlong floating-point na numero: a, b, at c at nagbabalik din ng floating-point na numero. Sumulat ng pagpapatupad ng naturang interface bilang isang lambda expression na nagbabalik ng discriminant. Kung sakaling nakalimutan mo, iyon ay D = b^2 — 4ac. Gawain 6. Gamit ang functional interface mula sa Gawain 5, sumulat ng lambda expression na nagbabalik ng resulta ng a * b^c. Isang paliwanag ng mga expression ng lambda sa Java. Sa mga halimbawa at gawain. Bahagi 2
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION