JavaRush /Blog Jawa /Random-JV /Populer babagan ekspresi lambda ing basa Jawa. Kanthi con...

Populer babagan ekspresi lambda ing basa Jawa. Kanthi conto lan tugas. Bagean 1

Diterbitake ing grup
Artikel iki kanggo sapa?
  • Kanggo sing mikir wis ngerti Java Core, nanging ora ngerti babagan ekspresi lambda ing basa Jawa. Utawa, mbok menawa, sampeyan wis krungu bab lambdas, nanging tanpa rincian.
  • kanggo sing duwe sawetara pangerten saka lambda expression, nanging isih wedi lan mboten umum kanggo nggunakake.
Yen sampeyan ora kalebu ing salah sawijining kategori kasebut, sampeyan bisa uga nemokake artikel iki mboseni, salah, lan umume "ora keren." Ing kasus iki, aja ragu-ragu kanggo ngliwati, utawa, yen sampeyan wis ngerti babagan topik kasebut, saranake ing komentar babagan carane bisa nambah utawa nambah artikel kasebut. Materi kasebut ora ngaku nilai akademik, luwih-luwih anyar. Luwih, ing nalisir: ing aku bakal nyoba kanggo njlèntrèhaké Komplek (kanggo sawetara) bab sabisa. Aku iki inspirasi kanggo nulis dening panjalukan kanggo nerangake stream api. Aku mikir babagan iki lan mutusake yen tanpa mangerteni ekspresi lambda, sawetara conto babagan "aliran" ora bisa dingerteni. Dadi ayo miwiti karo lambdas. Populer babagan ekspresi lambda ing basa Jawa.  Kanthi conto lan tugas.  Bagean 1 - 1Apa kawruh sing dibutuhake kanggo ngerti artikel iki:
  1. Pangertosan babagan pemrograman berorientasi objek (sateruse diarani OOP), yaiku:
    • kawruh babagan kelas lan obyek apa, apa bedane;
    • kawruh apa antarmuka, carane padha beda-beda saka kelas, apa sambungan antarane wong-wong mau (antarmuka lan kelas);
    • kawruh babagan apa metode, carane nyebataken, apa cara abstrak (utawa metode tanpa implementasine), apa paramèter / argumentasi saka metode, carane pass ing kono;
    • akses modifiers, cara statis / variabel, cara final / variabel;
    • warisan (kelas, antarmuka, macem-macem warisan antarmuka).
  2. Kawruh Jawa Inti: generik, koleksi (dhaptar), utas.
Inggih, ayo miwiti.

Sajarah sethitik

Ekspresi Lambda teka ing Jawa saka pemrograman fungsional, lan saka matématika. Ing tengah abad kaping 20 ing Amerika, Gréja Alonzo tartamtu makarya ing Universitas Princeton, sing seneng banget karo matématika lan kabeh jinis abstraksi. Iku Gréja Alonzo sing teka munggah karo kalkulus lambda, kang ing kawitan pesawat saka sawetara gagasan abstrak lan ora ana hubungane karo program. Ing wektu sing padha, matématikawan kayata Alan Turing lan John von Neumann makarya ing Universitas Princeton sing padha. Kabeh teka bebarengan: Church nggawe sistem kalkulus lambda, Turing ngembangake mesin komputasi abstrak, sing saiki dikenal minangka "mesin Turing." Inggih, von Neumann ngajokaken diagram arsitèktur komputer, ingkang dados dhasar komputer modern (lan sapunika dipunsebat "arsitektur von Neumann"). Ing wektu iku, gagasan Gréja Alonzo ora entuk misuwur minangka karya kanca-kancane (kajaba ing bidang matematika "murni"). Nanging, sethitik mengko, John McCarthy tartamtu (uga lulusan saka Universitas Princeton, ing wektu crita - pegawe saka Massachusetts Institute of Technology) dadi kasengsem ing gagasan Gréja. Adhedhasar kasebut, ing taun 1958 dheweke nggawe basa pemrograman fungsional pisanan, Lisp. Lan 58 taun sabanjure, ide-ide pemrograman fungsional bocor ing Jawa minangka nomer 8. Ora nganti 70 taun kepungkur ... Nyatane, iki dudu wektu sing paling suwe kanggo ngetrapake ide matematika ing praktik.

