การแนะนำ
นิพจน์แลมบ์ดาเป็นคุณสมบัติใหม่ที่สำคัญใน Java SE 8 นิพจน์ Lambda ช่วยให้คุณสามารถแทนที่อินเทอร์เฟซการทำงานด้วยนิพจน์ได้ นิพจน์ lambda ก็เหมือนกับวิธีการ โดยแสดงรายการพารามิเตอร์ปกติและเนื้อหา (ซึ่งอาจเป็นนิพจน์หรือบล็อคโค้ด) ที่ใช้พารามิเตอร์เหล่านี้
นิพจน์ Lambda ยังปรับปรุงไลบรารีคอลเลกชันอีกด้วย Java SE 8 เพิ่มสองแพ็คเกจสำหรับการดำเนินการแบบแบตช์กับข้อมูลที่เก็บรวบรวม: แพ็คเกจ java.util.function และแพ็คเกจ java.util.stream สตรีมก็เหมือนกับตัววนซ้ำ แต่มีคุณสมบัติเพิ่มเติมมากมาย โดยรวมแล้ว นิพจน์และสตรีมแลมบ์ดาเป็นการเปลี่ยนแปลงครั้งใหญ่ที่สุดนับตั้งแต่มีการเพิ่มข้อมูลทั่วไปและคำอธิบายประกอบให้กับภาษา Java ในบทความนี้ เราจะเห็นพลังของนิพจน์แลมบ์ดาและสตรีมจากตัวอย่างง่ายไปจนถึงตัวอย่างที่ซับซ้อน
การเตรียมสิ่งแวดล้อม
หากไม่ได้ติดตั้ง Java 8 คุณควรติดตั้งก่อนจึงจะสามารถใช้แลมบ์ดาและสตรีมได้ (นักแปลแนะนำให้ติดตั้งในเครื่องเสมือนเพื่อทำการทดสอบ) เครื่องมือและ IDE เช่น NetBeans และ IntelliJ IDEA รองรับคุณสมบัติ Java 8 รวมถึงนิพจน์แลมบ์ดา คำอธิบายประกอบที่ทำซ้ำได้ โปรไฟล์ขนาดเล็ก และคุณสมบัติอื่นๆ
ไวยากรณ์นิพจน์แลมบ์ดา
ไวยากรณ์พื้นฐาน:
(พารามิเตอร์) -> นิพจน์
หรือ
(พารามิเตอร์) ->{ คำสั่ง; }
นี่เป็นตัวอย่างง่ายๆ ของนิพจน์ Java lambda:
คัดลอกรหัสรหัสดังต่อไปนี้:
// 1. ไม่จำเป็นต้องมีพารามิเตอร์ ค่าที่ส่งคืนคือ 5
() -> 5
// 2. รับพารามิเตอร์ (ประเภทตัวเลข) และส่งคืนค่า 2 เท่า
x -> 2*x
// 3. ยอมรับ 2 พารามิเตอร์ (ตัวเลข) และส่งคืนส่วนต่าง
(x, y) -> xy
// 4. รับจำนวนเต็มประเภท int 2 จำนวนแล้วส่งคืนผลรวม
(int x, int y) -> x + y
// 5. ยอมรับวัตถุสตริงและพิมพ์บนคอนโซลโดยไม่ส่งคืนค่าใด ๆ (ดูเหมือนว่าจะคืนค่าเป็นโมฆะ)
(สตริง s) -> System.out.print
ตัวอย่างแลมบ์ดาพื้นฐาน
ตอนนี้เรารู้แล้วว่านิพจน์แลมบ์ดาคืออะไร เรามาเริ่มด้วยตัวอย่างพื้นฐานกันก่อน ในส่วนนี้ เราจะดูว่านิพจน์ lambda ส่งผลต่อวิธีที่เราเขียนโค้ดอย่างไร สมมติว่ามีรายชื่อผู้เล่น โปรแกรมเมอร์สามารถใช้คำสั่ง for ("for loop") เพื่อสำรวจ ซึ่งสามารถแปลงเป็นรูปแบบอื่นใน Java SE 8:
คัดลอกรหัสรหัสดังต่อไปนี้:
สตริง[] atp = {"ราฟาเอล นาดาล", "โนวัค ยอโควิช",
"สตานิสลาส วาวรินก้า"
"เดวิด เฟอร์เรอร์", "โรเจอร์ เฟเดอเรอร์",
แอนดี้ เมอร์เรย์, โทมัส เบอร์ดิช
"ฮวน มาร์ติน เดล โปโตร"};
รายการผู้เล่น <String> = Arrays.asList(atp);
// วิธีการวนซ้ำก่อนหน้า
สำหรับ (ผู้เล่นสตริง : ผู้เล่น) {
System.out.print(ผู้เล่น + "; ");
-
//ใช้นิพจน์แลมบ์ดาและการดำเนินการตามฟังก์ชัน
ผู้เล่น.forEach((ผู้เล่น) -> System.out.print(ผู้เล่น + "; "));
//ใช้ตัวดำเนินการโคลอนคู่ใน Java 8
ผู้เล่นforEach(System.out::println);
อย่างที่คุณเห็น นิพจน์แลมบ์ดาสามารถลดโค้ดของเราให้เหลือหนึ่งบรรทัดได้ อีกตัวอย่างหนึ่งคือในโปรแกรมส่วนต่อประสานกราฟิกกับผู้ใช้ซึ่งคลาสที่ไม่ระบุชื่อสามารถถูกแทนที่ด้วยนิพจน์แลมบ์ดา ในทำนองเดียวกัน สามารถใช้ในลักษณะนี้เมื่อใช้อินเทอร์เฟซ Runnable:
คัดลอกรหัสรหัสดังต่อไปนี้:
//ใช้คลาสภายในที่ไม่ระบุชื่อ
btn.setOnAction(EventHandler ใหม่<ActionEvent>() {
@แทนที่
โมฆะสาธารณะจัดการ (เหตุการณ์ ActionEvent) {
System.out.println("สวัสดีชาวโลก!");
-
-
// หรือใช้นิพจน์แลมบ์ดา
btn.setOnAction(เหตุการณ์ -> System.out.println("สวัสดีชาวโลก!"));
ต่อไปนี้เป็นตัวอย่างของการใช้ lambdas เพื่อใช้งานอินเทอร์เฟซ Runnable:
คัดลอกรหัสรหัสดังต่อไปนี้:
// 1.1 ใช้คลาสภายในที่ไม่ระบุชื่อ
เธรดใหม่ (เรียกใช้ใหม่ () {
@แทนที่
โมฆะสาธารณะวิ่ง () {
System.out.println("สวัสดีชาวโลก!");
-
}).เริ่ม();
// 1.2 ใช้นิพจน์แลมบ์ดา
เธรดใหม่ (() -> System.out.println ("สวัสดีชาวโลก!")). เริ่มต้น ();
// 2.1 ใช้คลาสภายในที่ไม่ระบุชื่อ
Runnable race1 = Runnable ใหม่ () {
@แทนที่
โมฆะสาธารณะวิ่ง () {
System.out.println("สวัสดีชาวโลก!");
-
-
// 2.2 ใช้นิพจน์แลมบ์ดา
Runnable race2 = () -> System.out.println ("สวัสดีชาวโลก!");
// เรียกใช้เมธอด run โดยตรง (ไม่มีการเปิดเธรดใหม่!)
race1.run();
race2.run();
นิพจน์แลมบ์ดาของ Runnable ใช้รูปแบบบล็อกเพื่อแปลงโค้ดห้าบรรทัดให้เป็นคำสั่งบรรทัดเดียว ต่อไป ในส่วนถัดไป เราจะใช้ lambdas เพื่อจัดเรียงคอลเลกชัน
การเรียงลำดับคอลเลกชันโดยใช้ Lambdas
ใน Java คลาส Comparator ใช้เพื่อเรียงลำดับคอลเลกชัน ในตัวอย่างด้านล่าง เราจะยึดตามชื่อผู้เล่น นามสกุล ความยาวของชื่อ และอักษรตัวสุดท้าย เช่นเดียวกับในตัวอย่างก่อนหน้านี้ ขั้นแรกเราใช้คลาสภายในที่ไม่ระบุชื่อเพื่อเรียงลำดับ จากนั้นใช้นิพจน์ lambda เพื่อปรับปรุงโค้ดของเรา
ในตัวอย่างแรก เราจะจัดเรียงรายการตามชื่อ หากใช้วิธีเก่า โค้ดจะมีลักษณะดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ผู้เล่นสตริง[] = {"ราฟาเอล นาดาล", "โนวัค ยอโควิช",
"สตานิสลาส วาวรินก้า", "เดวิด เฟร์เรอร์",
"โรเจอร์ เฟเดอเรอร์", "แอนดี เมอร์เรย์",
โทมัส เบอร์ดิช, ฮวน มาร์ติน เดล โปโตร
"ริชาร์ด แกสเกต์", "จอห์น อิสเนอร์"};
// 1.1 ใช้คลาสภายในที่ไม่ระบุตัวตนเพื่อจัดเรียงผู้เล่นตามชื่อ
Arrays.sort(ผู้เล่น ตัวเปรียบเทียบใหม่<String>() {
@แทนที่
การเปรียบเทียบ int สาธารณะ (สตริง s1, สตริง s2) {
กลับ (s1.compareTo (s2));
-
-
การใช้แลมบ์ดาสามารถใช้งานฟังก์ชันเดียวกันได้โดยใช้โค้ดต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
// 1.2 ใช้ lambda expression เพื่อจัดเรียงผู้เล่น
ตัวเปรียบเทียบ <String> sortByName = (สตริง s1, สตริง s2) -> (s1.compareTo(s2));
Arrays.sort (ผู้เล่น sortByName);
// 1.3 สามารถใช้แบบฟอร์มต่อไปนี้ได้:
Arrays.sort (ผู้เล่น (สตริง s1, สตริง s2) -> (s1.compareTo (s2)));
ส่วนอันดับอื่นๆ มีดังนี้ เช่นเดียวกับตัวอย่างข้างต้น โค้ดใช้ Comparator ผ่านคลาสภายในที่ไม่ระบุชื่อและนิพจน์แลมบ์ดาบางส่วน:
คัดลอกรหัสรหัสดังต่อไปนี้:
// 1.1 ใช้คลาสภายในที่ไม่ระบุตัวตนเพื่อจัดเรียงผู้เล่นตามนามสกุล
Arrays.sort(ผู้เล่น ตัวเปรียบเทียบใหม่<String>() {
@แทนที่
การเปรียบเทียบ int สาธารณะ (สตริง s1, สตริง s2) {
กลับ (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));
-
-
// 1.2 ใช้นิพจน์แลมบ์ดาเพื่อจัดเรียงตามนามสกุล
ตัวเปรียบเทียบ <String> sortBySurname = (สตริง s1, สตริง s2) ->
( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) );
Arrays.sort (ผู้เล่น, sortBySurname);
// 1.3 หรือประมาณนี้ สงสัยคนเขียนเดิมผิดวงเล็บเยอะมาก...
Arrays.sort (ผู้เล่น (สตริง s1, สตริง s2) ->
( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) )
-
// 2.1 ใช้คลาสภายในที่ไม่ระบุตัวตนเพื่อจัดเรียงผู้เล่นตามความยาวของชื่อ
Arrays.sort(ผู้เล่น ตัวเปรียบเทียบใหม่<String>() {
@แทนที่
การเปรียบเทียบ int สาธารณะ (สตริง s1, สตริง s2) {
กลับ (s1.length() - s2.length());
-
-
// 2.2 ใช้ lambda expression เพื่อจัดเรียงตามความยาวของชื่อ
ตัวเปรียบเทียบ <String> sortByNameLenght = (สตริง s1, สตริง s2) -> (s1.length() - s2.length());
Arrays.sort (ผู้เล่น sortByNameLenght);
// 2.3 หรือนี่
Arrays.sort(ผู้เล่น (สตริง s1, สตริง s2) -> (s1.length() - s2.length()));
// 3.1 ใช้คลาสภายในที่ไม่ระบุตัวตนเพื่อจัดเรียงผู้เล่นตามตัวอักษรตัวสุดท้าย
Arrays.sort(ผู้เล่น ตัวเปรียบเทียบใหม่<String>() {
@แทนที่
การเปรียบเทียบ int สาธารณะ (สตริง s1, สตริง s2) {
กลับ (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
-
-
// 3.2 ใช้ lambda expression เพื่อจัดเรียงตามตัวอักษรตัวสุดท้าย
ตัวเปรียบเทียบ <สตริง> sortByLastLetter =
(สตริง s1, สตริง s2) ->
(s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
Arrays.sort (ผู้เล่น sortByLastLetter);
// 3.3 หรือนี่
Arrays.sort(ผู้เล่น (สตริง s1, สตริง s2) -> (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1)));
แค่นั้นแหละ เรียบง่ายและใช้งานง่าย ในส่วนถัดไป เราจะสำรวจความสามารถของ lambda เพิ่มเติมและใช้กับสตรีม
การใช้แลมบ์ดาและสตรีม
Stream เป็น wrapper สำหรับคอลเลกชัน และมักจะใช้ร่วมกับ lambda การใช้ lambdas สามารถรองรับการดำเนินการได้หลายอย่าง เช่น แผนที่ ตัวกรอง ขีดจำกัด การเรียงลำดับ การนับ ต่ำสุด สูงสุด ผลรวม การรวบรวม ฯลฯ ในทำนองเดียวกัน Streams ใช้การดำเนินการแบบ Lazy พวกเขาไม่ได้อ่านข้อมูลทั้งหมดจริง ๆ และไวยากรณ์ลูกโซ่จะสิ้นสุดลงเมื่อพบกับวิธีการเช่น getFirst() ในตัวอย่างต่อไปนี้ เราจะสำรวจว่า lambda และ Stream ทำอะไรได้บ้าง เราสร้างคลาส Person และใช้คลาสนี้เพื่อเพิ่มข้อมูลบางอย่างลงในรายการ ซึ่งจะใช้สำหรับการดำเนินการสตรีมเพิ่มเติม Person เป็นเพียงคลาส POJO ธรรมดา:
คัดลอกรหัสรหัสดังต่อไปนี้:
บุคคลในชั้นเรียนสาธารณะ {
สตริงส่วนตัว firstName, นามสกุล, งาน, เพศ;
เงินเดือน int เอกชน อายุ;
บุคคลสาธารณะ (ชื่อสตริง, นามสกุลสตริง, งานสตริง,
เพศสตริง อายุ int เงินเดือน int) {
this.firstName = ชื่อแรก;
this.lastName = นามสกุล;
this.gender = เพศ;
this.age = อายุ;
this.job = งาน;
this.salary = เงินเดือน;
-
// ทะเยอทะยานและเซตเตอร์
-
-
ต่อไป เราจะสร้างสองรายการ ซึ่งทั้งสองรายการใช้เพื่อจัดเก็บอ็อบเจ็กต์บุคคล:
คัดลอกรหัสรหัสดังต่อไปนี้:
รายการ<บุคคล> javaProgrammers = ใหม่ ArrayList<บุคคล>() {
-
เพิ่ม (บุคคลใหม่ ("Elsdon", "Jaycob", "โปรแกรมเมอร์ Java", "ชาย", 43, 2000));
เพิ่ม (บุคคลใหม่ ("Tamsen", "Brittany", "โปรแกรมเมอร์ Java", "หญิง", 23, 1500));
เพิ่ม (บุคคลใหม่ ("ฟลอยด์", "ดอนนี่", "โปรแกรมเมอร์ Java", "ชาย", 33, 1800));
เพิ่ม (บุคคลใหม่ ("ซินดี้", "โจนี่", "โปรแกรมเมอร์ Java", "หญิง", 32, 1600));
เพิ่ม (บุคคลใหม่ ("Vere", "Hervey", "โปรแกรมเมอร์ Java", "ชาย", 22, 1200));
เพิ่ม (บุคคลใหม่ ("ม้อด", "เจมี่", "โปรแกรมเมอร์ Java", "เพศหญิง", 27, 1900));
เพิ่ม (บุคคลใหม่ ("Shawn", "Randall", "โปรแกรมเมอร์ Java", "ชาย", 30, 2300));
เพิ่ม (บุคคลใหม่ ("Jayden", "Corrina", "โปรแกรมเมอร์ Java", "หญิง", 35, 1700));
เพิ่ม (บุคคลใหม่ ("พาลเมอร์", "Dene", "โปรแกรมเมอร์ Java", "ชาย", 33, 2000));
เพิ่ม (บุคคลใหม่ ("แอดดิสัน", "แพม", "โปรแกรมเมอร์ Java", "หญิง", 34, 1300));
-
-
รายการ <บุคคล> phpProgrammers = ใหม่ ArrayList<บุคคล>() {
-
เพิ่ม (บุคคลใหม่ ("Jarrod", "Pace", "โปรแกรมเมอร์ PHP", "ชาย", 34, 1550));
เพิ่ม (บุคคลใหม่ ("Clarette", "Cicely", "โปรแกรมเมอร์ PHP", "เพศหญิง", 23, 1200));
เพิ่ม (บุคคลใหม่ ("วิกเตอร์", "แชนนิ่ง", "โปรแกรมเมอร์ PHP", "ชาย", 32, 1600));
เพิ่ม (บุคคลใหม่ ("Tori", "Sheryl", "โปรแกรมเมอร์ PHP", "เพศหญิง", 21, 1,000));
เพิ่ม (บุคคลใหม่ ("ออสบอร์น", "แชด", "โปรแกรมเมอร์ PHP", "ชาย", 32, 1100));
เพิ่ม(คนใหม่("โรซาลินด์", "ไลลา", "โปรแกรมเมอร์ PHP", "หญิง", 25, 1300));
เพิ่ม (บุคคลใหม่ ("เฟรเซอร์", "ฮิววี่", "โปรแกรมเมอร์ PHP", "ชาย", 36, 1100));
เพิ่ม (บุคคลใหม่ ("ควินน์", "ทามารา", "โปรแกรมเมอร์ PHP", "หญิง", 21, 1,000));
เพิ่ม (บุคคลใหม่ ("อัลวิน", "แลนซ์", "โปรแกรมเมอร์ PHP", "ชาย", 38, 1600));
เพิ่ม (บุคคลใหม่ ("Evonne", "Shari", "โปรแกรมเมอร์ PHP", "หญิง", 40, 1800));
-
-
ตอนนี้เราใช้เมธอด forEach เพื่อวนซ้ำและส่งออกรายการด้านบน:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("ชื่อของโปรแกรมเมอร์ทั้งหมด:");
javaProgrammers.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
phpProgrammers.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
นอกจากนี้เรายังใช้วิธี forEach เพื่อเพิ่มเงินเดือนของโปรแกรมเมอร์ 5%:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("ให้โปรแกรมเมอร์ขึ้นเงินเดือน 5%:");
ผู้บริโภค<บุคคล> GiveRaise = e -> e.setSalary(e.getSalary() / 100 * 5 + e.getSalary());
javaProgrammers.forEach (giveRaise);
phpProgrammers.forEach(giveRaise);
อีกวิธีที่มีประโยชน์คือ filter() ซึ่งช่วยให้เราสามารถแสดงโปรแกรมเมอร์ PHP ที่มีเงินเดือนมากกว่า $1,400:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("นี่คือโปรแกรมเมอร์ PHP ที่มีเงินเดือนมากกว่า $1,400:")
phpProgrammers.stream()
.filter((p) -> (p.getSalary() > 1400))
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
นอกจากนี้เรายังสามารถกำหนดตัวกรองแล้วนำมาใช้ซ้ำเพื่อดำเนินการอื่น ๆ ได้:
คัดลอกรหัสรหัสดังต่อไปนี้:
// กำหนดตัวกรอง
ภาคแสดง<บุคคล> ageFilter = (p) -> (p.getAge() > 25);
ภาคแสดง <บุคคล> salaryFilter = (p) -> (p.getSalary() > 1400);
ภาคแสดง<บุคคล> genderFilter = (p) -> ("หญิง".เท่ากับ(p.getGender()));
System.out.println("นี่คือโปรแกรมเมอร์ PHP หญิงที่มีอายุมากกว่า 24 ปีและมีเงินเดือนมากกว่า $1,400:");
phpProgrammers.stream()
.filter(ตัวกรองอายุ)
.filter(salaryFilter)
.filter(genderFilter)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
//นำตัวกรองกลับมาใช้ใหม่
System.out.println("โปรแกรมเมอร์ Java หญิงที่มีอายุมากกว่า 24 ปี:");
javaProgrammers.stream ()
.filter(ตัวกรองอายุ)
.filter(genderFilter)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
ใช้วิธีจำกัดเพื่อจำกัดจำนวนชุดผลลัพธ์:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("โปรแกรมเมอร์ Java 3 ตัวแรก:");
javaProgrammers.stream ()
.จำกัด(3)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
System.out.println("โปรแกรมเมอร์ Java หญิง 3 อันดับแรก:");
javaProgrammers.stream ()
.filter(genderFilter)
.จำกัด(3)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
แล้วการเรียงลำดับล่ะ เราจะจัดการมันในสตรีมได้ไหม คำตอบคือใช่ ในตัวอย่างต่อไปนี้ เราจะจัดเรียงโปรแกรมเมอร์ Java ตามชื่อและเงินเดือน ใส่ลงในรายการ จากนั้นแสดงรายการ:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("จัดเรียงตามชื่อและแสดงโปรแกรมเมอร์ Java 5 อันดับแรก:");
รายการ <บุคคล> sortedJavaProgrammers = javaProgrammers
.ลำธาร()
.sorted((p, p2) -> (p.getFirstName().compareTo(p2.getFirstName())))
.จำกัด(5)
.collect(toList());
sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
System.out.println("จัดเรียงโปรแกรมเมอร์ Java ตามเงินเดือน:");
sortedJavaProgrammers = โปรแกรมเมอร์ java
.ลำธาร()
.sorted( (p, p2) -> (p.getSalary() - p2.getSalary()) )
.collect( toList() );
sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
หากเราสนใจเฉพาะเงินเดือนต่ำสุดและสูงสุด สิ่งที่เร็วกว่าการเลือกรายการแรก/รายการสุดท้ายหลังการเรียงลำดับคือวิธี min และ max:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("โปรแกรมเมอร์ Java ที่จ่ายเงินต่ำที่สุด:");
บุคคล per = javaProgrammers
.ลำธาร()
.min((p1, p2) -> (p1.getSalary() - p2.getSalary()))
.รับ()
System.out.printf("ชื่อ: %s %s; เงินเดือน: $%,d.", pers.getFirstName(), pers.getLastName(), pers.getSalary())
System.out.println("โปรแกรมเมอร์ Java ที่มีเงินเดือนสูงสุด:");
บุคคล คน = javaProgrammers
.ลำธาร()
.max((p, p2) -> (p.getSalary() - p2.getSalary()))
.รับ()
System.out.printf("ชื่อ: %s %s; เงินเดือน: $%,d.", person.getFirstName(), person.getLastName(), person.getSalary())
ในตัวอย่างข้างต้น เราได้เห็นว่าวิธีการรวบรวมทำงานอย่างไร ร่วมกับวิธีการ map เราสามารถใช้วิธีการรวบรวมเพื่อนำชุดผลลัพธ์ของเราไปไว้ใน String, Set หรือ TreeSet:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("เชื่อมชื่อแรกของโปรแกรมเมอร์ PHP เข้ากับสตริง:");
สตริง phpDevelopers = phpProgrammers
.ลำธาร()
.map(บุคคล::getFirstName)
.collect(joining(" ; ")); // สามารถใช้เป็นโทเค็นในการดำเนินการต่อไปได้
System.out.println("บันทึกชื่อโปรแกรมเมอร์ Java ไว้เป็น Set:");
ตั้งค่า<String> javaDevFirstName = javaProgrammers
.ลำธาร()
.map(บุคคล::getFirstName)
.collect(toSet());
System.out.println("บันทึกชื่อของโปรแกรมเมอร์ Java ไปที่ TreeSet:");
TreeSet<String> javaDevLastName = javaProgrammers
.ลำธาร()
.map(บุคคล::getLastName)
.collect(toCollection(TreeSet::new));
สตรีมยังสามารถขนานกันได้ ตัวอย่างมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
System.out.println("คำนวณเงินทั้งหมดที่จ่ายให้กับโปรแกรมเมอร์ Java:");
int TotalSalary = โปรแกรมเมอร์ Java
.parallelStream()
.mapToInt(p -> p.getSalary())
.รวม();
เราสามารถใช้เมธอด summaryStatistics เพื่อรับข้อมูลสรุปต่างๆ ขององค์ประกอบในสตรีมได้ ต่อไป เราสามารถเข้าถึงวิธีการเหล่านี้ เช่น getMax, getMin, getSum หรือ getAverage:
คัดลอกรหัสรหัสดังต่อไปนี้:
//คำนวณจำนวน ต่ำสุด สูงสุด ผลรวม และค่าเฉลี่ยสำหรับตัวเลข
รายการตัวเลข <จำนวนเต็ม> = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
สถิติ IntSummaryStatistics = ตัวเลข
.ลำธาร()
.mapToInt((x) -> x)
.สรุปสถิติ();
System.out.println("ตัวเลขที่ใหญ่ที่สุดในรายการ: " + stats.getMax());
System.out.println("จำนวนที่น้อยที่สุดในรายการ: " + stats.getMin());
System.out.println("ผลรวมของตัวเลขทั้งหมด: " + stats.getSum());
System.out.println("ค่าเฉลี่ยของตัวเลขทั้งหมด: " + stats.getAverage());
โอเค แค่นั้นแหละ หวังว่าคุณจะชอบมัน!
สรุป
ในบทความนี้ เราได้เรียนรู้วิธีต่างๆ ในการใช้นิพจน์ lambda ตั้งแต่ตัวอย่างพื้นฐานไปจนถึงตัวอย่างที่ซับซ้อนยิ่งขึ้นโดยใช้ lambda และ streams นอกจากนี้เรายังได้เรียนรู้วิธีใช้นิพจน์ lambda และคลาส Comparator เพื่อจัดเรียงคอลเลกชัน Java
หมายเหตุผู้แปล: แม้ว่าจะดูล้ำหน้ามาก แต่แก่นแท้ของนิพจน์ Lambda ก็เป็นเพียง "รูปแบบไวยากรณ์" ที่คอมไพเลอร์อนุมานได้ และช่วยให้คุณแปลงและรวมเป็นโค้ดปกติ ดังนั้น คุณจึงใช้โค้ดน้อยลงเพื่อให้ได้ฟังก์ชันเดียวกันได้ . ฉันขอแนะนำว่าอย่าใช้มันโดยไม่เลือกปฏิบัติ เพราะมันเหมือนกับโค้ดที่เขียนโดยแฮกเกอร์ขั้นสูงบางคน มันกระชับ เข้าใจยาก และแก้ไขจุดบกพร่องได้ยาก และเจ้าหน้าที่บำรุงรักษาจะต้องดุคุณ