มุมมองของฉันเกี่ยวกับการแสดงออกของแลมบ์ดาในชวาค่อนข้างพันกัน:
หนึ่งฉันคิดว่าด้วยวิธีนี้: การแสดงออกของแลมบ์ดาลดประสบการณ์การอ่านของโปรแกรม Java โปรแกรม Java ไม่เคยโดดเด่นในการแสดงออก ในทางตรงกันข้ามปัจจัยหนึ่งที่ทำให้ Java ได้รับความนิยมคือความปลอดภัยและการอนุรักษ์-แม้แต่ผู้เริ่มต้นก็สามารถเขียนรหัสที่แข็งแกร่งและง่ายต่อการบำรุงรักษาตราบใดที่พวกเขาให้ความสนใจ การแสดงออกของแลมบ์ดามีข้อกำหนดที่ค่อนข้างสูงสำหรับนักพัฒนาดังนั้นพวกเขาจึงเพิ่มปัญหาการบำรุงรักษาบางอย่าง
อีกสิ่งหนึ่งที่ฉันคิดว่า: เป็นรหัสรหัสจำเป็นต้องเรียนรู้และยอมรับคุณสมบัติใหม่ของภาษา หากคุณยอมแพ้จุดแข็งที่แสดงออกเพียงเพราะประสบการณ์การอ่านที่ไม่ดีบางคนพบว่ามันยากที่จะเข้าใจแม้กระทั่งการแสดงออกของ trinocular ภาษาก็กำลังพัฒนาและผู้ที่ไม่สามารถติดตามได้จะถูกทิ้งไว้ข้างหลังโดยสมัครใจ
ฉันไม่อยากถูกทิ้งไว้ข้างหลัง อย่างไรก็ตามถ้าฉันต้องเลือกการตัดสินใจของฉันยังคงค่อนข้างอนุรักษ์นิยม: ไม่จำเป็นต้องใช้แลมบ์ดาในภาษา Java - มันทำให้คนจำนวนมากในวงกลม Java ปัจจุบันไม่คุ้นเคยและจะทำให้ต้นทุนแรงงานเพิ่มขึ้น ถ้าคุณชอบมันมากคุณสามารถพิจารณาใช้ Scala
อย่างไรก็ตามฉันยังคงเริ่มพยายามที่จะควบคุมแลมบ์ดาหลังจากทั้งหมดรหัสบางอย่างที่เก็บรักษาไว้ในที่ทำงานใช้แลมบ์ดา (เชื่อใจฉันฉันจะค่อยๆลบออก) บทเรียนที่จะเรียนรู้เป็นบทเรียนที่เกี่ยวข้องในเว็บไซต์ Oracle Java อย่างเป็นทางการ
-
สมมติว่าขณะนี้แอปพลิเคชันเครือข่ายสังคมกำลังถูกสร้างขึ้น คุณลักษณะหนึ่งคือผู้ดูแลระบบสามารถดำเนินการบางอย่างกับสมาชิกที่ตรงตามเกณฑ์ที่ระบุเช่นการส่งข้อความ ตารางต่อไปนี้อธิบายกรณีการใช้งานนี้โดยละเอียด:
| สนาม | อธิบาย |
| ชื่อ | การดำเนินการเพื่อดำเนินการ |
| ผู้เข้าร่วมหลัก | ผู้ดูแลระบบ |
| ข้อกำหนดเบื้องต้น | ผู้ดูแลระบบเข้าสู่ระบบ |
| โพสต์-เงื่อนไข | ดำเนินการเฉพาะสำหรับสมาชิกที่ตรงตามเกณฑ์ที่ระบุ |
| สถานการณ์ความสำเร็จหลัก | 1. ผู้ดูแลระบบกำหนดมาตรฐานการกรองสำหรับสมาชิกเป้าหมายในการดำเนินการ 2. ผู้ดูแลระบบเลือกการดำเนินการเพื่อดำเนินการ 3. ผู้ดูแลระบบคลิกปุ่มส่ง 4. ระบบค้นหาสมาชิกที่มีคุณสมบัติตรงตามเกณฑ์ที่ระบุ 5. ระบบดำเนินการที่เลือกไว้ล่วงหน้าสำหรับสมาชิกที่ตรงตามเกณฑ์ที่ระบุ |
| ซึ่งขยายออกไป | ก่อนที่จะเลือกการดำเนินการดำเนินการหรือก่อนคลิกปุ่มส่งผู้ดูแลระบบสามารถเลือกได้ว่าจะดูตัวอย่างข้อมูลสมาชิกที่ตรงตามเกณฑ์การกรอง |
| ความถี่ของการเกิดขึ้น | มันเกิดขึ้นหลายครั้งในหนึ่งวัน |
ใช้คลาสบุคคลต่อไปนี้เพื่อแสดงข้อมูลสมาชิกในเครือข่ายสังคมออนไลน์:
บุคคลชั้นเรียนสาธารณะ {public enum sex {ชาย, หญิง} ชื่อสตริง; วันเกิดท้องถิ่น; เพศเพศ; สตริง emailaddress; public int getage () {// ... } public void printperson () {// ... }}สมมติว่าสมาชิกทุกคนจะถูกบันทึกไว้ในรายการ <person> อินสแตนซ์
ในส่วนนี้เราเริ่มต้นด้วยวิธีที่ง่ายมากจากนั้นลองใช้งานโดยใช้คลาสท้องถิ่นและชั้นเรียนที่ไม่ระบุชื่อและในตอนท้ายเราจะค่อยๆสัมผัสกับพลังและประสิทธิภาพของการแสดงออกของแลมบ์ดา รหัสที่สมบูรณ์สามารถพบได้ที่นี่
โซลูชัน 1: สร้างวิธีการค้นหาสมาชิกที่ตรงตามเกณฑ์ที่ระบุทีละหนึ่ง
นี่เป็นวิธีแก้ปัญหาที่ง่ายและหยาบที่สุดในการใช้กรณีดังกล่าว: มันคือการสร้างวิธีการหลายวิธีและแต่ละวิธีจะตรวจสอบเกณฑ์ (เช่นอายุหรือเพศ) รหัสต่อไปนี้ตรวจสอบว่าอายุนั้นเก่ากว่าค่าที่ระบุ:
โมฆะสาธารณะคงที่ printpersonsolderthan (รายการ <person> บัญชีรายชื่ออายุ int) {สำหรับ (บุคคล P: บัญชีรายชื่อ) {ถ้า (p.getage ()> = อายุ) {p.printperson (); -นี่เป็นวิธีแก้ปัญหาที่เปราะบางมากและเป็นไปได้มากที่แอปพลิเคชันจะไม่ทำงานเนื่องจากการอัปเดตเล็กน้อย หากเราเพิ่มตัวแปรสมาชิกใหม่ในคลาสบุคคลหรือเปลี่ยนอัลกอริทึมสำหรับการวัดอายุในมาตรฐานเราจำเป็นต้องเขียนโค้ดจำนวนมากเพื่อปรับให้เข้ากับการเปลี่ยนแปลงนี้ นอกจากนี้ข้อ จำกัด ที่นี่มีความเข้มงวดเกินไป ตัวอย่างเช่นเราควรทำอย่างไรถ้าเราต้องการพิมพ์สมาชิกที่อายุน้อยกว่าค่าที่ระบุ? เพิ่มวิธีการใหม่ printpersonsyoungerthan อีกวิธีหนึ่ง? เห็นได้ชัดว่าเป็นวิธีที่โง่
โซลูชันที่ 2: สร้างวิธีการทั่วไปเพิ่มเติม
วิธีการต่อไปนี้สามารถปรับได้มากกว่า printpersonsolderthan; วิธีนี้พิมพ์ข้อมูลสมาชิกภายในกลุ่มอายุที่ระบุ:
โมฆะสาธารณะคงที่ printPersonSwithInagerange (รายการ <person> บัญชีรายชื่อ, int ต่ำ, int สูง) {สำหรับ (บุคคล p: บัญชีรายชื่อ) {ถ้า (ต่ำ <= p.getage () && p.getage () <สูง) {p.printperson (); -ตอนนี้มีแนวคิดใหม่: เราควรทำอย่างไรถ้าเราต้องการพิมพ์ข้อมูลสมาชิกของเพศที่ระบุหรือตรงกับเพศที่ระบุและอยู่ในกลุ่มอายุที่กำหนด? จะเกิดอะไรขึ้นถ้าเราปรับระดับบุคคลและเพิ่มคุณสมบัติเช่นมิตรภาพและที่ตั้งทางภูมิศาสตร์ แม้ว่าวิธีการเขียนเช่นนี้จะเป็นสากลมากกว่า printpersonsyoungerthan การเขียนวิธีการสำหรับการสืบค้นทุกครั้งที่เป็นไปได้สามารถนำไปสู่ความเปราะบางในรหัส เป็นการดีกว่าที่จะนำรหัสตรวจสอบมาตรฐานลงในคลาสใหม่
โซลูชัน 3: ใช้การตรวจสอบมาตรฐานในชั้นเรียนท้องถิ่น
วิธีการต่อไปนี้พิมพ์ข้อมูลสมาชิกที่ตรงตามเกณฑ์การค้นหา:
Public Public Void PrintPersons (รายการ <person> บัญชีรายชื่อผู้ทดสอบ CheckPerson) {สำหรับ (บุคคล P: บัญชีรายชื่อ) {ถ้า (tester.test (p)) {p.printperson (); -ตัวทดสอบวัตถุ CheckPerso ใช้ในโปรแกรมเพื่อตรวจสอบแต่ละอินสแตนซ์ในบัญชีรายชื่อพารามิเตอร์รายการ หาก tester.test () ส่งคืนจริงเมธอด printperson () จะถูกดำเนินการ ในการตั้งค่าเกณฑ์การค้นหาจะต้องมีการใช้งานอินเทอร์เฟซ CheckPerson
คลาสต่อไปนี้ใช้ CheckPerson และให้การใช้งานเฉพาะของวิธีการทดสอบ วิธีการทดสอบในชั้นเรียนนี้กรองข้อมูลเกี่ยวกับการเป็นสมาชิกที่ตรงตามข้อกำหนดสำหรับการรับราชการทหารในสหรัฐอเมริกานั่นคือเพศชายและอายุระหว่าง 18 ถึง 25 ปี
checkPersoneliveboreforlectiveService ใช้ checkperson {การทดสอบบูลีนสาธารณะ (บุคคล P) {return p.gender == person.sex.male && p.getage ()> = 18 && p.getage () <= 25; -ในการใช้คลาสนี้คุณต้องสร้างอินสแตนซ์และทริกเกอร์วิธี PrintPersons:
PrintPersons (บัญชีรายชื่อ, CheckPersonelyforSeforSeleCtiveService ใหม่ ());
ตอนนี้รหัสดูบอบบางน้อยลง - เราไม่จำเป็นต้องเขียนโค้ดใหม่เนื่องจากการเปลี่ยนแปลงในโครงสร้างคลาสบุคคล อย่างไรก็ตามยังมีรหัสเพิ่มเติมที่นี่: อินเทอร์เฟซที่กำหนดใหม่ซึ่งกำหนดคลาสภายในสำหรับแต่ละมาตรฐานการค้นหาในแอปพลิเคชัน
เนื่องจาก CheckPersonEluredSelectiveService ใช้อินเทอร์เฟซจึงสามารถใช้คลาสที่ไม่ระบุชื่อได้โดยไม่ต้องกำหนดคลาสด้านในสำหรับแต่ละมาตรฐาน
โซลูชัน 4: ใช้คลาสที่ไม่ระบุชื่อเพื่อใช้การตรวจสอบมาตรฐาน
หนึ่งพารามิเตอร์ในวิธี PrintPersons ที่เรียกว่าด้านล่างคือคลาสที่ไม่ระบุชื่อ ฟังก์ชั่นของชั้นเรียนที่ไม่ระบุชื่อนี้เหมือนกับของ CheckPersonelyforSeveSefleCtiveservice Class ในโครงการ 3: พวกเขาทั้งหมดเป็นสมาชิกที่ถูกกรองด้วยเพศชายและอายุระหว่าง 18 ถึง 25 ปี
PrintPersons (บัญชีรายชื่อ, CheckPerson ใหม่ () {การทดสอบบูลีนสาธารณะ (บุคคล P) {return p.getGender () == person.sex.male && p.getage ()> = 18 && p.getage () <= 25;}});รูปแบบนี้จะลดจำนวนการเข้ารหัสเนื่องจากไม่จำเป็นต้องสร้างคลาสใหม่สำหรับแต่ละรูปแบบการค้นหาที่จะดำเนินการ อย่างไรก็ตามมันก็ยังอึดอัดเล็กน้อยที่จะทำเช่นนี้: แม้ว่าอินเทอร์เฟซ CheckPerson มีเพียงวิธีเดียว แต่คลาสที่ไม่ระบุชื่อที่นำมาใช้ก็ยังคงเป็นสีสันและขนาดใหญ่ ในเวลานี้คุณสามารถใช้นิพจน์แลมบ์ดาเพื่อแทนที่คลาสที่ไม่ระบุชื่อ ต่อไปนี้จะอธิบายวิธีการใช้นิพจน์แลมบ์ดาเพื่อแทนที่คลาสที่ไม่ระบุชื่อ
โซลูชัน 5: ใช้นิพจน์แลมบ์ดาเพื่อใช้การตรวจสอบมาตรฐาน
อินเทอร์เฟซ CheckPerson เป็นอินเทอร์เฟซที่ใช้งานได้ อินเทอร์เฟซที่เรียกว่าฟังก์ชั่นที่เรียกว่าอินเทอร์เฟซใด ๆ ที่มีวิธีการนามธรรมเดียวเท่านั้น (อินเทอร์เฟซที่ใช้งานได้สามารถมีวิธีการเริ่มต้นหลายวิธีหรือวิธีการคงที่) เนื่องจากมีวิธีการนามธรรมเพียงวิธีเดียวในอินเทอร์เฟซการทำงานชื่อวิธีของวิธีการสามารถละเว้นได้เมื่อใช้วิธีการของอินเทอร์เฟซการทำงานนี้ ในการใช้แนวคิดนี้คุณสามารถแทนที่นิพจน์คลาสที่ไม่ระบุชื่อด้วยนิพจน์แลมบ์ดา ในวิธี PrintPersons ที่เขียนใหม่ด้านล่างรหัสที่เกี่ยวข้องจะถูกเน้น:
PrintPersons (บัญชีรายชื่อ, (Person P) -> P.GetGender () == Person.sex.male && P.Getage ()> = 18 && P.Getage () <= 25);
ที่นี่คุณยังสามารถใช้อินเทอร์เฟซฟังก์ชั่นมาตรฐานเพื่อแทนที่อินเตอร์เฟส CheckPerson ซึ่งจะทำให้รหัสง่ายขึ้น
โซลูชัน 6: ใช้อินเทอร์เฟซการทำงานมาตรฐานในนิพจน์แลมบ์ดา
มาดูอินเทอร์เฟซ CheckPerson:
Interface CheckPerson {การทดสอบบูลีน (Person P); -นี่เป็นอินเทอร์เฟซที่ง่ายมาก เนื่องจากมีวิธีนามธรรมเพียงวิธีเดียวจึงเป็นอินเทอร์เฟซที่ใช้งานได้ วิธีนามธรรมนี้ยอมรับพารามิเตอร์เดียวเท่านั้นและส่งคืนค่าบูลีน อินเทอร์เฟซนามธรรมนี้ง่ายมากที่เราจะพิจารณาว่าจำเป็นต้องกำหนดอินเทอร์เฟซดังกล่าวในแอปพลิเคชันหรือไม่ ในเวลานี้คุณสามารถพิจารณาใช้อินเทอร์เฟซฟังก์ชันมาตรฐานที่กำหนดโดย JDK และคุณสามารถค้นหาอินเทอร์เฟซเหล่านี้ได้ภายใต้แพ็คเกจ Java.util.Function
ในตัวอย่างนี้เราสามารถใช้อินเทอร์เฟซ Predicate <T> เพื่อแทนที่ CheckPerson มีวิธีการทดสอบบูลีน (T T) ในอินเทอร์เฟซนี้:
อินเทอร์เฟซ Predicate <T> {การทดสอบบูลีน (T T); -อินเทอร์เฟซ Predicate <t> เป็นอินเทอร์เฟซทั่วไป คลาสทั่วไป (หรืออินเทอร์เฟซทั่วไป) ระบุพารามิเตอร์ประเภทหนึ่งหรือมากกว่าโดยใช้วงเล็บมุมคู่ (<>) มีพารามิเตอร์ประเภทเดียวในอินเทอร์เฟซนี้ เมื่อคุณประกาศหรือยกตัวอย่างคลาสทั่วไปโดยใช้คลาสคอนกรีตคุณจะได้รับคลาสพารามิเตอร์ ตัวอย่างเช่น Parameterized Class Predicate <person> เป็นเช่นนี้:
อินเทอร์เฟซ Predicate <person> {การทดสอบบูลีน (บุคคล T); -ในคลาสพารามิเตอร์นี้มีวิธีการที่สอดคล้องกับพารามิเตอร์และค่าส่งคืนของวิธีการตรวจสอบการทดสอบการทดสอบ (Person P) ดังนั้นคุณสามารถใช้อินเทอร์เฟซ Predicate <T> เพื่อแทนที่อินเตอร์เฟส CheckPerson ตามที่แสดงในวิธีการต่อไปนี้:
public void printpersonswithpredicate (รายการ <person> บัญชีรายชื่อ, predicate <person> tester) {สำหรับ (บุคคล p: บัญชีรายชื่อ) {ถ้า (tester.test (p)) {p.printperson (); -จากนั้นใช้รหัสต่อไปนี้เพื่อกรองสมาชิกของการรับราชการทหารเช่นในแผน 3:
PrintPersonsWithPredicate (บัญชีรายชื่อ, P -> P.GetGender () == person.sex.male && p.getage ()> = 18 && p.getage () <= 25);
คุณสังเกตเห็นว่าเมื่อใช้ Predicate <person> เป็นประเภทพารามิเตอร์จะไม่มีการระบุประเภทพารามิเตอร์ที่ชัดเจน นี่ไม่ใช่สถานที่เดียวที่ใช้การแสดงออกของแลมบ์ดา โครงการต่อไปนี้จะแนะนำการใช้งาน Lambda Expressions มากขึ้น
โซลูชัน 7: ใช้นิพจน์แลมบ์ดาตลอดแอปพลิเคชัน
ลองมาดูวิธี PrintPersonsWithPredicate และพิจารณาว่าคุณสามารถใช้ Expressions Lambda ได้ที่นี่หรือไม่:
public void printpersonswithpredicate (รายการ <person> บัญชีรายชื่อ, predicate <person> tester) {สำหรับ (บุคคล p: บัญชีรายชื่อ) {ถ้า (tester.test (p)) {p.printperson (); -ในวิธีนี้แต่ละอินสแตนซ์ของแต่ละคนในบัญชีรายชื่อจะถูกตรวจสอบโดยใช้เครื่องทดสอบอินสแตนซ์เพรดิเคต หากอินสแตนซ์ของบุคคลนั้นเป็นไปตามเกณฑ์การตรวจสอบที่กำหนดไว้ในเครื่องทดสอบวิธีการพิมพ์ printperson ของอินสแตนซ์บุคคลจะถูกเรียกใช้
นอกเหนือจากการเรียกใช้วิธี printperson อินสแตนซ์ของบุคคลที่ตรงตามมาตรฐานผู้ทดสอบยังสามารถดำเนินการวิธีการอื่นได้ คุณสามารถพิจารณาใช้นิพจน์แลมบ์ดาเพื่อระบุวิธีการที่จะดำเนินการ (ฉันคิดว่าคุณสมบัตินี้ดีซึ่งแก้ปัญหาที่วิธีการใน Java ไม่สามารถส่งผ่านเป็นวัตถุ) ตอนนี้คุณต้องมีนิพจน์แลมบ์ดาคล้ายกับวิธี printperson - นิพจน์แลมบ์ดาที่ต้องการเพียงหนึ่งพารามิเตอร์และส่งคืนโมฆะ โปรดจำไว้ว่าสิ่งหนึ่ง: ในการใช้นิพจน์แลมบ์ดาคุณต้องใช้อินเทอร์เฟซที่ใช้งานได้ก่อน ในตัวอย่างนี้จำเป็นต้องใช้อินเทอร์เฟซที่ใช้งานได้ซึ่งมีวิธีนามธรรมเพียงวิธีเดียว วิธีนามธรรมนี้มีพารามิเตอร์ของประเภทบุคคลและกลับไปเป็นโมฆะ คุณสามารถดูที่อินเทอร์เฟซผู้บริโภคที่ใช้งานได้มาตรฐาน <T> จัดทำโดย JDK ซึ่งมีวิธีการที่เป็นนามธรรมเป็นโมฆะยอมรับ (T T) เพียงแค่ตรงตามข้อกำหนดนี้ ในรหัสต่อไปนี้ให้ใช้อินสแตนซ์ของผู้บริโภค <t> เพื่อเรียกใช้วิธีการยอมรับแทน p.printperson ():
ProcessPersperson Void แบบคงที่ (รายการ <person> บัญชีรายชื่อผู้ทดสอบ <person> ผู้ทดสอบผู้บริโภค <person> บล็อก) {สำหรับ (บุคคล P: บัญชีรายชื่อ) {ถ้า (tester.test (p)) {block.accept (p); -ตามลําดับคุณสามารถใช้รหัสต่อไปนี้เพื่อกรองสมาชิกของอายุการรับราชการทหาร:
ProcessPersons (บัญชีรายชื่อ, P -> P.GetGender () == person.sex.male && p.getage ()> = 18 && p.getage () <= 25, p -> p.printperson ());
หากเราต้องการทำสิ่งต่าง ๆ ที่ไม่ได้เป็นเพียงการพิมพ์ข้อมูลสมาชิก แต่ยังมีสิ่งต่าง ๆ เช่นการตรวจสอบการเป็นสมาชิกการรับข้อมูลการติดต่อสมาชิก ฯลฯ ณ จุดนี้เราต้องใช้อินเทอร์เฟซที่ใช้งานได้ด้วยวิธีการส่งคืน ฟังก์ชั่นอินเทอร์เฟซการใช้งานมาตรฐานของ JDK <t, r> มีวิธีการเช่นนี้ใช้ r (t t) วิธีการต่อไปนี้ได้รับข้อมูลจาก Mapper พารามิเตอร์และดำเนินการพฤติกรรมที่ระบุโดยบล็อกพารามิเตอร์บนข้อมูลเหล่านี้:
โมฆะสาธารณะคงที่ ProcessPersonSwithFunction (รายการ <person> บัญชีรายชื่อ, predicate <person> tester, ฟังก์ชั่น <person, string> mapper, ผู้บริโภค <String> บล็อก) {สำหรับ (บุคคล P: บัญชีรายชื่อ) {ถ้า (tester.test (p)) {สตริงข้อมูล = mapper.apply (p); block.accept (ข้อมูล); -รหัสต่อไปนี้ได้รับข้อมูลอีเมลของสมาชิกทุกคนในยุครับราชการทหารในบัญชีรายชื่อและพิมพ์ออกมา:
ProcessPersonSwithFunction (บัญชีรายชื่อ, P -> P.GetGender () == person.sex.male && p.getage ()> = 18 && p.getage () <= 25, p -> p.getemailaddress (), อีเมล -> system.out.println (อีเมล));
โซลูชัน 8: ใช้ยาชื่อสามัญบ่อยขึ้น
ลองตรวจสอบวิธี ProcessPersonsWithFunction ต่อไปนี้เป็นเวอร์ชันทั่วไปของวิธีนี้ วิธีการใหม่ต้องการความอดทนมากขึ้นในประเภทพารามิเตอร์:
สาธารณะคงที่ <x, y> โมฆะ processlements (iterable <x> แหล่งที่มา, predicate <x> tester, ฟังก์ชั่น <x, y> mapper, ผู้บริโภค <y> บล็อก) {สำหรับ (x p: แหล่งที่มา) {ถ้า (tester.test (p)) {y data = mapper.apply (p); block.accept (ข้อมูล); -ในการพิมพ์ข้อมูลสมาชิกสำหรับการรับราชการทหารในวัยที่เหมาะสมคุณสามารถโทรหาวิธี ProcessElements ได้ดังต่อไปนี้:
ProcessElements (บัญชีรายชื่อ, P -> P.GetGender () == person.sex.male && p.getage ()> = 18 && p.getage () <= 25, p -> p.getemailaddress (), อีเมล -> system.out.println (อีเมล));
ในระหว่างกระบวนการเรียกใช้วิธีการพฤติกรรมต่อไปนี้จะดำเนินการ:
รับข้อมูลวัตถุจากการรวบรวมในตัวอย่างนี้รับข้อมูลวัตถุบุคคลจากบัญชีรายชื่ออินสแตนซ์การรวบรวม
ตัวกรองวัตถุที่สามารถจับคู่ผู้ทดสอบอินสแตนซ์เพรดิเคต ในตัวอย่างนี้วัตถุภาคแสดงคือการแสดงออกของแลมบ์ดาที่ระบุเงื่อนไขสำหรับการกรองการรับราชการทหารในวัยที่เหมาะสม
วัตถุที่ผ่านการกรองจะถูกส่งไปยังแม็ป (Mapper Object Object สำหรับการประมวลผลและ MAPPER จะตรงกับค่ากับวัตถุนี้ ในตัวอย่างนี้ Mapper Object Function เป็นนิพจน์แลมบ์ดาที่ส่งคืนที่อยู่อีเมลของสมาชิกแต่ละคน
ระบุพฤติกรรมโดยบล็อกวัตถุผู้บริโภคสำหรับค่าที่จับคู่โดย Mapper ในตัวอย่างนี้วัตถุผู้บริโภคเป็นนิพจน์แลมบ์ดาซึ่งเป็นฟังก์ชั่นของการพิมพ์สตริงซึ่งเป็นที่อยู่อีเมลสมาชิกที่ส่งคืนโดยแม็กอินสแตนซ์ฟังก์ชั่น
โซลูชัน 9: ใช้การดำเนินการรวมโดยใช้นิพจน์แลมบ์ดาเป็นพารามิเตอร์
รหัสต่อไปนี้ใช้การดำเนินการรวมเพื่อพิมพ์ที่อยู่อีเมลของสมาชิกวัยทหารในคอลเลกชันบัญชีรายชื่อ:
ROSTER.STREAM () .Filter (P -> P.GetGender () == person.sex.male && p.getage ()> = 18 && p.getage () <= 25) .map (p -> p.getemailaddress ()). foreach (อีเมล -> system.out.println (อีเมล)
วิเคราะห์กระบวนการดำเนินการของรหัสข้างต้นและจัดระเบียบตารางต่อไปนี้:
พฤติกรรม | การดำเนินการรวม |
รับวัตถุ | สตรีม <e> สตรีม () |
ตัวกรองวัตถุที่ตรงกับเกณฑ์ที่ระบุของอินสแตนซ์ภาคแสดง | สตรีม <t> ตัวกรอง (Predicate <? super t> ทำนาย) |
รับค่าการจับคู่ของวัตถุผ่านอินสแตนซ์ฟังก์ชั่น | <r> สตรีม <r> แผนที่ (ฟังก์ชั่น <? super t, ขยาย r> mapper) |
ดำเนินการพฤติกรรมที่ระบุโดยอินสแตนซ์ของผู้บริโภค | เป็นโมฆะ foreach (ผู้บริโภค <? super t> การกระทำ) |
การดำเนินการตัวกรองแผนที่และ foreach ในตารางล้วนดำเนินการโดยรวม องค์ประกอบที่ประมวลผลโดยการดำเนินการรวมมาจากสตรีมไม่ใช่โดยตรงจากคอลเลกชัน (นั่นคือเนื่องจากวิธีแรกที่เรียกว่าในโปรแกรมตัวอย่างนี้คือสตรีม ()) สตรีมเป็นลำดับข้อมูล สตรีมไม่ได้จัดเก็บข้อมูลด้วยโครงสร้างเฉพาะซึ่งแตกต่างจากคอลเลกชัน สตรีมได้รับข้อมูลจากแหล่งเฉพาะเช่นจากคอลเลกชันผ่านไปป์ไลน์ Pipeline เป็นลำดับการทำงานของสตรีมในตัวอย่างนี้ตัวกรอง-แผนที่-foreach นอกจากนี้การดำเนินการรวมมักจะใช้นิพจน์แลมบ์ดาเป็นพารามิเตอร์ซึ่งทำให้เรามีพื้นที่ที่กำหนดเองมากมาย