Intine

Ekspresi lambda minangka fungsi kasebut. Sampeyan bisa mikir iki minangka cara biasa ing Jawa, mung prabédan iku bisa liwati kanggo cara liyane minangka bantahan. Ya, wis dadi bisa kanggo pass ora mung nomer, strings lan kucing kanggo cara, nanging uga cara liyane! Kapan kita butuh iki? Contone, yen kita pengin pass sawetara callback. We kudu cara kita nelpon kanggo bisa nelpon sawetara cara liyane sing kita pass menyang. Sing, supaya kita duwe kesempatan kanggo ngirim siji callback ing sawetara kasus, lan liyane ing liyane. Lan cara kita, sing bakal nampa callback kita, bakal nelpon. Conto prasaja yaiku ngurutake. Ayo kita nulis sawetara jinis ngurutake angel sing katon kaya iki:
public void mySuperSort() {
    // ... do something here
    if(compare(obj1, obj2) > 0)
    // ... and here we do something
}
Where, ifkita nelpon cara compare(), pass ana rong obyek sing kita mbandhingaké, lan kita arep kanggo mangerteni kang obyek iki "luwih gedhe". Kita bakal sijine sing "luwih" sadurunge sing "luwih cilik". Aku nulis "luwih" ing kuotasi amarga kita nulis cara universal sing bakal bisa ngurutake ora mung ing munggah nanging uga ing urutan mudhun (ing kasus iki, "luwih" bakal obyek sing ateges luwih cilik, lan kosok balene) . Kanggo nyetel aturan kanggo persis carane kita arep kanggo Ngurutake, kita kudu piye wae pass menyang kita mySuperSort(). Ing kasus iki, kita bakal bisa "kontrol" cara kita nalika diarani. Mesthi, sampeyan bisa nulis rong cara sing kapisah mySuperSortAsc()kanggo mySuperSortDesc()ngurutake kanthi urutan munggah lan mudhun. Utawa pass sawetara parameter nang cara (contone, booleanyen true, Urut ing urutan munggah, lan yen falseing mudhun urutan). Nanging apa yen kita pengin ngurutake ora sawetara struktur prasaja, nanging, contone, dhaptar array senar? Kepiye cara kita mySuperSort()ngerti carane ngurutake array senar kasebut? Kanggo ukuran? Miturut total dawa tembung? Mbok miturut abjad, gumantung ing baris pisanan ing array? Nanging yen ing sawetara kasus, kita kudu ngurutake dhaptar array kanthi ukuran array, lan ing kasus liyane, kanthi total dawa tembung ing array? Aku mikir sampeyan wis krungu babagan komparator lan ing kasus kaya mengkono, kita mung ngirim obyek komparator menyang cara ngurutake kita, ing ngendi kita nerangake aturan sing arep diurutake. Wiwit cara standar sort()diimplementasikake kanthi prinsip sing padha, mySuperSort()ing conto aku bakal nggunakake sing standar sort().
String[] array1 = {"Mother", "soap", "frame"};
String[] array2 = {"I", "Very", "I love", "java"};
String[] array3 = {"world", "work", "May"};

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[]> sortByWordsLength = 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);
asil:
  1. ibu ngumbah pigura
  2. tentrem Buruh bisa
  3. Aku pancen tresna marang jawa
Ing kene, larik diurutake miturut jumlah tembung ing saben larik. Larik kanthi tembung luwih sithik dianggep "cilik". Mulane teka ing wiwitan. Sing ana tembung liyane dianggep "luwih" lan rampung ing pungkasan. Yen sort()kita ngliwati komparator liyane menyang metode (sortByWordsLength), mula asile bakal beda:
  1. tentrem Buruh bisa
  2. ibu ngumbah pigura
  3. Aku pancen tresna marang jawa
