JavaRush /Java Blog /Random-TK /Java-da lambda aňlatmalary hakda meşhur. Mysallar we mese...

Java-da lambda aňlatmalary hakda meşhur. Mysallar we meseleler bilen. 2-nji bölüm

Toparda çap edildi
Bu makala kim üçin?
  • Bu makalanyň birinji bölümini okanlar üçin ;

  • Java Core-ni eýýäm gowy bilýärler öýdýän, ýöne Java-da lambda aňlatmalary hakda pikirem ýoklar. Ora-da, belki, lambdalar hakda bir zat eşitdiňiz, ýöne jikme-jikliksiz.

  • lambda aňlatmalaryna belli bir derejede düşünýän, ýöne olary ulanmakdan gorkýan we adaty däl adamlar üçin.

Daşarky üýtgeýänlere giriş

Bu kod anonim synp bilen jemlenermi?
int counter = 0;
Runnable r = new Runnable() {
    @Override
    public void run() {
        counter++;
    }
};
No.ok. Üýtgeýji counterbolmaly final. Ora-da hökman däl final, ýöne islendik ýagdaýda-da bahasyny üýtgedip bilmez. Lambda aňlatmalarynda-da şol bir prinsip ulanylýar. Olara yglan edilen ýerinden "görünýän" ähli üýtgeýänlere girip bilerler. Emma lambda olary üýtgetmeli däldir (täze baha belläň). Dogry, anonim synplarda bu çäklendirmäni aýyrmak mümkinçiligi bar. Diňe salgylanma görnüşiniň üýtgeýjisini döretmek we obýektiň içki ýagdaýyny üýtgetmek ýeterlikdir. Bu ýagdaýda üýtgeýjiniň özi şol bir obýekti görkezer we bu ýagdaýda ony ygtybarly görkezip bilersiňiz final.
final AtomicInteger counter = new AtomicInteger(0);
Runnable r = new Runnable() {
    @Override
    public void run() {
        counter.incrementAndGet();
    }
};
Bu ýerde üýtgeýjimiz countergörnüşli bir obýekte salgylanma AtomicInteger. Bu obýektiň ýagdaýyny üýtgetmek üçin usul ulanylýar incrementAndGet(). Programma işleýän wagtynda üýtgeýjiniň bahasy üýtgemeýär we hemişe açar söz bilen üýtgeýjini yglan etmäge mümkinçilik berýän şol bir obýekti görkezýär final. Şol bir mysallar, ýöne lambda aňlatmalary bilen:
int counter = 0;
Runnable r = () -> counter++;
Anonim synp bilen opsiýa ýaly bir sebäbe görä jemlenmeýär: counterprogramma işleýän wagtynda üýtgemeli däl. Thisöne munuň ýaly - hemme zat gowy:
final AtomicInteger counter = new AtomicInteger(0);
Runnable r = () -> counter.incrementAndGet();
Bu çagyryş usullaryna hem degişlidir. “Lambda” aňlatmasynyň içinden diňe bir “görünýän” üýtgeýjilere girip bolman, elýeterli usullary hem atlandyryp bilersiňiz.
public class Main {
    public static void main(String[] args) {
        Runnable runnable = () -> staticMethod();
        new Thread(runnable).start();
    }

    private static void staticMethod() {
        System.out.println("Я - метод staticMethod(), и меня только-что кто-то вызвал!");
    }
}
Usul staticMethod()şahsy bolsa-da, usulyň içinde çagyrylmak “elýeterli” main(), şonuň üçin bu usulda döredilen lambdanyň içinden jaň edip bolýar main.

Lambda aňlatma kodunyň ýerine ýetirilen pursaty

Bu sorag size gaty ýönekeý bolup görünmegi mümkin, ýöne soramaga mynasyp: lambda aňlatmasynyň içindäki kod haçan ýerine ýetiriler? Creationaradylan pursatda? Ora-da haçan (nirededigi entek belli däl) jaň ediljek pursatda? Barlamak gaty aňsat.
System.out.println("Запуск программы");

// много всякого разного codeа
// ...

System.out.println("Перед объявлением лямбды");

Runnable runnable = () -> System.out.println("Я - лямбда!");

System.out.println("После объявления лямбды");

// много всякого другого codeа
// ...

System.out.println("Перед передачей лямбды в тред");
new Thread(runnable).start();
Ekranda çykyş:
Запуск программы
Перед объявлением лямбды
После объявления лямбды
Перед передачей лямбды в тред
Я - лямбда!
Lambda aňlatma kodunyň iň soňunda, sapak döredilenden we diňe programmanyň ýerine ýetiriş prosesi usulyň hakyky ýerine ýetirilişinde ýerine ýetirilendigini görmek bolýar run(). We yglan edilen wagty asla däl. Lambda aňlatmasyny yglan etmek bilen, diňe görnüşdäki bir obýekt döretdik Runnablewe onuň usulynyň özüni alyp barşyny beýan etdik run(). Usulyň özi has soň işe girizildi.

Usul salgylanmalary?

Lambdalaryň özleri bilen gönüden-göni baglanyşykly däl, ýöne bu makalada bu hakda birnäçe söz aýtmak mantykly bolar diýip pikir edýärin. Aýratyn bir zat etmeýän, diňe käbir usuly çagyrýan lambda aňlatmasy bar diýeliň.
x -> System.out.println(x)
Oňa bir zat berdiler х, ýöne oňa jaň edip System.out.println(), şol ýerden geçirdi х. Bu ýagdaýda, zerur usula baglanyşyk bilen çalşyp bileris. Şuňa meňzeş:
System.out::println
Hawa, ahyrynda gabyksyz! Has doly mysal:
List<String> strings = new LinkedList<>();
strings.add("Mother");
strings.add("soap");
strings.add("frame");

