Javascript foreach lambda

Một vấn đề với các lớp ẩn danh là nếu việc triển khai lớp ẩn danh của bạn rất đơn giản, chẳng hạn như một giao diện chỉ chứa một phương thức, thì cú pháp của các lớp ẩn danh có vẻ khó sử dụng và không rõ ràng. Trong những trường hợp này, bạn thường cố gắng chuyển chức năng làm đối số sang phương thức khác, chẳng hạn như hành động nào sẽ được thực hiện khi ai đó nhấp vào nút. Biểu thức lambda cho phép bạn làm điều này, để coi chức năng là đối số của phương thức hoặc mã là dữ liệu

Phần trước, Các lớp ẩn danh, chỉ cho bạn cách triển khai một lớp cơ sở mà không cần đặt tên cho nó. Mặc dù điều này thường ngắn gọn hơn so với lớp được đặt tên, nhưng đối với các lớp chỉ có một phương thức, ngay cả một lớp ẩn danh cũng có vẻ hơi thừa và rườm rà. Các biểu thức lambda cho phép bạn thể hiện các thể hiện của các lớp một phương thức một cách gọn gàng hơn

Phần này bao gồm các chủ đề sau

Giả sử rằng bạn đang tạo một ứng dụng mạng xã hội. Bạn muốn tạo một tính năng cho phép quản trị viên thực hiện bất kỳ loại hành động nào, chẳng hạn như gửi tin nhắn, đối với các thành viên của ứng dụng mạng xã hội đáp ứng các tiêu chí nhất định. Bảng sau mô tả chi tiết trường hợp sử dụng này

TrườngMô tảTênThực hiện hành động đối với các thành viên được chọn. Diễn viên chínhQuản trị viênĐiều kiện tiên quyếtQuản trị viên đã đăng nhập vào hệ thống. Hậu điều kiệnHành động chỉ được thực hiện trên các thành viên phù hợp với tiêu chí đã chỉ định. Kịch bản thành công chính
  1. Quản trị viên chỉ định tiêu chí của các thành viên để thực hiện một hành động nhất định
  2. Quản trị viên chỉ định một hành động để thực hiện trên những thành viên được chọn
  3. Quản trị viên chọn nút Gửi
  4. Hệ thống tìm tất cả các thành viên phù hợp với các tiêu chí được chỉ định
  5. Hệ thống thực hiện hành động được chỉ định trên tất cả các thành viên phù hợp
Tiện ích mở rộng

1a. Quản trị viên có tùy chọn xem trước những thành viên phù hợp với tiêu chí đã chỉ định trước khi chỉ định hành động sẽ được thực hiện hoặc trước khi chọn nút Gửi

Tần suất xuất hiện Nhiều lần trong ngày

Giả sử rằng các thành viên của ứng dụng mạng xã hội này được đại diện bởi lớp

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 sau

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}

Giả sử rằng các thành viên của ứng dụng mạng xã hội của bạn được lưu trữ trong một thực thể

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
9

Phần này bắt đầu với một cách tiếp cận ngây thơ đối với trường hợp sử dụng này. Nó cải thiện cách tiếp cận này với các lớp ẩn danh và cục bộ, sau đó kết thúc bằng cách tiếp cận ngắn gọn và hiệu quả bằng cách sử dụng các biểu thức lambda. Tìm các đoạn mã được mô tả trong phần này trong ví dụ

interface CheckPerson {
    boolean test(Person p);
}
0

Một cách tiếp cận đơn giản là tạo ra một số phương thức; . Phương pháp sau đây in các thành viên lớn hơn một độ tuổi được chỉ định

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}

Ghi chú. Một

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
9 là một
interface CheckPerson {
    boolean test(Person p);
}
2 có thứ tự. Một bộ sưu tập là một đối tượng nhóm nhiều phần tử thành một đơn vị. Bộ sưu tập được sử dụng để lưu trữ, truy xuất, thao tác và truyền đạt dữ liệu tổng hợp. Để biết thêm thông tin về các bộ sưu tập, hãy xem Đường mòn bộ sưu tập