Saiki array diurutake miturut jumlah total huruf ing tembung array kasebut. Ing kasus pisanan ana 10 aksara, ing kaloro 12, lan ing katelu 15. Yen kita nggunakake mung siji komparator, banjur kita ora bisa nggawe variabel kapisah kanggo iku, nanging mung nggawe obyek saka kelas anonim tengen ing wektu nelpon cara sort(). Koyo kui:
String[] array1 = {"Mother", "soap", "frame"};
String[] array2 = {"I", "Very", "I love", "java"};
String[] array3 = {"world", "work", "May"};

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;
    }
});
Asil bakal padha karo ing kasus pisanan. Tugas 1 . Tulis maneh conto iki supaya ngurutake larik ora ing urutan munggah saka jumlah tembung ing larik, nanging ing urutan mudhun. Kita wis ngerti kabeh iki. Kita ngerti carane ngirim obyek menyang metode, kita bisa ngliwati obyek iki utawa obyek kasebut menyang metode gumantung saka apa sing kita butuhake saiki, lan ing jero metode sing kita ngliwati obyek kasebut, metode sing kita tulis implementasine bakal diarani. . Pitakonan muncul: apa hubungane karo ekspresi lambda? Amarga lambda minangka obyek sing ngemot siji metode. Iku kaya obyek metode. Cara sing dibungkus ing obyek. Dheweke mung duwe sintaks sing rada ora biasa (nanging luwih akeh mengko). Ayo dipikir maneh ing entri iki
arrays.sort(new Comparator<String[]>() {
    @Override
    public int compare(String[] o1, String[] o2) {
        return o1.length - o2.length;
    }
});
Kene kita njupuk dhaftar kita arrayslan nelpon cara sort(), ngendi kita pass obyek comparator karo siji cara compare()(ora Matter kanggo kita apa iku disebut, amarga iku mung siji ing obyek iki, kita ora bakal kantun). Cara iki njupuk rong paramèter, sing bakal ditindakake sabanjure. Yen sampeyan kerja ing IntelliJ IDEA , sampeyan bisa uga wis weruh carane menehi kode iki kanggo nyepetake kanthi signifikan:
arrays.sort((o1, o2) -> o1.length - o2.length);
Mangkono carane enem baris dadi siji cendhak. 6 baris ditulis maneh dadi siji cekak. Soko wis ilang, nanging aku njamin sing ora penting ilang, lan kode iki bakal bisa persis padha karo kelas anonim. Tugas 2 . Tokoh carane nulis ulang solusi kanggo masalah 1 nggunakake lambdas (minangka Resor pungkasan, takon IntelliJ IDEA kanggo ngowahi kelas anonim menyang lambda).

Ayo dadi pirembagan bab antarmuka

Sejatine, antarmuka mung minangka dhaptar metode abstrak. Nalika kita nggawe kelas lan ngomong sing bakal ngleksanakake sawetara jenis antarmuka, kita kudu nulis ing kelas kita implementasine saka cara sing kadhaptar ing antarmuka (utawa, minangka Resor pungkasan, ora nulis, nanging nggawe kelas abstrak. ). Ana antarmuka karo macem-macem cara (contone List), ana antarmuka karo mung siji cara (contone, Comparator padha utawa Runnable). Ana antarmuka tanpa cara siji (sing diarani antarmuka panandha, contone Serializable). Antarmuka sing mung nduweni siji cara uga diarani antarmuka fungsional . Ing Jawa 8 malah ditandhani karo anotasi @FunctionalInterface khusus . Iki minangka antarmuka karo siji cara sing cocog kanggo nggunakake ekspresi lambda. Kaya sing dakkandhakake ing ndhuwur, ekspresi lambda minangka cara sing dibungkus ing obyek. Lan nalika kita ngliwati obyek kasebut ing endi wae, kita, nyatane, ngliwati metode siji iki. Pranyata ora masalah kanggo kita apa cara iki diarani. Kabeh sing penting kanggo kita yaiku paramèter sing ditindakake metode iki, lan, nyatane, kode metode kasebut dhewe. Ekspresi lambda, sejatine. implementasi antarmuka fungsional. Ing ngendi kita ndeleng antarmuka kanthi siji cara, tegese kita bisa nulis ulang kelas anonim kasebut kanthi nggunakake lambda. Yen antarmuka wis luwih / kurang saka siji cara, banjur expression lambda ora cocog karo kita, lan kita bakal nggunakake kelas anonim, utawa malah biasa. Iku wektu kanggo dig menyang lambdas. :)

Sintaksis

