2017-02-09 3 views
4

Java 8はlambda expressionsを導入しました。これは素晴らしいことです。しかし、今、このコードの書き換えを検討:ラムダ式とメソッド参照してリスナーとして使用されるラムダ式/メソッドハンドルを削除するにはどうすればよいですか?

class B implements PropertyChangeListener { 
    void listenToA(A a) { 
     a.addPropertyChangeListener(this); 
    } 

    void propertyChange(PropertyChangeEvent evt) { 
     switch(evt.getPropertyName()) { 
      case "Property1": 
       doSomething(); 
       break; 
      case "Property2": 
       doSomethingElse();    case "Property1": 
       doSomething; 
       break; 

       break; 
    } 

    void doSomething() { } 
    void doSomethingElse() { } 
} 

class A { 
    final PropertyChangeSupport pcs = new PropertyChangeSupport(this); 

    void addPropertyChangeListener(PropertyChangeListener listener) { 
     pcs.addPropertyChangeListener(listener); 
    } 

    void removePropertyChangeListener(PropertyChangeListener listener) { 
     pcs.removePropertyChangeListener(listener); 
    } 
} 

を、我々が

class B { 
    void listenToA(A a) { 
     // using method reference 
     a.addPropertyChangeListener("Property1", this::doSomething); 
     // using lambda expression 
     a.addPropertyChangeListener("Property2", e -> doSomethingElse()); 
    } 

    void doSomething(PropertyChangeEvent evt) { } 
    void doSomethingElse() { } 
} 

class A { 
    final PropertyChangeSupport pcs = new PropertyChangeSupport(this); 

    void addPropertyChangeListener(String name, PropertyChangeListener listener) { 
     pcs.addPropertyChangeListener(name, listener); 
    } 

    void removePropertyChangeListener(String name, PropertyChangeListener listener) { 
     pcs.removePropertyChangeListener(name, listener); 
    } 
} 

を書くことができるようB私は新しいコードがないだけだと思う​​PropertyChangeListnerを実装持っているもう必要ありません短くて洗練され、理解しやすい。しかし、here(重複thisの回答)を読んだ後で、質問と回答がより鮮明であると私は思っています。stopListening()というメソッドを実装する方法はありません。

私はこれにつまずく最初の人ではないと確信しています。だから誰もこの例に示すようにメソッドハンドルを使用し、後でリスナーを後で取り除くことができる方法について素晴らしい解決策を見つけましたか?速かった

UPDATE

class B { 
    void listenToA(A a) { 
     a.addPropertyChangeListener("Property1", doSomething); 
     a.addPropertyChangeListener("Property2", doSomethingElse); 
    } 

    final PropertyChangeListener doSomething = evt -> {}; 
    final PropertyChangeListener doSomethingElse = evt -> {}; 
} 
+0

。メソッドを宣言する代わりに、関数オブジェクト(ラムダ式)を宣言します。これは、いくつかのユースケースでは有用な戦略です。 – ZhongYu

+0

しかし、機能(つまり、機能オブジェクト)が静的(この場合は「はい」)であるかどうかについて考えてください。すべてのオブジェクトに独自の関数のインスタンスがある場合は、メモリが浪費される可能性があります。 – ZhongYu

+0

@中文ありがとうございます。しかし、リスナーは自分が属している 'B'インスタンスで何かをしなければならないので、自分のプログラムで静的にすることはできません。 – Axel

答えて

6

次のようにあなたのリスナーを宣言することができます:

private final PropertyChangeListener myProperty1Listener = this::doSomething; 
private final PropertyChangeListener myProperty2Listener = e -> doSomethingElse()); 

を、あなたは自分のリスナーを追加することができ、:

マイクNaklisとウナギのホバークラフトのフルによって回答に構築、私はこれで終わりました
// using method reference 
a.addPropertyChangeListener("Property1", myProperty1Listener); 
// using lambda expression 
a.addPropertyChangeListener("Property2", myProperty2Listener); 

、あなたはそれらを削除することができます

a.removePropertyChangeListener("Property1", myProperty1Listener); 
a.removePropertyChangeListener("Property2", myProperty2Listener); 
+1

あなたは私が(1+) –

1

ラムダを使用しても変数を使用できます。たとえば、次のような場合:

class B { 
    private PropertyChangeListener listener1 = this::doSomething; 
    private PropertyChangeListener listener2 = e -> doSomethingElse(); 

    void listenToA(A a) { 
     // using method reference 
     a.addPropertyChangeListener("Property1", listener1); 
     // using lambda expression 
     a.addPropertyChangeListener("Property2", listener2); 
    } 

次に、必要なときにlistener1またはlistener2を簡単に削除できます。

また、PropertyChangeSupportオブジェクトには、必要に応じてforループ内のすべてのリスナーを削除できるgetPropertyChangeListeners()があるため、別の方法もあります。

class A { 
    final PropertyChangeSupport pcs = new PropertyChangeSupport(this); 

    void addPropertyChangeListener(String name, PropertyChangeListener listener) { 
     pcs.addPropertyChangeListener(name, listener); 
    } 

    void removePropertyChangeListener(String name, PropertyChangeListener listener) { 
     pcs.removePropertyChangeListener(name, listener); 
    } 

    public void removeAllListeners() { 
     for (PropertyChangeListener l : pcs.getPropertyChangeListeners()) { 
      pcs.removePropertyChangeListener(l); 
     } 
    } 
} 
関連する問題