2016-04-20 22 views
5

Tôi đã có một giao diện như:Java thực hiện phương pháp trên tất cả các đối tượng trong một danh sách

public interface Listener { 
    void onA(); 
    void onB(); 
    void onC(); 
} 

Và có một danh sách các thính giả/nhà quan sát:

List<Listener> listeners = new ArrayList<Listener>(); 

Làm thế nào tôi có thể dễ dàng thông báo cho tất cả người nghe, mà A, B, C đã xảy ra qua Listener.onA(), Listener.onB(), Listener.onC()?

Tôi có phải sao chép-dán lặp lại trên tất cả người nghe ít nhất ba lần không?

Trong C++ tôi sẽ tạo ra một chức năng như:

void Notify(const std::function<void(Listener *listener)> &command) { 
    for(auto &listener : listeners) { 
    command(listener); 
    } 
} 

Và vượt qua lambda cho mỗi phương pháp:

Notify([](Listener *listener) {listener->onA();}); 

hoặc

Notify([](Listener *listener) {listener->onB();}); 

hoặc

Notify([](Listener *listener) {listener->onC();}); 

Có cách tiếp cận tương tự trong Java không?

Trả lời

6

Trong Java 8, có:

listeners.forEach(listener -> listener.onA()); 

hay:

listeners.forEach(Listener::onA); 

Lưu ý rằng có một loạt các hoạt động chức năng lập trình theo phong cách khác có thể được thực hiện với các hàm lambda, nhưng hầu hết trong số họ sẽ yêu cầu trước tiên bạn tạo luồng từ bộ sưu tập của mình bằng cách gọi .stream() trên đó. forEach(), như tôi đã học được từ các ý kiến, là một ngoại lệ cho điều này.

+3

Bạn không cần phải 'dòng'. 'List' có phương thức' forEach' trực tiếp trên nó – tddmonkey

+0

Chỉ đơn giản là 'foreach' mà không có' stream' –

+1

@tddmonkey và Yassin Hajaj: Cảm ơn; Tôi không biết điều đó. –

1

Nếu phiên bản java của bạn không cho phép một Lambdas sau đó làm:

List<Listener> l = ... 
for (Listener myListeners : listenersList) { 
    myListeners.onA(); 
    myListeners.onB(); 
    myListeners.onC(); 
} 
Các vấn đề liên quan