Rumah  >  Soal Jawab  >  teks badan

java - ini dalam kelas dalaman tanpa nama, bagaimana untuk masuk ke lambda?

nsv_productdetail.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int bottomMargin = ((ViewGroup.MarginLayoutParams) nsv_productdetail.getLayoutParams()).bottomMargin;
                nsv_productdetail.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });

Jika kod di atas ditukar kepada lambda, ini akan menghala ke kelas luaran dan pendengar tidak boleh dialih keluar pada masa ini.
Jadi saya ingin bertanya, bagaimanakah kelas dalaman tanpa nama (kelas dalaman tanpa nama yang boleh ditukar kepada lambda) boleh memperoleh dirinya dalam lambda?

阿神阿神2675 hari yang lalu1059

membalas semua(2)saya akan balas

  • PHP中文网

    PHP中文网2017-06-23 09:15:26

    Ganti beberapa kelas dalam tanpa nama
    Bahagian ini akan memperkenalkan cara menggunakan ungkapan Lambda untuk memudahkan penulisan kelas dalam tanpa nama Walau bagaimanapun, ekspresi Lambda tidak boleh menggantikan semua kelas dalam tanpa nama. Jangan risau tentang butirannya lagi, mari lihat beberapa contoh.

    Contoh 1: Singkatan fungsi tanpa parameter
    Jika anda perlu mencipta utas baharu, cara penulisan biasa adalah seperti ini:

    // kaedah penulisan kelas dalaman tanpa nama JDK7
    Thread baharu(new Runnable(){// nama antara muka

    @Override
    public void run(){// 方法名
        System.out.println("Thread run()");
    }

    }).start();
    Kod di atas menghantar objek Runnable tanpa nama ke kelas Tread dan melebihkan kaedah run() antara muka Runnable untuk melaksanakan logik yang sepadan. Ini adalah cara penulisan biasa dalam JDK7 dan sebelum ini. Kelas dalaman tanpa nama menjimatkan masalah untuk menamakan kelas, tetapi ia masih tidak cukup mudah dalam Java 8, ia boleh dipermudahkan kepada bentuk berikut:

    // Cara menulis ungkapan JDK8 Lambda
    Benang baharu(

        () -> System.out.println("Thread run()")// 省略接口名和方法名

    ).start();
    Kod di atas mempunyai fungsi yang sama seperti kelas dalam tanpa nama, tetapi ia lebih jauh daripada kelas dalam tanpa nama. Di sini nama sambungan dan nama fungsi ditinggalkan bersama-sama, menjadikannya lebih menyegarkan untuk menulis. Jika badan fungsi mempunyai beberapa baris, ia boleh disertakan dengan pendakap kerinting, seperti ini:

    // Cara menulis blok kod ungkapan Lambda JDK8
    Benang baharu(

        () -> {
            System.out.print("Hello");
            System.out.println(" Hoolee");
        }

    ).start();
    Contoh 2: Singkatan fungsi dengan parameter
    Jika anda ingin menghantar pembanding tersuai ke senarai rentetan dan mengisihnya mengikut panjang rentetan, bentuk penulisan Java 7 adalah seperti berikut:

    // Cara menulis kelas dalaman tanpa nama dalam JDK7
    List<String> list = Arrays.asList("I", "love", "you", "too");
    Collections.sort(list, new Comparator<String> ;() {//Nama antara muka

    @Override
    public int compare(String s1, String s2){// 方法名
        if(s1 == null)
            return -1;
        if(s2 == null)
            return 1;
        return s1.length()-s2.length();
    }

    });
    Kod di atas membebankan kaedah compare() antara muka Comparator melalui kelas dalam untuk melaksanakan logik perbandingan. Menggunakan ungkapan Lambda boleh dipendekkan seperti berikut:

    // Cara menulis ungkapan JDK8 Lambda
    List<String> list = Arrays.asList("I", "love", "you", "too");
    Collections.sort(list, (s1, s2) - > ;{// Abaikan jenis jadual parameter

    if(s1 == null)
        return -1;
    if(s2 == null)
        return 1;
    return s1.length()-s2.length();

    });
    Kod di atas mempunyai fungsi yang sama seperti kelas dalaman tanpa nama. Selain meninggalkan nama antara muka dan nama kaedah, jenis jadual parameter juga ditinggalkan dalam kod. Ini adalah disebabkan oleh mekanisme inferens jenis javac Pengkompil boleh membuat kesimpulan jenis parameter berdasarkan maklumat kontekstual. Ambil perhatian bahawa Java ialah bahasa yang ditaip kuat, dan setiap pembolehubah dan objek mesti mempunyai jenis yang jelas.

    Asas untuk singkatan
    Mungkin anda sudah fikir bahawa asas untuk menggunakan Lambda ialah mesti ada antara muka berfungsi yang sepadan (antara muka berfungsi merujuk kepada antara muka dengan hanya satu kaedah abstrak di dalamnya). Ini konsisten dengan Java sebagai bahasa yang ditaip kuat, yang bermaksud bahawa anda tidak boleh menulis ungkapan Lambda sewenang-wenangnya di mana-mana dalam kod. Sebenarnya, jenis Lambda ialah jenis yang sepadan dengan antara muka fungsi. Asas lain untuk ungkapan lambda ialah mekanisme inferens jenis Jika maklumat konteks mencukupi, pengkompil boleh membuat kesimpulan jenis jadual parameter tanpa menamakannya secara eksplisit. Lambda menyatakan lebih banyak bentuk bertulis undang-undang seperti berikut:

    // Bentuk tulisan Lambda
    Larian boleh dijalankan = () -> System.out.println("Hello World");// 1
    ActionListener listener = event -> System.out.println("button clicked " );// 2
    Barisan berbilang boleh dijalankan = () -> {// 3 blok kod

    System.out.print("Hello");
    System.out.println(" Hoolee");

    };
    BinaryOperator<Long> tambah = (Panjang x, Long y) -> menunjukkan singkatan bagi fungsi tanpa parameter;

    Antara muka fungsi tersuai

    Antara muka fungsi tersuai adalah mudah, anda hanya perlu menulis antara muka dengan hanya satu kaedah abstrak.


    // Antara muka fungsi tersuai

    @FunctionalInterface

    antara muka awam ConsumerInterface<T>{

    void accept(T t);

    }

    @FunctionalInterface dalam kod di atas adalah pilihan, tetapi menambahkan anotasi ini pengkompil akan membantu anda menyemak sama ada antara muka mematuhi spesifikasi antara muka berfungsi. Sama seperti menambah anotasi @Override akan menyemak sama ada fungsi tersebut terlebih beban.


    Dengan definisi antara muka di atas, anda boleh menulis kod yang serupa dengan yang berikut:

    ConsumerInterface<String> pengguna = str -> System.out.println(str);

    Seterusnya, anda juga boleh menggunakannya seperti ini:

    kelas MyStream<T>{

    private List<T> list;
    ...
    public void myForEach(ConsumerInterface<T> consumer){// 1
        for(T t : list){
            consumer.accept(t);
        }
    }

    }

    MyStream<String> strim = MyStream<String>();

    stream.myForEach(str -> System.out.println(str));// Gunakan antara muka fungsi tersuai untuk menulis ungkapan Lambda

    balas
    0
  • 女神的闺蜜爱上我

    女神的闺蜜爱上我2017-06-23 09:15:26

    Apa yang tidak boleh dilakukan ialah Lambda itu sendiri bukan objek.

    balas
    0
  • Batalbalas