Edytuj: Moje pytanie tutaj zostało wysłuchane. Podsumowując, byłem zdezorientowany, jeśli chodzi o użycie niestatycznych odnośników do metod. Tam interfejs funkcjonalny i metoda referencyjna mają różną liczbę parametrów.Używanie podwójnych dwukropków - różnica między odwołaniami do metod statycznych i niestatycznych
Odpowiedź na moje pytanie brzmi: comment i zaakceptowana odpowiedź.
Jestem obecnie czytania Java Tutorial o metodach redukcji strumień (https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html). Tam znalazłem kawałek kodu, który uważałem za błędny, więc napisałem prostszy kod, aby się upewnić.
// B.java file
import java.util.*;
public class B
{
public static void main(String[] args)
{
List<Integer> zahlen = new LinkedList<Integer>();
zahlen.add(1);
zahlen.add(2);
zahlen.add(3);
Averager averageCollect = zahlen.stream()
.collect(Averager::new, Averager::addcount, Averager::combine);
System.out.println(averageCollect.average());
}
}
// Averager.java from the official Java tutorial
public class Averager
{
private int total = 0;
private int count = 0;
public double average() {
return count > 0 ? ((double) total)/count : 0;
}
public void addcount(int i) { total += i; count++;}
public void combine(Averager other) {
total += other.total;
count += other.count;
}
}
Powodem myślałem, że to nie będzie działać z powodu linii:
Averager averageCollect = zahlen.stream()
.collect(Averager::new, Averager::addcount, Averager::combine);
W dokumentacji Java dla Stream.collect
(https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.function.Supplier-java.util.function.BiConsumer-java.util.function.BiConsumer-) mówi, że jako drugi parametr funkcja, która odpowiada wymagany jest interfejs funkcjonalny BiConsumer
, który ma abstrakcyjną metodę z dwoma argumentami. Ale Averager.addcount
imają tylko jeden parametr.
ja również sprawdzane z wyrażeń lambda:
Averager averageCollect = zahlen.stream()
.collect(Averager::new, (a,b) -> a.addcount(b), (a,b) -> a.combine(b));
Ten kod działa również i jako drugi i trzeci parametr Mam funkcji z dwoma parametrami.
Dlaczego dokładnie powyższy kod napisałem powyżej, mimo że podano tylko funkcje z jednym parametrem? I dlaczego pojawiają się komunikaty o błędach, gdy zmieniam zarówno Averager.addcount
i i i
public void addcount(Averager one, Integer i)
public void combine(Averager one, Averager other)
Jeśli to zrobić pojawia się następujący komunikat o błędzie:
B.java:12: error: no suitable method found for collect(Averager::new,Averager::addcount,Averager::combine) .collect(Averager::new, Averager::addcount, Averager::combine); ^ method Stream.collect(Supplier,BiConsumer,BiConsumer) is not applicable (cannot infer type-variable(s) R#1 (argument mismatch; invalid method reference cannot find symbol symbol: method addcount(R#1,Integer) location: class Averager)) method Stream.collect(Collector) is not applicable (cannot infer type-variable(s) R#2,A (actual and formal argument lists differ in length)) where R#1,T,R#2,A are type-variables: R#1 extends Object declared in method collect(Supplier,BiConsumer,BiConsumer) T extends Object declared in interface Stream R#2 extends Object declared in method collect(Collector) A extends Object declared in method collect(Collector) 1 error
Proszę mi pomóc zrozumieć.
Parametrem _current_ może być pierwszy parametr. Tak więc metoda 'BiConsumer' może mnie' (a, b) 'dla metody' static' lub 'a.method (b)' dla metody instancji. W twoim złamanym przykładzie; przeszedłeś ** metodę ** instancji. –
Patrz także [Samouczek firmy Oracle "Referencje metod"] (http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html#PageTitle), esp.sekcja "Rodzaje odniesień metodycznych". – Holger