strings.forEach(x -> System.out.println(x));
forEach()Iň soňky setirde interfeýs obýektini kabul edýän usul ulanýarys Consumer. Bu ýene-de diňe bir usul bilen işleýän interfeýs void accept(T t). Şoňa laýyklykda bir parametr alýan lambda aňlatmasyny ýazýarys (interfeýsiň özünde ýazylandygy sebäpli, parametriň görnüşini görkezmeýäris, ýöne atlandyryljakdygyny görkezýäris х). Lambda aňlatmasynyň bedeninde kod ýazýarys usul çagyrylanda ýerine ýetiriler accept(). Bu ýerde diňe üýtgeýäniň bardygyny ekranda görkezýäris х. Usulyň özi forEach()kolleksiýanyň ähli elementlerinden geçýär, Consumerinterfeýs obýektiniň usulyny (lambda) çagyrýar accept(), kolleksiýadan her elementi nirede geçirýär. Öňem aýdyşym ýaly, bu lambda-ekspressiýa (diňe başga bir usuly çagyrmak), zerur usula salgylanma bilen çalşyp bileris. Soňra kodumyz şeýle bolar:
List<String> strings = new LinkedList<>();
strings.add("Mother");
strings.add("soap");
strings.add("frame");

strings.forEach(System.out::println);
Esasy zat, usullaryň kabul edilen parametrleri (println()we accept()). Usul println()islendik zady kabul edip bilýändigi sebäpli (lambda aňlatmasynyň ýerine hemme primitiwler we islendik obýektler üçin artykmaç ýüklenýär), forEach()diňe usula salgylanyp geçip bileris println(). Soňra forEach()kolleksiýanyň her elementini alar we gönüden-göni geçirer. Bu usul bilen println()ilkinji gezek ýüzbe-ýüz bolýanlar üçin usula jaň etmeýändigimize üns bermegiňizi haýyş edýäris System.out.println()(sözleriň arasyndaky nokatlar we ahyrynda ýaýlar bilen), gaýtam bu usulyň salgylanmasyny berýäris.
strings.forEach(System.out.println());
düzmekde ýalňyşlyk bolar. Sebäbi jaňdan öň forEach()Java çagyrylýandygyny görer System.out.println(), yzyna gaýtaryljakdygyna düşüner we muny şol ýerde garaşýan görnüş obýektine geçirmäge voidsynanyşar . voidforEach()Consumer

Usul salgylanmalaryny ulanmak üçin sintaksis

Bu gaty ýönekeý:
  1. Statik usula salgylanma bermekNameКласса:: NameСтатическогоМетода?

    public class Main {
        public static void main(String[] args) {
            List<String> strings = new LinkedList<>();
            strings.add("Mother");
            strings.add("soap");
            strings.add("frame");
    
            strings.forEach(Main::staticMethod);
        }
    
        private static void staticMethod(String s) {
            // do something
        }
    }
  2. Bar bolan obýekti ulanyp, statik däl usula salgylanma bermekNameПеременнойСОбъектом:: method name

    public class Main {
        public static void main(String[] args) {
            List<String> strings = new LinkedList<>();
            strings.add("Mother");
            strings.add("soap");
            strings.add("frame");
    
            Main instance = new Main();
            strings.forEach(instance::nonStaticMethod);
        }
    
        private void nonStaticMethod(String s) {
            // do something
        }
    }
  3. Şeýle usulyň amala aşyrylýan synpyny ulanyp, statik däl usula salgylanma berýärisNameКласса:: method name

    public class Main {
        public static void main(String[] args) {
            List<User> users = new LinkedList<>();
            users.add(new User("Vasya"));
            users.add(new User("Коля"));
            users.add(new User("Петя"));
    
            users.forEach(User::print);
        }
    
        private static class User {
            private String name;
    
            private User(String name) {
                this.name = name;
            }
    
            private void print() {
                System.out.println(name);
            }
        }
    }
  4. Konstruktora baglanyşyk NameКласса::new
    bermek Metod baglanyşyklaryny ulanmak, doly kanagatlanarly taýýar usul bar bolsa, ony yzyna çagyryş hökmünde ulanmak isleýärsiňiz. Bu ýagdaýda, şol usulyň kody bilen lambda aňlatmasyny ýa-da bu usul diýip atlandyrýan lambda aňlatmasyny ýazmagyň ýerine, diňe oňa salgylanma berýäris. Bu hemmesi.

Anonim synp bilen lambda aňlatmasynyň arasynda gyzykly tapawut

Anonim synpda açar söz thisşol näbelli synpyň obýektini görkezýär. Lambdanyň içinde ulansak this, çarçuwa synpynyň obýektine girip bileris. Aslynda bu aňlatmany ýazan ýerimiz. Bu bolýar, sebäbi lambda aňlatmalary düzülende, ýazylan synpyň şahsy usulyna öwrülýär. Bu "aýratynlygy" ulanmagy maslahat bermerin, sebäbi funksional programmirleme ýörelgelerine ters gelýän ters täsiri bar. Emma bu çemeleşme OOP bilen gaty gabat gelýär. ;)

Maglumatlary nireden aldym ýa-da başga näme okamaly

Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION