1. Antarmuka

Kanggo ngerti apa fungsi lambda, sampeyan kudu ngerti apa antarmuka. Dadi, ayo ngelingi poin utama.

Antarmuka minangka variasi saka konsep kelas. Kelas sing dipotong banget, ayo ngomong. Ora kaya kelas, antarmuka ora bisa duwe variabel dhewe (kajaba statis). Sampeyan uga ora bisa nggawe obyek sing jinis antarmuka:

  • Sampeyan ora bisa ngumumake variabel kelas
  • Sampeyan ora bisa nggawe obyek

Tuladha:

interface Runnable
{
   void run();
}
Conto antarmuka standar

Nggunakake antarmuka

Dadi kenapa antarmuka dibutuhake? Antarmuka mung digunakake bebarengan karo warisan. Antarmuka sing padha bisa diwarisake dening kelas sing beda-beda, utawa kaya sing dikandhakake - classes implement the interface .

Yen kelas ngleksanakake antarmuka, iku kudu ngleksanakake cara ngumumaké dening nanging ora dipun ginakaken dening antarmuka. Tuladha:

interface Runnable
{
   void run();
}

class Timer implements Runnable
{
   void run()
   {
      System.out.println(LocalTime.now());
   }
}

class Calendar implements Runnable
{
   void run()
   {
      var date = LocalDate.now();
      System.out.println("Today: " + date.getDayOfWeek());
   }
}

Kelas Timerngleksanakake Runnableantarmuka, mula kudu ngumumake kabeh cara sing ana ing antarmuka Runnablelan ngetrapake, yaiku nulis kode ing awak metode. Semono uga ing Calendarkelas.

Nanging saiki Runnablevariabel bisa nyimpen referensi kanggo obyek sing ngleksanakake Runnableantarmuka.

Tuladha:

Kode Cathetan
Timer timer = new Timer();
timer.run();

Runnable r1 = new Timer();
r1.run();

Runnable r2 = new Calendar();
r2.run();

Metode run()ing Timerkelas bakal disebut


Metode run()ing Timerkelas bakal disebut


Metode run()ing Calendarkelas bakal disebut

Sampeyan bisa tansah nemtokake referensi obyek kanggo variabel saka sembarang tipe, anggere jinis iku salah siji saka kelas leluhur obyek. Kanggo kelas Timerlan Calendar, ana rong jinis kasebut: Objectlan Runnable.

Yen sampeyan nemtokake referensi obyek menyang Objectvariabel, sampeyan mung bisa nelpon cara sing diumumake ing Objectkelas kasebut. Lan yen sampeyan nemtokake referensi obyek menyang Runnablevariabel, sampeyan bisa nelpon metode jinis kasebut Runnable.

Tuladha 2:

ArrayList<Runnable> list = new ArrayList<Runnable>();
list.add (new Timer());
list.add (new Calendar());

for (Runnable element: list)
    element.run();

Kode iki bakal bisa, amarga Timerlan Calendarobyek wis mbukak cara sing bisa digunakake kanthi becik. Dadi, nelpon dheweke ora masalah. Yen kita wis mung ditambahaké roto () cara kanggo loro kelas, banjur kita ora bakal bisa nelpon ing kuwi cara prasaja.

Sejatine, Runnableantarmuka mung digunakake minangka panggonan kanggo nyelehake cara roto.



2. Ngurutake

Ayo pindhah menyang sing luwih praktis. Contone, ayo goleki ngurutake senar.

Kanggo ngurutake koleksi senar miturut abjad, Jawa nduweni cara sing apik sing diaraniCollections.sort(collection);

Cara statis iki ngurutake koleksi sing dilewati. Lan ing proses ngurutake, nindakake perbandingan pasangan saka unsur kasebut supaya ngerti apa unsur kudu diganti.

Sajrone ngurutake, perbandingan kasebut ditindakake kanthi nggunakake compareTometode () sing kabeh kelas standar duwe: Integer, String, ...

Metode compareTo () saka kelas Integer mbandhingake nilai saka rong nomer, dene metode compareTo () saka kelas String katon ing urutan alfabet strings.

Dadi koleksi nomer bakal diurutake kanthi urutan munggah, dene koleksi string bakal diurutake miturut abjad.

Algoritma ngurutake alternatif

Nanging kepiye yen kita pengin ngurutake senar ora miturut abjad, nanging kanthi dawa? Lan yen kita pengin ngurutake nomer ing urutan mudhun? Apa sing sampeyan tindakake ing kasus iki?

