Google ฝรั่งมีกริยาที่ผลตอบแทนเสมอ trueJava 8 มีบางอย่างที่คล้ายกันPredicateหรือไม่? ฉันรู้ว่าฉันสามารถใช้แต่ฉันต้องการบางสิ่งบางอย่างที่ทำไว้ล่วงหน้าเพื่อที่คล้ายคลึงกัน(foo)->{return true;}Collections.emptySet()
Google ฝรั่งมีกริยาที่ผลตอบแทนเสมอ trueJava 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()วิธีการด้วยเหตุผลข้างต้น