次の機能インターフェイスがあると仮定します。
_public interface TemperatureObserver {
void react(BigDecimal t);
}
_
次に、別のクラスでは、すでにArrayList
型のオブジェクトのTemperatureObserver
がすでに入力されています。 temp
がBigDecimal
であると仮定すると、react
をループ内で呼び出すことができます。
_observers.forEach(item -> item.react(temp));
_
私の質問:上記のコードのメソッド参照を使用できますか?
以下は機能しません。
_observers.forEach(TemperatureObserver::react);
_
エラーメッセージは私にそれを伝えています
Arraylist observers
_のforEach
は、タイプ_TemperatureObserver::react
_には適用されませんTemperatureObserver
はメソッドを定義していませんreact(TemperatureObserver)
forEach
が_Consumer<? super TemperatureObserver>
_を引数として期待しているため、十分に公平であり、私のインターフェースは機能的ではありますが、Consumer
(私の場合はreact
)の引数が異なるため、BigDecimal
に準拠していません。
それでこれを解決できますか、それともラムダに対応するメソッド参照がない場合ですか?
ストリームから単一の値を取得できる場合に使用できるメソッド参照には、次の3種類があります。
ストリーミングされたオブジェクトのパラメーターなしのメソッド。
class Observer {
public void act() {
// code here
}
}
observers.forEach(Observer::act);
observers.forEach(obs -> obs.act()); // equivalent lambda
ストリーミングされたオブジェクトは、メソッドのthis
オブジェクトになります。
ストリームオブジェクトをパラメーターとして使用する静的メソッド。
class Other {
public static void act(Observer o) {
// code here
}
}
observers.forEach(Other::act);
observers.forEach(obs -> Other.act(obs)); // equivalent lambda
ストリームオブジェクトをパラメーターとして使用する非静的メソッド。
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);
パラメータではなくハンドラを反復するため、機能しません。
たとえば、次のコードは機能します。
ArrayList<BigDecimal> temps = new ArrayList<>();
TemperatureObserver observer = new TemperatureObserverImpl();
temps.forEach(observer::react);