web-dev-qa-db-ja.com

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

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

_public interface TemperatureObserver {
    void react(BigDecimal t);
}
_

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

_observers.forEach(item -> item.react(temp));
_

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

以下は機能しません。

_observers.forEach(TemperatureObserver::react);
_

エラーメッセージは私にそれを伝えています

  1. _Arraylist observers_のforEachは、タイプ_TemperatureObserver::react_には適用されません
  2. TemperatureObserverはメソッドを定義していませんreact(TemperatureObserver)

forEachが_Consumer<? super TemperatureObserver>_を引数として期待しているため、十分に公平であり、私のインターフェースは機能的ではありますが、Consumer(私の場合はreact)の引数が異なるため、BigDecimalに準拠していません。

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

20
Temp Agilist

ストリームから単一の値を取得できる場合に使用できるメソッド参照には、次の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);
20
Andreas

パラメータではなくハンドラを反復するため、機能しません。

たとえば、次のコードは機能します。

    ArrayList<BigDecimal> temps = new ArrayList<>();

    TemperatureObserver observer = new TemperatureObserverImpl();

    temps.forEach(observer::react);
6
Bor Laze