Java 8 のインスタンスメソッド参照での forEach の制限 質問する

Java 8 のインスタンスメソッド参照での forEach の制限 質問する

次のような機能インターフェースがあると仮定します。

public interface TemperatureObserver {
    void react(BigDecimal t);
}

そして、別のクラスには、ArrayList型のオブジェクトがすでに入力されていますTemperatureObserver。 がtempであると仮定すると、次を使用してループでBigDecimal呼び出すことができます。react

observers.forEach(item -> item.react(temp));

私の質問: 上記のコードにメソッド参照を使用できますか?

以下は機能しません:

observers.forEach(TemperatureObserver::react);

エラーメッセージは私にこう伝えています

  1. forEachはタイプArraylist observersには適用されませんTemperatureObserver::react
  2. TemperatureObserverメソッドを定義しないreact(TemperatureObserver)

まあ、 はforEach引数 a として期待されており、私のインターフェースは機能的ではありますが、引数が異なるため(私の場合は a )Consumer<? super TemperatureObserver>に準拠していません。ConsumerreactBigDecimal

それで、これは解決できるのでしょうか、それともラムダに対応するメソッド参照がない場合なのでしょうか?

ベストアンサー1

ストリームから単一の値が利用できる場合に使用できるメソッド参照には、次の 3 種類があります。

  1. ストリーミングされたオブジェクトのパラメーターなしのメソッド。

    class Observer {
        public void act() {
            // code here
        }
    }
    
    observers.forEach(Observer::act);
    
    observers.forEach(obs -> obs.act()); // equivalent lambda
    

    ストリームされたオブジェクトはthisメソッドのオブジェクトになります。

  2. ストリーム オブジェクトをパラメーターとして持つ静的メソッド。

    class Other {
        public static void act(Observer o) {
            // code here
        }
    }
    
    observers.forEach(Other::act);
    
    observers.forEach(obs -> Other.act(obs)); // equivalent lambda
    
  3. ストリーム オブジェクトをパラメーターとして持つ非静的メソッド。

    class Other {
        void act(Observer o);
    }
    
    Other other = new Other();
    observers.forEach(other::act);
    
    observers.forEach(obs -> other.act(obs)); // equivalent lambda
    

コンストラクター参照もありますが、これはこの質問とは実際には関係ありません。

外部値が​​ありtemp、メソッド参照を使用したい場合は、3 番目のオプションを実行できます。

class Temp {
    private final BigDecimal temp;
    public Temp(BigDecimal temp) {
        this.temp = temp;
    }
    public void apply(TemperatureObserver observer) {
        observer.react(this.temp);
    }
}

Temp tempObj = new Temp(temp);

observers.forEach(tempObj::apply);

おすすめ記事