Kanggo nangani kahanan kasebut, Collectionskelas kasebut duwe sort()metode liyane sing duwe rong paramèter:

Collections.sort(collection, comparator);

Ngendi komparator minangka obyek khusus sing ngerti carane mbandhingake obyek ing koleksi sajrone operasi ngurutake . Istilah comparator asalé saka tembung comparator Inggris , sing asalé saka comparison , tegesé "kanggo mbandhingaké".

Dadi apa obyek khusus iki?

Comparatorantarmuka

Inggih, kabeh iku prasaja banget. Jinis sort()paramèter kapindho metode yaikuComparator<T>

Ngendi T minangka parameter jinis sing nuduhake jinis unsur ing koleksi , lan Comparatorminangka antarmuka sing nduweni metode siji.int compare(T obj1, T obj2);

Ing tembung liyane, obyek komparator iku sembarang obyek saka sembarang kelas sing ngleksanakake antarmuka Comparator. Antarmuka Comparator katon prasaja banget:

public interface Comparator<Type>
{
   public int compare(Type obj1, Type obj2);
}
Kode kanggo antarmuka Comparator

Cara kasebut compare()mbandhingake rong argumen sing diterusake.

Yen cara ngasilake nomer negatif, tegese obj1 < obj2. Yen cara ngasilake angka positif, tegese obj1 > obj2. Yen metode ngasilake 0, tegese obj1 == obj2.

Iki minangka conto obyek komparator sing mbandhingake senar kanthi dawa:

public class StringLengthComparator implements Comparator<String>
{
   public int compare (String obj1, String obj2)
   {
      return obj1.length() – obj2.length();
   }
}
Kode StringLengthComparatorkelas

Kanggo mbandhingake dawa senar, mung nyuda siji dawa saka liyane.

Kode lengkap kanggo program sing ngurutake senar kanthi dawa bakal katon kaya iki:

public class Solution
{
   public static void main(String[] args)
   {
      ArrayList<String> list = new ArrayList<String>();
      Collections.addAll(list, "Hello", "how's", "life?");
      Collections.sort(list, new StringLengthComparator());
   }
}

class StringLengthComparator implements Comparator<String>
{
   public int compare (String obj1, String obj2)
   {
      return obj1.length() – obj2.length();
   }
}
Ngurutake senar miturut dawa


3. Gula sintaksis

Apa sampeyan mikir, apa kode iki bisa ditulis luwih kompak? Sejatine, mung ana siji baris sing ngemot informasi migunani - obj1.length() - obj2.length();.

Nanging kode ora bisa ana njaba cara, supaya kita kudu nambah compare()cara, lan kanggo nyimpen cara kita kudu nambah kelas anyar - StringLengthComparator. Lan kita uga kudu nemtokake jinis variabel ... Kabeh katon bener.

Nanging ana cara kanggo nggawe kode iki luwih cendhek. Kita duwe gula sintaksis kanggo sampeyan. Loro scoop!

Kelas batin anonim

Sampeyan bisa nulis kode komparator tengen ing main()cara, lan compiler bakal nindakake liyane. Tuladha:

public class Solution
{
    public static void main(String[] args)
    {
        ArrayList<String> list = new ArrayList<String>();
        Collections.addAll(list, "Hello", "how's", "life?");

        Comparator<String> comparator = new Comparator<String>()
        {
            public int compare (String obj1, String obj2)
            {
                return obj1.length() – obj2.length();
            }
        };

        Collections.sort(list, comparator);
    }
}
Urut senar miturut dawa

Sampeyan bisa nggawe obyek sing ngetrapake Comparatorantarmuka tanpa nggawe kelas kanthi jelas! Compiler bakal nggawe kanthi otomatis lan menehi sawetara jeneng sementara. Ayo mbandhingake:

Comparator<String> comparator = new Comparator<String>()
{
    public int compare (String obj1, String obj2)
    {
        return obj1.length() – obj2.length();
    }
};
Kelas batin anonim
Comparator<String> comparator = new StringLengthComparator();

class StringLengthComparator implements Comparator<String>
{
    public int compare (String obj1, String obj2)
    {
        return obj1.length() – obj2.length();
    }
}
StringLengthComparatorkelas

Werna sing padha digunakake kanggo nuduhake blok kode sing padha ing rong kasus sing beda. Bentenipun cukup cilik ing laku.

Nalika compiler ketemu pemblokiran pisanan kode, iku mung ngasilake pemblokiran kaloro kode lan menehi kelas sawetara jeneng acak.