Cách tiếp cận này có khả năng làm cho ứng dụng của bạn trở nên giòn, có khả năng ứng dụng không hoạt động do giới thiệu các bản cập nhật (chẳng hạn như các loại dữ liệu mới hơn). Giả sử rằng bạn nâng cấp ứng dụng của mình và thay đổi cấu trúc của lớp

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 sao cho nó chứa các biến thành viên khác nhau; . Bạn sẽ phải viết lại rất nhiều API của mình để phù hợp với thay đổi này. Ngoài ra, cách tiếp cận này là hạn chế không cần thiết;

Phương pháp sau đây chung chung hơn

interface CheckPerson {
    boolean test(Person p);
}
4;

public static void printPersonsWithinAgeRange(
    List roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
    }
}

What if you want to print members of a specified sex, or a combination of a specified gender and age range? What if you decide to change the

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 class and add other attributes such as relationship status or geographical location? Although this method is more generic than
interface CheckPerson {
    boolean test(Person p);
}
4, trying to create a separate method for each possible search query can still lead to brittle code. Thay vào đó, bạn có thể tách mã chỉ định tiêu chí mà bạn muốn tìm kiếm trong một lớp khác

Phương pháp sau đây in các thành viên phù hợp với tiêu chí tìm kiếm mà bạn chỉ định

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}

Phương thức này kiểm tra từng trường hợp

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 có trong tham số
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
9
interface CheckPerson {
    boolean test(Person p);
}
9 xem nó có thỏa mãn tiêu chí tìm kiếm được chỉ định trong tham số
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
61 hay không bằng cách gọi phương thức
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
62. Nếu phương thức
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
62 trả về giá trị
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
64, thì phương thức
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
65 được gọi trong trường hợp
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8

Để chỉ định tiêu chí tìm kiếm, bạn triển khai giao diện

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60

interface CheckPerson {
    boolean test(Person p);
}

Lớp sau triển khai giao diện

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60 bằng cách chỉ định triển khai cho phương thức
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
69. Phương pháp này lọc các thành viên đủ điều kiện tham gia Dịch vụ Chọn lọc tại Hoa Kỳ. nó trả về giá trị
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
64 nếu tham số
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 của nó là nam và trong độ tuổi từ 18 đến 25

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
6

Để sử dụng lớp này, bạn tạo một thể hiện mới của nó và gọi phương thức

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
65

interface CheckPerson {
    boolean test(Person p);
}
1

Mặc dù cách tiếp cận này ít dễ vỡ hơn—bạn không phải viết lại các phương thức nếu bạn thay đổi cấu trúc của

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8—bạn vẫn có mã bổ sung. một giao diện mới và một lớp cục bộ cho mỗi tìm kiếm bạn định thực hiện trong ứng dụng của mình. Bởi vì
interface CheckPerson {
    boolean test(Person p);
}
14 triển khai một giao diện, bạn có thể sử dụng một lớp ẩn danh thay vì một lớp cục bộ và bỏ qua nhu cầu khai báo một lớp mới cho mỗi lần tìm kiếm

Một trong những đối số của lời gọi sau đây của phương thức

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
65 là một lớp ẩn danh lọc các thành viên đủ điều kiện tham gia Dịch vụ Chọn lọc tại Hoa Kỳ. những người là nam và trong độ tuổi từ 18 đến 25

interface CheckPerson {
    boolean test(Person p);
}
5

Cách tiếp cận này giảm số lượng mã cần thiết vì bạn không phải tạo một lớp mới cho mỗi tìm kiếm mà bạn muốn thực hiện. Tuy nhiên, cú pháp của các lớp ẩn danh là cồng kềnh vì giao diện

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60 chỉ chứa một phương thức. Trong trường hợp này, bạn có thể sử dụng biểu thức lambda thay vì lớp ẩn danh, như được mô tả trong phần tiếp theo

