Przyjmijmy, mają następujące działania: interfejsOgraniczenia forEach z odniesieniem sposobu przykład Jawa 8
public interface TemperatureObserver {
void react(BigDecimal t);
}
i w innej klasie i już wypełniony ArrayList
obiektów typu TemperatureObserver
. Zakładając, że temp
jest BigDecimal
mogę powołać react
w pętli przy użyciu:
observers.forEach(item -> item.react(temp));
Moje pytanie: Mogę użyć metody odniesienia dla powyższego kodu?
Następujące nie działa:
observers.forEach(TemperatureObserver::react);
Komunikat o błędzie mówi mi, że
forEach
wArraylist observers
nie ma zastosowania do typuTemperatureObserver::react
TemperatureObserver
nie definiuje metodęreact(TemperatureObserver)
Wystarczająco uczciwe, jako że forEach
oczekuje jako argumentu Consumer<? super TemperatureObserver>
, a mój interfejs, choć funkcjonalny, nie jest zgodny z Consumer
z powodu odmiennego argumentu react
(a BigDecimal
w moim przypadku).
Czy można to rozwiązać, czy jest to przypadek, w którym lambda nie ma odpowiedniego odniesienia do metody?
Metoda, do której się odwołujesz, znajduje się w interfejsie. Nie ma implementacji, więc nie ma sensu go używać. Jeśli stworzysz klasę i użyjesz instancji tej klasy dla odniesienia do metody (np. 'InstanceTempObs :: react') lub uczynisz metodę statyczną, to by działało. (JEŻELI twoja lista jest wpisana jako' BigDecimal') – Riiverside
Byłoby możliwe, gdyby java.lang.Iterable miał drugą metodę forEach, która zajęłaby BiConsumer i parametr. Następnie możesz użyć referencji do metody i przekazać BigDecimal jako drugi parametr. Ten wzorzec istnieje w kolekcjach Eclipse w metodach z przyrostkiem "Z" (np. DlaEachWith). https://github.com/eclipse/eclipse-collections/blob/master/eclipse-collections-api/src/main/java/org/eclipse/collections/api/InternalIterable.java#L106 –
Zobacz [currying] (https) : //en.wikipedia.org/wiki/Currying). –