Sintaks umum kaya iki:
(параметры) -> {тело метода}
Yaiku, kurung, ing njero ana paramèter metode, "panah" (iki rong karakter berturut-turut: minus lan luwih gedhe), sawise awak metode kasebut ana ing kurung kriting, kaya biasane. Parameter kasebut cocog karo sing ditemtokake ing antarmuka nalika nerangake metode kasebut. Yen jinis variabel bisa ditetepake kanthi jelas dening kompiler (ing kasus kita, kita ngerti manawa kita nggarap array strings, amarga diketik Listkanthi tepat dening array strings), mula jinis variabel kasebut String[]ora perlu. ditulis.
Yen sampeyan ora yakin, nemtokake jinis, lan IDEA bakal nyorot werna abu-abu yen ora perlu.
Sampeyan bisa maca liyane ing tutorial Oracle , contone. Iki diarani "target typing" . Sampeyan bisa menehi jeneng kanggo variabel, ora kudu sing kasebut ing antarmuka. Yen ora ana paramèter, banjur mung kurung. Yen mung ana siji parameter, mung jeneng variabel tanpa tanda kurung. Kita wis ngurutake paramèter, saiki babagan awak ekspresi lambda dhewe. Ing njero kurung kriting, tulis kode kaya cara biasa. Yen kabeh kode mung dumadi saka siji baris, sampeyan ora kudu nulis kurung kriting kabeh (kaya karo ifs lan loops). Yen lambda sampeyan bali soko, nanging awak kasusun saka siji baris, iku returnora perlu kanggo nulis. Nanging yen sampeyan duwe kurung kriting, banjur, kaya ing cara biasanipun, sampeyan kudu tegas nulis return.

Tuladha

