1. Mga paraan ng pag-andar

Kung ang isang interface ay may isang paraan lamang , ang isang variable ng ganoong uri ng interface ay maaaring magtalaga ng isang halaga na ibinigay ng isang lambda expression (lambda function). Ang ganitong mga interface ay naging kilala bilang mga functional na interface (pagkatapos ng Java na magdagdag ng suporta para sa mga function ng lambda).

Halimbawa, ang Java ay may Consumer<Type>interface, na mayroong accept(Type obj)pamamaraan. Bakit kailangan ang interface na ito?

Sa Java 8, ang mga koleksyon ay may forEach()pamamaraan, na nagbibigay-daan sa iyong magsagawa ng ilang aksyon para sa bawat elemento ng koleksyon . At dito ang Consumer<T>functional na interface ay ginagamit upang ipasa ang aksyon sa forEach()pamamaraan.

Narito kung paano mo maipapakita ang lahat ng elemento ng isang koleksyon :

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Hello", "how's", "life?");

list.forEach( (s) -> System.out.println(s) );
Ipinapakita ang lahat ng elemento ng isang koleksyon (gamit ang isang lambda expression)

Iko-convert ng compiler ang code sa itaas sa code sa ibaba:

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Hello", "how's", "life?");

list.forEach(new Consumer<String>()
{
   public void accept(String s)
   {
      System.out.println(s));
   }
});
Ipinapakita ang lahat ng elemento ng isang koleksyon (gamit ang isang hindi kilalang klase)

Ang unang bersyon ay tiyak na mas maikli kaysa sa pangalawa. At habang ang code na may mga expression ng lambda ay mahirap basahin, ang code na may anonymous na mga panloob na klase ay minsan ay mas mahirap basahin.



2. Sanggunian ng pamamaraan

Gayunpaman, ang aming lambda expression code ay maaaring maisulat nang mas maikli.

Una, maaari mong alisin ang mga panaklong sa paligid ng sparameter:

list.forEach( (s) -> System.out.println(s) );
dati
list.forEach( s -> System.out.println(s) );
Pagkatapos

Magagawa lamang ito kung mayroong isang parameter . Kung mayroong maraming mga parameter, dapat kang gumamit ng mga panaklong .

At pangalawa, maaari mong isulat ito tulad nito:

list.forEach( System.out::println );
Karamihan sa mga compact na notasyon

Ito ang eksaktong parehong notasyon. Tandaan na walang panaklong pagkatapos ng println.

Narito mayroon kaming parehong code - isang tawag sa pamamaraan:

object::method
x -> object.method(x)

Pag-isipan ito: gusto naming magsagawa ng ilang aksyon para sa bawat elemento ng listkoleksyon. Kung ang aksyon ay iisang function na tawag (tulad ng println()), makatuwirang ipasa lang ang function sa pamamaraan bilang isang parameter.

Ngunit paano natin ipapaliwanag sa compiler na gusto nating ipasa ang pamamaraan sa halip na tawagan ito? Upang gawin ito, sa halip na ang operator ng tuldok, gumagamit kami ng dalawang colon bago ang pangalan ng pamamaraan. Ginagamit na ang isang colon upang ipahiwatig ang ternary operator.

Ito ang pinakasimple at pinaka compact na notation.



3. Tagabuo

Ang mga sanggunian ng pamamaraan na may mga double colon ay napakadaling gamitin kapag nagtatrabaho kami sa mga stream ng I/O. Makikita mo ito mamaya.

Pansamantala, pag-usapan natin ang tungkol sa 3 tanyag na paraan upang maipasa ang isang sanggunian ng pamamaraan:

Sanggunian sa isang paraan ng isang bagay

Upang magpasa ng isang sanggunian sa isang paraan ng isang bagay, kailangan mong magsulat ng isang bagay tulad ng . Ang code na ito ay katumbas ng .object::method
x -> object.method(x)

Ang mga espesyal thisat supervariable ay maaaring gamitin bilang object.

Sanggunian sa isang paraan ng isang klase

Upang magpasa ng isang sanggunian sa isang static na pamamaraan, kailangan mong magsulat ng isang bagay tulad ng . Ang code na ito ay mako-convert sa tulad ng codeclass::methodx -> class.method(x);

Sanggunian sa isang constructor

Ang isang konstruktor ay kumikilos nang katulad sa isang static na pamamaraan ng klase, kaya maaari ka ring magpasa ng isang sanggunian sa isang konstruktor. Ganito ang hitsura nito: .class::new

Halimbawa, maaari kang makalibot sa uri ng erasure para sa mga koleksyon at ipasa ang toArray()pamamaraan ng isang reference sa isang constructor na lilikha ng nais na array:toArray(int[]::new);