Google ฝรั่งมีกริยาที่ผลตอบแทนเสมอ true
Java 8 มีบางอย่างที่คล้ายกันPredicate
หรือไม่? ฉันรู้ว่าฉันสามารถใช้แต่ฉันต้องการบางสิ่งบางอย่างที่ทำไว้ล่วงหน้าเพื่อที่คล้ายคลึงกัน(foo)->{return true;}
Collections.emptySet()
Google ฝรั่งมีกริยาที่ผลตอบแทนเสมอ true
Java 8 มีบางอย่างที่คล้ายกันPredicate
หรือไม่? ฉันรู้ว่าฉันสามารถใช้แต่ฉันต้องการบางสิ่งบางอย่างที่ทำไว้ล่วงหน้าเพื่อที่คล้ายคลึงกัน(foo)->{return true;}
Collections.emptySet()
คำตอบ:
ไม่มีเพรดิเคตในตัวเสมอจริงและเสมอ - เท็จใน Java 8 วิธีที่กระชับที่สุดในการเขียนสิ่งเหล่านี้คือ
x -> true
และ
x -> false
เปรียบเทียบสิ่งเหล่านี้กับ
Predicates.alwaysTrue() // Guava
และในที่สุดก็เป็นคลาสภายในที่ไม่ระบุชื่อ:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
อาจเป็นเหตุผลที่ Guava มีเพรดิเคตในตัวเหล่านี้คือมีข้อได้เปรียบทางวากยสัมพันธ์อย่างมากของการเรียกเมธอดแบบคงที่ในคลาสภายในที่ไม่ระบุตัวตน ใน Java 8 ไวยากรณ์แลมบ์ดามีความกระชับมากจนมีข้อเสียทางวากยสัมพันธ์ในการเขียนการเรียกเมธอดแบบคงที่
นั่นเป็นเพียงการเปรียบเทียบทางวากยสัมพันธ์เท่านั้น อาจมีข้อได้เปรียบด้านพื้นที่เล็กน้อยหากมีเพรดิเคตทั่วโลกที่เป็นจริงเสมอเมื่อเทียบกับx -> true
เหตุการณ์ที่เกิดขึ้นในหลายชั้นเรียนซึ่งแต่ละรายการจะสร้างอินสแตนซ์เพรดิเคตของตัวเอง นี่คือสิ่งที่คุณกังวลหรือไม่? การประหยัดดูไม่น่าสนใจซึ่งอาจเป็นสาเหตุที่ไม่ได้เพิ่มเข้ามาในตอนแรก แต่อาจได้รับการพิจารณาใหม่สำหรับการเปิดตัวในอนาคต
อัพเดท 2015-04-24
เราได้พิจารณานอกเหนือจากความหลากหลายของแบบคงที่ฟังก์ชั่นเช่นชื่อPredicate.alwaysTrue
, Runnable.noop
ฯลฯ และเราได้ตัดสินใจที่จะไม่เพิ่มใด ๆ เพิ่มเติมในรุ่นอนาคตของ Java SE
แน่นอนว่ามีค่าบางอย่างในบางสิ่งที่มีชื่อเทียบกับแลมบ์ดาที่เขียนออกมา แต่ค่านี้ค่อนข้างน้อย เราคาดหวังว่าผู้คนจะเรียนรู้วิธีการอ่านและเขียนx -> true
และ() -> { }
การใช้งานของพวกเขาจะกลายเป็นสำนวน แม้แต่มูลค่าFunction.identity()
เกินx -> x
ก็ยังน่าสงสัย
มีข้อได้เปรียบด้านประสิทธิภาพเล็กน้อยในการนำฟังก์ชันที่มีอยู่กลับมาใช้ใหม่แทนที่จะประเมินแลมบ์ดาที่เป็นลายลักษณ์อักษร แต่เราคาดว่าการใช้งานฟังก์ชันประเภทนี้จะมีขนาดเล็กมากจนข้อได้เปรียบดังกล่าวเล็กน้อยไม่คุ้มกับการขยายตัวของ API
Holger ยังกล่าวถึงในความคิดเห็นถึงความเป็นไปได้ในการปรับแต่งฟังก์ชันประกอบเช่นPredicate.or
และอื่น ๆ สิ่งนี้ได้รับการพิจารณาเช่นกัน ( JDK-8067971 ) แต่ถือว่าค่อนข้างเปราะบางและเกิดข้อผิดพลาดได้ง่ายและเกิดขึ้นไม่บ่อยพอจนไม่คุ้มกับความพยายามในการนำไปใช้
โปรดดูรายการคำถามที่พบบ่อยของ Lambda
Predicate.alwaysTrue()
คุณก็อาจจะเผลอเขียนPredicate.alwaysFalse()
ไปด้วยก็ได้
alwaysTrue()
alwaysFalse()
ด้วยแลมด้าจริงฉันมีหลายรูปแบบ ฉันกำลังสร้างสูตรขึ้นใหม่ทุกครั้ง ในสาระสำคัญalwaysTrue()
คือป้ายกำกับความหมายสำหรับสิ่งที่ฉันต้องการทำ x->true
กำลังทำซ้ำทุกครั้ง ไม่ใหญ่โต แต่ต้องคำนึงถึง
Predicate.alwaysTrue()
และPredicate.alwaysFalse()
กรณีคือว่าพวกเขาจะได้รับการยอมรับโดยการรวมวิธีการเช่นPredicate.or
, และPredicate.and
Predicate.negate()
สิ่งนี้จะอนุญาตให้เริ่มต้นPredicate
ตัวแปรล่วงหน้าalwaysTrue()
และเพิ่มเพรดิเคตโดยการรวมผ่านand
โดยไม่มีค่าใช้จ่าย x->true
ตั้งแต่การแสดงออกแลมบ์ดาไม่มีการรับประกันตัวตนของวัตถุนี้อาจล้มเหลวด้วย ยังไงก็ตามถ้าฉันมีคลาสที่X
มีstatic
วิธีการy(){return true;}
ใช้งานX::y
จะสั้นกว่าx->true
แต่ไม่แนะนำจริงๆ…
x -> true
มีข้อเสียที่ฉันต้องใช้ตัวแปรโดยไม่ต้องใช้ สิ่งนี้สร้างภาระสมองโดยไม่จำเป็นและยังเป็นการเตือนใน IDE ของฉัน ฉันพยายามใช้_ -> true
แต่นั่นเป็นข้อผิดพลาดทางไวยากรณ์ Java ไม่มีคีย์เวิร์ด (อ่าน: keyletter) สำหรับ "unused parameters" หวังว่าสิ่งนี้จะมาใน Java 9 (หรืออย่างน้อยก็: Java อะไรก็ได้ก่อนที่ฉันจะตาย ^^)
ไม่มีฝรั่ง
Boolean.TRUE::booleanValue
Predicate
เพราะมันไม่ได้ใช้การโต้แย้ง
(foo)->{return true;}
ดีที่สุดที่ฉันทำได้ฉันต้องการที่ดีกว่านี้ แต่คุณหยิบยกขึ้นมาx->true
ซึ่งดีกว่ามากและช่วยบรรเทาปัญหาแรกได้ ประเด็นที่สองคือตรรกะและการประกาศแบบคงที่ ถ้าฉันใช้x->true
ก็ยังมีตรรกะที่เกี่ยวข้องซึ่งฉันอาจจะทำให้x->!true
เสียหายโดยไม่ได้ตั้งใจ (เช่น) แต่Predicate.alwaysTrue()
มีที่ว่างสำหรับข้อผิดพลาดทางตรรกะเป็นศูนย์เนื่องจากมีวิธีการที่คล้ายกันเพียงหนึ่งหรือสองวิธี แถมยังได้รับรหัส IDE ฟรีx->true
เกือบจะดี แต่ฉันยังคงเขียนPredicate.alwaysTrue()
วิธีการด้วยเหตุผลข้างต้น