Các SayHello
là một giao diện đơn Tóm tắt phương pháp trong đó có một phương pháp mà phải mất một chuỗi và trả về void. Điều này tương tự như một người tiêu dùng. Bạn chỉ đang cung cấp một triển khai phương thức đó dưới dạng một người tiêu dùng tương tự như việc triển khai lớp bên trong ẩn danh sau đây.
SayHello sh = new SayHello() {
@Override
public void speak(String message) {
System.out.println("Hello " + message);
}
};
names.forEach(n -> sh.speak(n));
May mắn thay, giao diện của bạn có một phương thức duy nhất sao cho hệ thống loại (chính thức hơn là thuật toán phân giải loại) có thể suy ra kiểu của nó là SayHello
. Nhưng nếu nó có 2 phương pháp trở lên, điều này sẽ không thể thực hiện được.
Tuy nhiên, một cách tiếp cận tốt hơn nhiều là khai báo người tiêu dùng trước vòng lặp for và sử dụng nó như hiển thị bên dưới. Tuyên bố việc thực hiện cho mỗi lần lặp lại tạo ra nhiều đối tượng hơn mức cần thiết và dường như phản trực giác với tôi. Đây là phiên bản nâng cao sử dụng tham chiếu phương thức thay vì lambda. Tham chiếu phương thức giới hạn được sử dụng ở đây gọi phương thức có liên quan trên hello
thể hiện được khai báo ở trên.
SayHello hello = message -> System.out.println("Hello " + message);
names.forEach(hello::speak);
Cập nhật
Cho rằng đối với lambdas không trạng thái không nắm bắt được bất cứ điều gì từ phạm vi từ vựng của chúng chỉ một lần sẽ được tạo ra, cả hai cách tiếp cận chỉ tạo ra một thể hiện của SayHello
, và không có bất kỳ lợi ích nào theo cách tiếp cận được đề xuất. Tuy nhiên, đây dường như là một chi tiết triển khai và tôi đã không biết đến nó cho đến bây giờ. Vì vậy, một cách tiếp cận tốt hơn nhiều chỉ là chuyển người tiêu dùng đến forEach của bạn như được đề xuất trong bình luận bên dưới. Cũng lưu ý rằng tất cả các cách tiếp cận này chỉ tạo ra một phiên bản của SayHello
giao diện của bạn trong khi cách tiếp cận cuối cùng ngắn gọn hơn. Đây là vẻ ngoài của nó.
names.forEach(message -> System.out.println("Hello " + message));
Đây câu trả lời sẽ cung cấp cho bạn cái nhìn sâu sắc hơn về điều đó. Đây là phần có liên quan từ JLS §15.27.4 : Đánh giá thời gian thực của biểu thức Lambda
Các quy tắc này nhằm cung cấp tính linh hoạt cho việc triển khai ngôn ngữ lập trình Java, theo đó:
- Một đối tượng mới không cần phải được phân bổ trên mỗi đánh giá.
Trong thực tế, ban đầu tôi nghĩ mọi đánh giá đều tạo ra một trường hợp mới, đó là sai. @Holger cảm ơn đã chỉ ra rằng, bắt tốt.