Giao diện

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60 là giao diện chức năng. Giao diện chức năng là bất kỳ giao diện nào chỉ chứa một phương thức trừu tượng. (Một giao diện chức năng có thể chứa một hoặc nhiều phương thức mặc định hoặc phương thức tĩnh. ) Vì giao diện chức năng chỉ chứa một phương thức trừu tượng, bạn có thể bỏ qua tên của phương thức đó khi triển khai nó. Để làm điều này, thay vì sử dụng một biểu thức lớp ẩn danh, bạn sử dụng một biểu thức lambda, được đánh dấu trong lời gọi phương thức sau

interface CheckPerson {
    boolean test(Person p);
}
8

Xem Cú pháp biểu thức Lambda để biết thông tin về cách xác định biểu thức lambda

Bạn có thể sử dụng giao diện chức năng tiêu chuẩn thay cho giao diện

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60, giúp giảm hơn nữa số lượng mã cần thiết

Xem xét lại giao diện

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60

interface CheckPerson {
    boolean test(Person p);
}

Đây là một giao diện rất đơn giản. Đó là một giao diện chức năng vì nó chỉ chứa một phương thức trừu tượng. Phương thức này nhận một tham số và trả về giá trị

interface CheckPerson {
    boolean test(Person p);
}
50. Phương pháp này đơn giản đến mức có thể không đáng để xác định một phương pháp trong ứng dụng của bạn. Do đó, JDK xác định một số giao diện chức năng tiêu chuẩn mà bạn có thể tìm thấy trong gói
interface CheckPerson {
    boolean test(Person p);
}
51

Ví dụ: bạn có thể sử dụng giao diện

interface CheckPerson {
    boolean test(Person p);
}
52 thay cho
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60. Giao diện này chứa phương thức
interface CheckPerson {
    boolean test(Person p);
}
54

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
0

Giao diện

interface CheckPerson {
    boolean test(Person p);
}
52 là một ví dụ về giao diện chung. (Để biết thêm thông tin về thuốc gốc, hãy xem bài học Thuốc gốc (Đã cập nhật). ) Loại chung (chẳng hạn như giao diện chung) chỉ định một hoặc nhiều tham số loại trong dấu ngoặc nhọn (
interface CheckPerson {
    boolean test(Person p);
}
56). Giao diện này chỉ chứa một tham số loại,
interface CheckPerson {
    boolean test(Person p);
}
57. Khi bạn khai báo hoặc khởi tạo một kiểu chung với các đối số kiểu thực, bạn có một kiểu được tham số hóa. Ví dụ: loại tham số hóa
interface CheckPerson {
    boolean test(Person p);
}
52 như sau

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
1

Kiểu được tham số hóa này chứa một phương thức có cùng kiểu trả về và các tham số như

interface CheckPerson {
    boolean test(Person p);
}
59. Do đó, bạn có thể sử dụng
interface CheckPerson {
    boolean test(Person p);
}
52 thay cho
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60 như phương pháp sau minh họa

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
2

Kết quả là, lời gọi phương thức sau giống như khi bạn gọi

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
65 trong Cách tiếp cận 3. Chỉ định Mã tiêu chí tìm kiếm trong Lớp địa phương để có được các thành viên đủ điều kiện cho Dịch vụ chọn lọc

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
3

Đây không phải là nơi duy nhất có thể sử dụng biểu thức lambda trong phương pháp này. Cách tiếp cận sau gợi ý các cách khác để sử dụng biểu thức lambda

Xem xét lại phương thức

interface CheckPerson {
    boolean test(Person p);
}
83 để xem bạn có thể sử dụng biểu thức lambda ở đâu khác

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
2

Phương thức này kiểm tra từng phiên bản

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 có trong tham số
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
9
interface CheckPerson {
    boolean test(Person p);
}
9 xem nó có thỏa mãn các tiêu chí được chỉ định trong tham số
interface CheckPerson {
    boolean test(Person p);
}
52
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
61 hay không. Nếu phiên bản
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 đáp ứng các tiêu chí được chỉ định bởi
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
61, thì phương thức
interface CheckPerson {
    boolean test(Person p);
}
1 được gọi trên phiên bản
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8

Thay vì gọi phương thức

interface CheckPerson {
    boolean test(Person p);
}
1, bạn có thể chỉ định một hành động khác để thực hiện trên các phiên bản
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 đó đáp ứng các tiêu chí được chỉ định bởi
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
61. Bạn có thể chỉ định hành động này bằng biểu thức lambda. Giả sử bạn muốn một biểu thức lambda tương tự như
interface CheckPerson {
    boolean test(Person p);
}
1, một biểu thức nhận một đối số (một đối tượng thuộc loại
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8) và trả về void. Hãy nhớ rằng, để sử dụng biểu thức lambda, bạn cần triển khai giao diện chức năng. Trong trường hợp này, bạn cần một giao diện chức năng chứa một phương thức trừu tượng có thể nhận một đối số kiểu
public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
8 và trả về void. Giao diện
interface CheckPerson {
    boolean test(Person p);
}
9 chứa phương thức
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
00, có các đặc điểm này. Phương thức sau thay thế lời gọi
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
01 bằng một thể hiện của
interface CheckPerson {
    boolean test(Person p);
}
9 gọi phương thức
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
03

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
5

Kết quả là, lời gọi phương thức sau giống như khi bạn gọi

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
65 trong Cách tiếp cận 3. Chỉ định Mã tiêu chí tìm kiếm trong Lớp địa phương để có được các thành viên đủ điều kiện cho Dịch vụ chọn lọc. Biểu thức lambda được sử dụng để in các thành viên được tô sáng

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
6

Điều gì sẽ xảy ra nếu bạn muốn làm nhiều việc hơn với hồ sơ thành viên của mình hơn là in chúng ra. Giả sử bạn muốn xác thực hồ sơ của các thành viên hoặc truy xuất thông tin liên hệ của họ? . Giao diện

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
05 chứa phương thức
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
06. Phương thức sau truy xuất dữ liệu được chỉ định bởi tham số
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
07, sau đó thực hiện một hành động trên dữ liệu được chỉ định bởi tham số
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
08

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
7

Phương pháp sau lấy địa chỉ email từ mỗi thành viên có trong

interface CheckPerson {
    boolean test(Person p);
}
9 đủ điều kiện cho Dịch vụ Chọn lọc và sau đó in nó

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
8

Xem xét lại phương pháp

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
10. Sau đây là phiên bản chung của nó chấp nhận, như một tham số, một bộ sưu tập chứa các phần tử của bất kỳ kiểu dữ liệu nào

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
9

Để in địa chỉ e-mail của các thành viên đủ điều kiện tham gia Dịch vụ Chọn lọc, hãy gọi phương thức

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
11 như sau

public static void printPersonsWithinAgeRange(
    List roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
    }
}
0

Lời gọi phương thức này thực hiện các hành động sau

  1. Lấy nguồn đối tượng từ bộ sưu tập
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    12. Trong ví dụ này, nó lấy một nguồn gồm các đối tượng
    public static void printPersons(
        List roster, CheckPerson tester) {
        for (Person p : roster) {
            if (tester.test(p)) {
                p.printPerson();
            }
        }
    }
    8 từ bộ sưu tập
    interface CheckPerson {
        boolean test(Person p);
    }
    9. Lưu ý rằng bộ sưu tập
    interface CheckPerson {
        boolean test(Person p);
    }
    9, là một bộ sưu tập kiểu
    public static void printPersons(
        List roster, CheckPerson tester) {
        for (Person p : roster) {
            if (tester.test(p)) {
                p.printPerson();
            }
        }
    }
    9, cũng là một đối tượng kiểu
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    17
  2. Lọc các đối tượng phù hợp với đối tượng
    interface CheckPerson {
        boolean test(Person p);
    }
    52
    public class Person {
    
        public enum Sex {
            MALE, FEMALE
        }
    
        String name;
        LocalDate birthday;
        Sex gender;
        String emailAddress;
    
        public int getAge() {
            // ...
        }
    
        public void printPerson() {
            // ...
        }
    }
    61. Trong ví dụ này, đối tượng
    interface CheckPerson {
        boolean test(Person p);
    }
    52 là một biểu thức lambda chỉ định thành viên nào sẽ đủ điều kiện tham gia Dịch vụ Chọn lọc
  3. Ánh xạ từng đối tượng được lọc thành một giá trị như được chỉ định bởi đối tượng
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    05
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    07. Trong ví dụ này, đối tượng
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    05 là một biểu thức lambda trả về địa chỉ e-mail của một thành viên
  4. Thực hiện một hành động trên từng đối tượng được ánh xạ như được chỉ định bởi đối tượng
    interface CheckPerson {
        boolean test(Person p);
    }
    9
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    08. Trong ví dụ này, đối tượng
    interface CheckPerson {
        boolean test(Person p);
    }
    9 là một biểu thức lambda in ra một chuỗi, là địa chỉ email được trả về bởi đối tượng
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    05

Bạn có thể thay thế từng thao tác này bằng một thao tác tổng hợp

Ví dụ sau sử dụng các thao tác tổng hợp để in địa chỉ e-mail của những thành viên có trong bộ sưu tập

interface CheckPerson {
    boolean test(Person p);
}
9 đủ điều kiện tham gia Dịch vụ Chọn lọc

public static void printPersonsWithinAgeRange(
    List roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
    }
}
1

Bảng sau đây ánh xạ từng thao tác mà phương thức

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
11 thực hiện với thao tác tổng hợp tương ứng

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
11 ActionAggregate OperationObtain a source of objects
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
31Filter objects that match a
interface CheckPerson {
    boolean test(Person p);
}
52 object
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
33Map objects to another value as specified by a
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
05 object
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
35Perform an action as specified by a
interface CheckPerson {
    boolean test(Person p);
}
9 object
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
37

Các hoạt động

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
38,
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
39 và
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
40 là các hoạt động tổng hợp. Các hoạt động tổng hợp xử lý các phần tử từ một luồng chứ không phải trực tiếp từ một tập hợp (đó là lý do tại sao phương thức đầu tiên được gọi trong ví dụ này là
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
41). Luồng là một dãy các phần tử. Không giống như một bộ sưu tập, nó không phải là một cấu trúc dữ liệu lưu trữ các phần tử. Thay vào đó, một luồng mang các giá trị từ một nguồn, chẳng hạn như bộ sưu tập, thông qua một đường dẫn. Đường ống là một chuỗi các hoạt động truyền phát, trong ví dụ này là
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
38-
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
39-
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
40. Ngoài ra, các hoạt động tổng hợp thường chấp nhận các biểu thức lambda làm tham số, cho phép bạn tùy chỉnh cách chúng hoạt động

Để thảo luận kỹ hơn về các phép toán tổng hợp, hãy xem bài học Các phép toán tổng hợp

Để xử lý các sự kiện trong ứng dụng giao diện người dùng đồ họa (GUI), chẳng hạn như thao tác bàn phím, thao tác chuột và thao tác cuộn, bạn thường tạo trình xử lý sự kiện, thường liên quan đến việc triển khai một giao diện cụ thể. Thông thường, giao diện xử lý sự kiện là giao diện chức năng;

Trong ví dụ JavaFX

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
45 (đã thảo luận trong phần trước Lớp ẩn danh), bạn có thể thay thế lớp ẩn danh được đánh dấu bằng biểu thức lambda trong câu lệnh này

public static void printPersonsWithinAgeRange(
    List roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
    }
}
2

Lời gọi phương thức

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
46 chỉ định điều gì sẽ xảy ra khi bạn chọn nút được đại diện bởi đối tượng
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
47. Phương thức này yêu cầu một đối tượng kiểu
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
48. Giao diện
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
48 chỉ chứa một phương thức,
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
50. Giao diện này là một giao diện chức năng, vì vậy bạn có thể sử dụng biểu thức lambda được đánh dấu sau đây để thay thế nó

public static void printPersonsWithinAgeRange(
    List roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
    }
}
3

Một biểu thức lambda bao gồm những điều sau đây

  • Một danh sách các tham số chính thức được phân tách bằng dấu phẩy được đặt trong dấu ngoặc đơn. Phương thức

    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    51 chứa một tham số,
    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    52, đại diện cho một thể hiện của lớp
    public static void printPersons(
        List roster, CheckPerson tester) {
        for (Person p : roster) {
            if (tester.test(p)) {
                p.printPerson();
            }
        }
    }
    8

    Ghi chú. Bạn có thể bỏ qua kiểu dữ liệu của tham số trong biểu thức lambda. Ngoài ra, bạn có thể bỏ dấu ngoặc đơn nếu chỉ có một tham số. Ví dụ: biểu thức lambda sau cũng hợp lệ

    public static void printPersonsWithinAgeRange(
        List roster, int low, int high) {
        for (Person p : roster) {
            if (low <= p.getAge() && p.getAge() < high) {
                p.printPerson();
            }
        }
    }
    4
  • Mã thông báo mũi tên,

    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    54

  • Một phần thân, bao gồm một biểu thức hoặc một khối câu lệnh. Ví dụ này sử dụng biểu thức sau

    public static void printPersonsWithinAgeRange(
        List roster, int low, int high) {
        for (Person p : roster) {
            if (low <= p.getAge() && p.getAge() < high) {
                p.printPerson();
            }
        }
    }
    5

    Nếu bạn chỉ định một biểu thức, thì bộ thực thi Java sẽ đánh giá biểu thức đó rồi trả về giá trị của nó. Ngoài ra, bạn có thể sử dụng câu lệnh return

    public static void printPersonsWithinAgeRange(
        List roster, int low, int high) {
        for (Person p : roster) {
            if (low <= p.getAge() && p.getAge() < high) {
                p.printPerson();
            }
        }
    }
    6

    Câu lệnh return không phải là một biểu thức; . Tuy nhiên, bạn không cần phải đặt lời gọi phương thức void trong dấu ngoặc nhọn. Ví dụ: sau đây là biểu thức lambda hợp lệ

    public static void printPersonsWithinAgeRange(
        List roster, int low, int high) {
        for (Person p : roster) {
            if (low <= p.getAge() && p.getAge() < high) {
                p.printPerson();
            }
        }
    }
    7

Lưu ý rằng một biểu thức lambda trông rất giống một khai báo phương thức;

Ví dụ sau,

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
56, là một ví dụ về biểu thức lambda nhận nhiều hơn một tham số hình thức

public static void printPersonsWithinAgeRange(
    List roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
    }
}
8

Phương thức

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
57 thực hiện phép toán trên hai toán hạng số nguyên. Bản thân hoạt động được chỉ định bởi một phiên bản của
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
58. Ví dụ định nghĩa hai thao tác với biểu thức lambda,
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
59 và
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
60. Ví dụ in như sau

public static void printPersonsWithinAgeRange(
    List roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
    }
}
9

Giống như các lớp ẩn danh và cục bộ, các biểu thức lambda có thể nắm bắt các biến; . Tuy nhiên, không giống như các lớp ẩn danh và cục bộ, các biểu thức lambda không có bất kỳ vấn đề về đổ bóng nào (xem phần Đổ bóng để biết thêm thông tin). Biểu thức lambda có phạm vi từ vựng. Điều này có nghĩa là chúng không kế thừa bất kỳ tên nào từ siêu kiểu hoặc giới thiệu một cấp phạm vi mới. Declarations in a lambda expression are interpreted just as they are in the enclosing environment. Ví dụ sau đây,

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
61, chứng minh điều này

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
0

Ví dụ này tạo ra đầu ra sau

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
1

Nếu bạn thay thế tham số

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
62 ở vị trí của
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
63 trong phần khai báo của biểu thức lambda
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
64, thì trình biên dịch sẽ tạo ra lỗi

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
2

