เลือกองค์ประกอบเดียว
จริงๆ แล้ว การเลือกองค์ประกอบเดียวนั้นง่ายกว่าการเลือกหลายองค์ประกอบอย่างแน่นอน แต่มีปัญหาบางประการที่นี่ ขั้นแรกเรามาดูกันว่าปัญหาคืออะไรเมื่อใช้แนวทางทั่วไป แล้วดูว่าจะใช้นิพจน์แลมบ์ดาเพื่อแก้ไขได้อย่างไร
ขั้นแรกเรามาสร้างวิธีการใหม่เพื่อค้นหาองค์ประกอบที่ขึ้นต้นด้วยตัวอักษรเฉพาะ จากนั้นจึงพิมพ์ออกมา
คัดลอกรหัสรหัสดังต่อไปนี้:
โมฆะสาธารณะคงที่ PickName(
รายการสุดท้าย <String> ชื่อ สตริงสุดท้าย beginningLetter) {
สตริง foundName = null;
สำหรับ (ชื่อสตริง : ชื่อ) {
ถ้า (name.startsWith (ตัวอักษรเริ่มต้น)) {
พบชื่อ = ชื่อ;
หยุดพัก;
-
-
วิธีนี้ก็เหม็นพอๆ กับรถขยะที่เพิ่งผ่านไป ขั้นแรกเราสร้างตัวแปร foundName ใหม่ จากนั้นกำหนดค่าเริ่มต้นให้เป็นโมฆะ นี่คือที่มาของกลิ่นเหม็น เราต้องตรวจสอบว่าเป็นโมฆะหรือไม่ ไม่เช่นนั้น NullPointerException หรือการตอบสนองข้อผิดพลาดจะถูกส่งออกไป นอกจากนี้เรายังใช้ตัววนซ้ำภายนอกเพื่อวนซ้ำรายการ หากเราพบองค์ประกอบที่เราต้องการ เราจะต้องแยกออกจากวงจร ซึ่งเพิ่มกลิ่นดั้งเดิมให้กับ: ความหวาดระแวงแบบพื้นฐาน รูปแบบที่จำเป็น ความไม่แน่นอน ทั้งหมดกลับมามีชีวิตชีวา เมื่อเราออกจากลูปเราต้องตรวจสอบผลลัพธ์ก่อนพิมพ์ งานเล็กๆ แบบนี้ต้องใช้โค้ดที่ยาวขนาดนั้นจริงๆ
มาวิเคราะห์ปัญหานี้อีกครั้ง เราเพียงต้องการให้สามารถเลือกองค์ประกอบแรกที่ตรงกันและจัดการกรณีที่ไม่มีองค์ประกอบดังกล่าวได้อย่างปลอดภัย มาเขียนวิธีการเลือกชื่อนี้ใหม่โดยใช้นิพจน์แลมบ์ดา
คัดลอกรหัสรหัสดังต่อไปนี้:
โมฆะสาธารณะคงที่ PickName(
รายการสุดท้าย <String> ชื่อ สตริงสุดท้าย beginningLetter) {
สุดท้าย ตัวเลือก <String> foundName =
ชื่อ.สตรีม()
.filter(ชื่อ ->name.startsWith(startingLetter))
.findFirst();
System.out.println(String.format("ชื่อที่ขึ้นต้นด้วย %s: %s",
beginningLetter, foundName.orElse("ไม่พบชื่อ")));
-
ฟังก์ชันอันทรงพลังบางอย่างใน JDK ทำให้โค้ดนี้กระชับมาก ขั้นแรก เราใช้วิธี filter เพื่อรับองค์ประกอบทั้งหมดที่ตรงตามเงื่อนไข จากนั้นใช้วิธี findFirst ของคลาส Stream เพื่อเลือกองค์ประกอบแรกของคอลเลกชันที่ส่งคืน เมธอดนี้ส่งคืนออบเจ็กต์เสริม ซึ่งเป็นเครื่องกำจัดกลิ่นที่ได้รับการรับรองอย่างเป็นทางการสำหรับตัวแปร null ใน Java
คลาสทางเลือกมีประโยชน์มาก คุณไม่ต้องกังวลว่าผลลัพธ์จะมีอยู่หรือไม่ มันช่วยเราจากปัญหาข้อยกเว้นของตัวชี้ null และทำให้ชัดเจนยิ่งขึ้นว่าไม่มีผลลัพธ์ใดที่เป็นไปได้ ด้วยเมธอด isPresent() เราสามารถรู้ได้ว่าผลลัพธ์นั้นมีอยู่หรือไม่ หากเราต้องการรับค่าผลลัพธ์ เราสามารถใช้เมธอด get() ได้ นอกจากนี้เรายังสามารถตั้งค่าเริ่มต้นได้โดยใช้ (ชื่อของวิธีนี้จะทำให้คุณตกใจ) วิธี orElse เช่นเดียวกับในโค้ดก่อนหน้า
เราใช้คอลเลกชันเพื่อนที่เราเคยใช้มาก่อนเพื่อยืนยันวิธีการเลือกชื่อของเรา
คัดลอกรหัสรหัสดังต่อไปนี้:
เลือกชื่อ(เพื่อน, "N");
เลือกชื่อ(เพื่อน, "Z");
รหัสนี้จะเลือกองค์ประกอบแรกที่ตรงกัน และพิมพ์ข้อความที่เป็นมิตรหากไม่พบ
คัดลอกรหัสรหัสดังต่อไปนี้:
ชื่อที่ขึ้นต้นด้วย น:เนท
ชื่อที่ขึ้นต้นด้วย Z: ไม่พบชื่อ
การรวมกันของเมธอด findFirst() และคลาส Optinal จะช่วยลดจำนวนโค้ดของเราและดูดี แต่ฟังก์ชั่นของคลาสเสริมนั้นมีอะไรมากกว่านั้นอีกมาก ตัวอย่างเช่น นอกเหนือจากการระบุค่าเริ่มต้นเมื่อไม่มีออบเจ็กต์แล้ว คุณยังสามารถใช้เพื่อรันโค้ดบางส่วนหรือนิพจน์แลมบ์ดาได้ หากผลลัพธ์มีอยู่เช่นนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
foundName.ifPresent(ชื่อ -> System.out.println("สวัสดี " + ชื่อ));
เมื่อเทียบกับรหัสที่จำเป็นในการเลือกชื่อที่ตรงกันแรก สไตล์การทำงานที่หรูหราของโฟลว์จะดูดีกว่า แต่ Call Flow เวอร์ชันนี้มีอะไรให้ทำมากเกินไปหรือเปล่า? ไม่แน่นอน วิธีการเหล่านี้ฉลาดมากและทำงานตามความต้องการ (เราจะสำรวจสิ่งนี้ในเชิงลึกใน Lazy Evalued of Streams ที่หน้า 113)
ตัวอย่างของการเลือกองค์ประกอบเดียวจะแสดงฟังก์ชันที่มีประสิทธิภาพมากขึ้นของไลบรารี JDK มาดูกันว่านิพจน์แลมบ์ดาสามารถค้นหาค่าที่ต้องการตามคอลเลกชันได้อย่างไร