Modifica: la mia domanda ha avuto risposta. Per riassumere, ero confuso sull'uso di riferimenti al metodo non statici. Lì l'interfaccia funzionale e il metodo di riferimento hanno un numero diverso di parametri.Uso di doppi punti - differenza tra i riferimenti di metodo statici e non statici
Ciò che ha risposto alla mia domanda è comment e la risposta accettata.
Attualmente sto leggendo il tutorial Java sui metodi di riduzione del flusso (https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html). Lì ho trovato un pezzo di codice che pensavo fosse sbagliato, quindi ho fatto un codice più semplice per essere sicuro.
// 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;
}
}
La ragione per cui ho pensato che questo non avrebbe funzionato è a causa della linea:
Averager averageCollect = zahlen.stream()
.collect(Averager::new, Averager::addcount, Averager::combine);
Nella documentazione Java per il 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-) si dice che come secondo parametro una funzione che soddisfa è richiesta l'interfaccia funzionale BiConsumer
che ha un metodo astratto con due argomenti. Ma Averager.addcount
e Averager.combine
hanno un solo parametro.
Ho anche verificato con le espressioni lambda:
Averager averageCollect = zahlen.stream()
.collect(Averager::new, (a,b) -> a.addcount(b), (a,b) -> a.combine(b));
Questo codice funziona anche e come secondo e terzo parametro devo funzioni con due parametri.
Perché esattamente il codice che ho scritto sopra funziona, anche se sono state fornite funzioni con un solo parametro? E perché ci sono messaggi di errore quando cambio sia Averager.addcount
e Averager.combine
per avere due parametri come questo?
public void addcount(Averager one, Integer i)
public void combine(Averager one, Averager other)
Se lo faccio ottengo il seguente messaggio di errore:
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
Si prega di aiutarmi a capire.
l'elemento _corrente_ può essere il primo parametro. Quindi un metodo 'BiConsumer' mi può' (a, b) 'per un metodo' static' o 'a.method (b)' per un metodo di istanza. Nel tuo esempio spezzato; hai passato un metodo ** instance **. –
Vedere anche [Riferimenti del metodo "del tutorial di Oracle"] (http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html#PageTitle), esp.la sezione "Tipi di riferimenti al metodo". – Holger