Trình biên dịch tạo ra lỗi "Tham số x của biểu thức Lambda không thể khai báo lại một biến cục bộ khác được xác định trong phạm vi kèm theo" vì biểu thức lambda không đưa ra mức phạm vi mới. Do đó, bạn có thể truy cập trực tiếp các trường, phương thức và biến cục bộ của phạm vi kèm theo. Ví dụ: biểu thức lambda truy cập trực tiếp tham số

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
62 của phương thức
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
66. Để truy cập các biến trong lớp kèm theo, hãy sử dụng từ khóa
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
67. Trong ví dụ này,
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
68 đề cập đến biến thành viên
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
69

Tuy nhiên, giống như các lớp ẩn danh và cục bộ, biểu thức lambda chỉ có thể truy cập các biến cục bộ và tham số của khối kèm theo là cuối cùng hoặc có hiệu lực cuối cùng. Trong ví dụ này, biến

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
70 có hiệu lực cuối cùng; . Tuy nhiên, giả sử rằng bạn thêm câu lệnh gán sau vào biểu thức lambda
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
64

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
3

Do câu lệnh gán này, biến

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
70 không còn là giá trị cuối cùng nữa. Do đó, trình biên dịch Java tạo ra một thông báo lỗi tương tự như "Biến cục bộ z được xác định trong phạm vi kèm theo phải là cuối cùng hoặc có hiệu lực cuối cùng"

Làm cách nào để bạn xác định loại biểu thức lambda?

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
4

Biểu thức lambda này đã được sử dụng trong hai phương thức sau

Khi thời gian chạy Java gọi phương thức

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
65, nó sẽ mong đợi một loại dữ liệu là
public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}
60, vì vậy biểu thức lambda thuộc loại này. Tuy nhiên, khi thời gian chạy Java gọi phương thức
interface CheckPerson {
    boolean test(Person p);
}
83, nó sẽ mong đợi một loại dữ liệu là
interface CheckPerson {
    boolean test(Person p);
}
52, vì vậy biểu thức lambda thuộc loại này. Kiểu dữ liệu mà các phương thức này mong đợi được gọi là kiểu đích. Để xác định loại biểu thức lambda, trình biên dịch Java sử dụng loại mục tiêu của ngữ cảnh hoặc tình huống trong đó biểu thức lambda được tìm thấy. Theo đó, bạn chỉ có thể sử dụng các biểu thức lambda trong các tình huống mà trình biên dịch Java có thể xác định loại mục tiêu

  • khai báo biến

  • bài tập

  • Báo cáo trả về

  • Bộ khởi tạo mảng

  • Đối số phương thức hoặc hàm tạo

  • nội dung biểu thức lambda

  • Biểu thức điều kiện,

    public static void printPersonsOlderThan(List roster, int age) {
        for (Person p : roster) {
            if (p.getAge() >= age) {
                p.printPerson();
            }
        }
    }
    77

  • Truyền biểu thức

Đối với các đối số phương thức, trình biên dịch Java xác định loại mục tiêu với hai tính năng ngôn ngữ khác. overload resolution and type argument inference

Xem xét hai giao diện chức năng sau (

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
78 và
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
79)

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
5

Phương thức

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
80 không trả về giá trị, trong khi đó
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
81 thì không

Giả sử rằng bạn đã nạp chồng phương thức

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
82 như sau (xem Xác định phương thức để biết thêm thông tin về các phương thức nạp chồng)

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
6

Phương thức nào sẽ được gọi trong câu lệnh sau?

public static void printPersons(
    List roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
7

Phương thức

public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
83 sẽ được gọi vì phương thức đó trả về một giá trị; . Trong trường hợp này, loại biểu thức lambda
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
85 là
public static void printPersonsOlderThan(List roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
86

Bạn có thể tuần tự hóa một biểu thức lambda nếu loại mục tiêu và các đối số đã bắt của nó có thể tuần tự hóa được. Tuy nhiên, giống như các lớp bên trong, việc tuần tự hóa các biểu thức lambda không được khuyến khích