4. Ukara Lambda ing basa Jawa

Contone, sampeyan arep nggunakake kelas jero anonim ing kode sampeyan. Ing kasus iki, sampeyan bakal duwe blok kode kaya iki:

Comparator<String> comparator = new Comparator<String>()
{
    public int compare (String obj1, String obj2)
    {
        return obj1.length() – obj2.length();
    }
};
Kelas batin anonim

Ing kene kita gabungke deklarasi variabel karo nggawe kelas anonim. Nanging ana cara kanggo nggawe kode iki luwih cendhek. Contone, kaya iki:

Comparator<String> comparator = (String obj1, String obj2) ->
{
    return obj1.length() – obj2.length();
};

Titik koma dibutuhake amarga ing kene ora mung deklarasi kelas implisit, nanging uga nggawe variabel.

Notasi kaya iki diarani ekspresi lambda.

Yen kompiler nemoni notasi kaya iki ing kode sampeyan, mung nggawe versi verbose kode kasebut (kanthi kelas batin anonim).

Elinga yen nalika nulis ekspresi lambda, kita ora mung ngilangi jeneng kelas , nanging uga jeneng metode kasebut.Comparator<String>int compare()

Kompilasi ora bakal duwe masalah kanggo nemtokake cara , amarga ekspresi lambda mung bisa ditulis kanggo antarmuka sing duwe metode siji . Miturut cara, ana cara kanggo ngubengi aturan iki, nanging sampeyan bakal sinau babagan nalika sampeyan miwiti sinau OOP kanthi luwih jero (kita ngomong babagan metode standar).

Ayo ndeleng maneh versi verbose kode kasebut, nanging kita bakal ngilangi bagean sing bisa diilangi nalika nulis ekspresi lambda:

Comparator<String> comparator = new Comparator<String>()
{
    public int compare (String obj1, String obj2)
   {
      return obj1.length() – obj2.length();
   }
};
Kelas batin anonim

Kayane ora ana sing penting diilangi. Pancen, yen Comparatorantarmuka mung duwe siji compare()cara, compiler bisa mbalekake kabeh kode werna abu-abu saka kode sing isih ana.

Ngurutake

Miturut cara, saiki kita bisa nulis kode sorting kaya iki:

Comparator<String> comparator = (String obj1, String obj2) ->
{
   return obj1.length() – obj2.length();
};
Collections.sort(list, comparator);

Utawa malah kaya iki:

Collections.sort(list, (String obj1, String obj2) ->
   {
      return obj1.length() – obj2.length();
   }
);

Kita mung langsung ngganti comparatorvariabel kanthi nilai sing ditugasake kanggo comparatorvariabel kasebut.

Ketik inferensi

Nanging ora mung kuwi. Kode ing conto iki bisa ditulis malah luwih kompak. Kaping pisanan, kompiler bisa nemtokake dhewe yen variabel obj1lan . Lan kapindho, kurung kriting lan statement bali uga bisa diilangi yen sampeyan mung duwe printah siji ing kode metode.obj2Strings

Versi cendhak bakal kaya iki:

Comparator<String> comparator = (obj1, obj2) ->
   obj1.length() – obj2.length();

Collections.sort(list, comparator);

Lan yen tinimbang nggunakake comparatorvariabel, kita langsung nggunakake nilai kasebut, mula kita entuk versi ing ngisor iki:

Collections.sort(list, (obj1, obj2) ->  obj1.length() — obj2.length() );

Nah, apa sing sampeyan pikirake? Mung siji baris kode tanpa informasi sing ora perlu - mung variabel lan kode. Ora ana cara kanggo nggawe luwih cendhek! Utawa ana?



5. Cara kerjane

Nyatane, kode kasebut bisa ditulis kanthi luwih kompak. Nanging luwih ing mengko.

Sampeyan bisa nulis ekspresi lambda ing ngendi sampeyan nggunakake jinis antarmuka kanthi cara siji.

Contone, ing kode , sampeyan bisa nulis ekspresi lambda amarga tandha cara kaya iki:Collections.sort(list, (obj1, obj2) -> obj1.length() - obj2.length());sort()

sort(Collection<T> colls, Comparator<T> comp)

Nalika kita ngliwati ArrayList<String>koleksi minangka argumen pisanan kanggo cara ngurutake, kompiler bisa nemtokake manawa jinis argumen kapindho yaiku . Lan saka iki, disimpulake yen antarmuka iki nduweni cara siji. Kabeh liyane iku teknis.Comparator<String>int compare(String obj1, String obj2)