Predikat Java 8 bawaan yang selalu mengembalikan true?

129

Google Guava memiliki predikat yang selalu kembalitrue . Apakah Java 8 memiliki sesuatu yang serupa Predicate? Saya tahu saya bisa menggunakan (foo)->{return true;}, tetapi saya ingin sesuatu yang sudah dibuat sebelumnya, analog dengan Collections.emptySet().

Garret Wilson
sumber

Jawaban:

162

Tidak ada predikat bawaan selalu benar dan selalu salah di Jawa 8. Cara paling ringkas untuk menulis ini adalah

x -> true

dan

x -> false

Bandingkan ini dengan

Predicates.alwaysTrue() // Guava

dan akhirnya ke kelas batin anonim:

new Predicate<Object>() {
    public boolean test(Object x) {
        return true;
    }
}

Mungkin alasan bahwa Guava memiliki predikat bawaan ini adalah bahwa ada keuntungan sintaksis yang sangat besar dari pemanggilan metode statis melalui kelas dalam anonim. Di Java 8, sintaks lambda begitu ringkas sehingga ada kerugian sintaksis untuk menuliskan pemanggilan metode statis.

Itu hanya perbandingan sintaksis. Mungkin ada keuntungan ruang kecil jika ada satu predikat global selalu-benar tunggal, dibandingkan dengan x -> truekejadian yang tersebar di beberapa kelas, masing-masing akan menciptakan contoh predikat sendiri. Apakah ini yang Anda khawatirkan? Penghematan tampaknya tidak menarik, yang mungkin mengapa mereka tidak ditambahkan pada awalnya. Tapi itu bisa dipertimbangkan untuk rilis di masa depan.

UPDATE 2015-04-24

Kami telah dianggap penambahan berbagai statis, bernama fungsi seperti Predicate.alwaysTrue, Runnable.noop, dll, dan kami telah memutuskan untuk tidak menambah lagi di masa depan versi Java SE.

Tentu saja ada beberapa nilai dalam sesuatu yang memiliki nama vs lambda yang ditulis, tetapi nilai ini cukup kecil. Kami berharap orang akan belajar membaca dan menulis x -> truedan () -> { }penggunaannya akan menjadi idiomatis. Bahkan nilai Function.identity()lebih x -> xdipertanyakan.

Ada keuntungan kinerja yang sangat kecil untuk menggunakan kembali fungsi yang sudah ada alih-alih mengevaluasi lambda yang sudah dihapus, tetapi kami berharap penggunaan fungsi-fungsi semacam ini sangat kecil sehingga keuntungan seperti itu dapat diabaikan, tentu saja tidak sebanding dengan mengasapi API.

Holger juga menyebutkan dalam komentar kemungkinan mengoptimalkan fungsi-fungsi tersusun seperti Predicate.ordan semacamnya. Ini juga dipertimbangkan ( JDK-8067971 ) tetapi dianggap agak rapuh dan rawan kesalahan, dan jarang terjadi sehingga tidak layak untuk diimplementasikan.

Lihat juga entri FAQ Lambda ini .

Stuart Marks
sumber
14
Dua masalah: Yang pertama adalah singkatnya. Jika (foo)->{return true;}yang terbaik yang bisa saya lakukan, saya ingin yang lebih baik. Tapi Anda mengemukakannya x->true, yang jauh lebih baik dan mengurangi masalah pertama. Masalah kedua adalah deklarasi logika vs statis. Jika saya menggunakan x->true, masih ada logika yang terlibat, yang saya dapat secara tidak sengaja mengacaukan (misalnya x->!true). Tetapi dengan Predicate.alwaysTrue(), tidak ada ruang untuk kesalahan logika, karena hanya ada satu atau dua metode serupa. Ditambah lagi, saya mendapatkan penyelesaian kode IDE secara gratis. x->truehampir baik-baik saja, tetapi saya masih menulis Predicate.alwaysTrue()metode untuk alasan di atas.
Garret Wilson
10
@ GarretWilson Tetapi dengan Predicate.alwaysTrue()Anda juga bisa mengacaukan dengan menulis secara tidak sengaja Predicate.alwaysFalse().
David Conrad
5
@ Davidvidon, tentu saja. Selalu ada cara saya bisa membuat kesalahan, dan sebenarnya saya terus-menerus menemukan yang baru. ;) Saya tidak ingin memulai argumen di sini tentang sesuatu yang sepele, tetapi saya hanya akan mengatakan bahwa maksud saya adalah bahwa dengan referensi metode statis saya memiliki kosakata terbatas dengan hanya dua pilihan: alwaysTrue()dan alwaysFalse(). Dengan lambda yang sebenarnya, saya memiliki banyak variasi; Saya pada dasarnya merekonstruksi formula setiap kali. Intinya, alwaysTrue()adalah label semantik untuk apa yang ingin saya lakukan; x->truesebenarnya melakukannya lagi setiap kali. Bukan besar, tapi pertimbangan.
Garret Wilson
25
Salah satu keuntungan besar dari kanonik Predicate.alwaysTrue()dan Predicate.alwaysFalse()contoh adalah, bahwa mereka dapat diakui dengan menggabungkan metode seperti Predicate.or, Predicate.and, dan Predicate.negate(). Ini akan memungkinkan untuk melakukan inisialisasi Predicatevariabel dengan alwaysTrue()dan menambahkan predikat dengan menggabungkan via andtanpa overhead. Karena ekspresi lambda tidak memiliki jaminan identitas objek, ini mungkin gagal x->true. By the way, jika saya memiliki kelas Xdengan staticmetode y(){return true;}, menggunakan X::ybahkan lebih pendek daripada x->truetetapi tidak benar-benar direkomendasikan ...
Holger
10
Ungkapan ini x -> truememiliki kelemahan yaitu saya harus menggunakan variabel tanpa menggunakan. Ini menciptakan beban otak yang tidak perlu dan juga peringatan di IDE saya. Saya mencoba menggunakan _ -> true, tetapi itu adalah kesalahan sintaksis. Java jelas kehilangan kata kunci (baca: keyletter) untuk "parameter yang tidak digunakan". Berharap sesuatu seperti ini akan datang di Jawa 9 (atau setidaknya: Jawa apa pun sebelum aku mati ^^)
kap
4

Tanpa jambu biji

Boolean.TRUE::booleanValue
boriselec
sumber
3
Itu menarik. Saya tidak yakin apakah itu benar-benar menangkap semangat permintaan, tetapi mendapat poin untuk kreativitas!
Garret Wilson
21
Tapi itu bukan Predicate, karena tidak butuh argumen.
Florent Guillaume
1
Ini bukan predikat, ini adalah referensi metode tetapi memiliki kelebihan karena ringkas dan tidak memaksa untuk menyebutkan parameter yang tidak digunakan. +1 Ngomong-ngomong, karena menghindari untuk menggunakan Guava yang memiliki masalah serius modularitas, layak mendapatkan upvote saya;)
gouessej
16
Referensi metode Anda dapat dialihkan ke Pemasok <Boolean> tetapi tidak Predikat <T>
Daniel K.