Tuladha 1.
() -> {}
Pilihan sing paling gampang. Lan sing paling ora ana gunane :) Amarga ora ana apa-apa. Tuladha 2.
() -> ""
Uga pilihan sing menarik. Ora nampa apa-apa lan ngasilake senar kosong ( returndiilangi minangka ora perlu). Padha, nanging karo return:
() -> {
    return "";
}
Tuladha 3. Hello donya nggunakake lambdas
() -> System.out.println("Hello world!")
Nampa apa-apa, bali apa-apa (kita ora bisa sijine returnsadurunge telpon System.out.println(), wiwit jinis bali ing cara println() — void), mung nampilake prasasti ing layar. Becik kanggo ngleksanakake antarmuka Runnable. Conto padha luwih lengkap:
public class Main {
    public static void main(String[] args) {
        new Thread(() -> System.out.println("Hello world!")).start();
    }
}
Utawa kaya iki:
public class Main {
    public static void main(String[] args) {
        Thread t = new Thread(() -> System.out.println("Hello world!"));
        t.start();
    }
}
Utawa kita malah bisa nyimpen ekspresi lambda minangka obyek saka jinis Runnable, banjur pass menyang konstruktor thread’а:
public class Main {
    public static void main(String[] args) {
        Runnable runnable = () -> System.out.println("Hello world!");
        Thread t = new Thread(runnable);
        t.start();
    }
}
Ayo goleki kanthi luwih rinci babagan wektu nyimpen ekspresi lambda dadi variabel. Antarmuka Runnablengandhani yen obyek kasebut kudu duwe metode public void run(). Miturut antarmuka, cara roto ora nampa apa-apa minangka paramèter. Lan ora ngasilake apa-apa (void). Mulane, nalika nulis kanthi cara iki, obyek bakal digawe kanthi sawetara cara sing ora nampa utawa ngasilake apa-apa. Kang cukup konsisten karo cara run()ing antarmuka Runnable. Pramila kita bisa nyelehake ekspresi lambda iki dadi variabel kaya Runnable. Tuladha 4
() -> 42
Maneh, ora nampa apa-apa, nanging ngasilake nomer 42. Ekspresi lambda iki bisa diselehake ing variabel jinis Callable, amarga antarmuka iki mung nemtokake siji cara, sing katon kaya iki:
V call(),
endi Vjinis nilai bali (ing kasus kita int). Dadi, kita bisa nyimpen ekspresi lambda kaya ing ngisor iki:
Callable<Integer> c = () -> 42;
Conto 5. Lambda ing sawetara baris
() -> {
    String[] helloWorld = {"Hello", "world!"};
    System.out.println(helloWorld[0]);
    System.out.println(helloWorld[1]);
}
Maneh, iki ekspresi lambda tanpa paramèter lan jinis bali void(amarga ora ana return). Tuladha 6
x -> x
Kene kita njupuk soko menyang variabel хlan bali. Elinga yen mung siji parameter sing ditampa, tanda kurung ing sakubenge ora perlu ditulis. Padha, nanging nganggo kurung:
(x) -> x
Lan iki pilihan kanthi eksplisit return:
x -> {
    return x;
}
Utawa kaya iki, kanthi kurung lan return:
(x) -> {
    return x;
}
Utawa kanthi indikasi eksplisit saka jinis kasebut (lan, kanthi kurung):
(int x) -> x
Tuladha 7
x -> ++x
Kita nampa хlan bali, nanging 1luwih. Sampeyan uga bisa nulis maneh kaya iki:
x -> x + 1
Ing kasus loro, kita ora nuduhake kurung watara parameter, awak metode, lan tembung return, amarga iki ora perlu. Pilihan kanthi tanda kurung lan bali diterangake ing conto 6. Tuladha 8
(x, y) -> x % y
We nampa sawetara хlan у, bali seko divisi xdening y. Kurung watara paramèter wis dibutuhake ing kene. Padha opsional mung yen ana mung siji parameter. Kaya iki kanthi indikasi eksplisit saka jinis:
(double x, int y) -> x % y
Tuladha 9
(Cat cat, String name, int age) -> {
    cat.setName(name);
    cat.setAge(age);
}
Kita nampa obyek Cat, senar karo jeneng lan umur integer. Ing cara dhewe, kita nyetel jeneng liwati lan umur kanggo Kucing. Amarga variabel catkita minangka jinis referensi, obyek Kucing ing njaba ekspresi lambda bakal diganti (bakal nampa jeneng lan umur sing dilewati ing njero). Versi sing rada rumit sing nggunakake lambda sing padha:
public class Main {
    public static void main(String[] args) {
        // create a cat and print to the screen to make sure it's "blank"
        Cat myCat = new Cat();
        System.out.println(myCat);

        // create lambda
        Settable<Cat> s = (obj, name, age) -> {
            obj.setName(name);
            obj.setAge(age);
        };

        // call the method, to which we pass the cat and the lambda
        changeEntity(myCat, s);
        // display on the screen and see that the state of the cat has changed (has a name and age)
        System.out.println(myCat);
    }

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

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

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

class Cat implements WithNameAndAge {
    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 +
                '}';
    }
}
Asil: Cat{name='null', age=0} Cat{name='Murzik', age=3} Nalika sampeyan bisa ndeleng, ing wiwitan obyek Cat duwe siji negara, nanging sawise nggunakake ekspresi lambda, negara diganti. . Ekspresi Lambda bisa digunakake kanthi apik karo generik. Lan yen kita kudu nggawe kelas Dog, contone, sing uga bakal ngleksanakake WithNameAndAge, banjur ing cara main()kita bisa nindakake operasi padha karo Dog, tanpa ngganti expression lambda dhewe ing kabeh. Tugas 3 . Tulis antarmuka fungsional kanthi cara sing njupuk nomer lan ngasilake nilai Boolean. Tulis implementasine antarmuka kasebut ing wangun ekspresi lambda sing bakal bali trueyen nomer liwati bisa dibagi 13 tanpa sisa.Tugas 4 . Tulis antarmuka fungsional kanthi cara sing njupuk rong senar lan ngasilake senar sing padha. Tulis implementasi antarmuka kasebut ing wangun lambda sing ngasilake senar paling dawa. Tugas 5 . Nulis antarmuka fungsional kanthi cara sing nampa telung nomer pecahan: a, b, clan ngasilake nomer pecahan sing padha. Tulis implementasi antarmuka kasebut ing wangun ekspresi lambda sing ngasilake diskriminan. Sapa sing lali, D = b^2 - 4ac . Tugas 6 . Nggunakake antarmuka fungsional saka tugas 5, nulis ekspresi lambda sing ngasilake asil operasi a * b^c. Populer babagan ekspresi lambda ing basa Jawa. Kanthi conto lan tugas. Bagean 2.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION