Come funziona il metodo Stream.filter ()?

2

So come funziona l'espressione lambda e so che è un argomento per .filter() che stabilisce i criteri per filtrare con. Ma non capisco come .filter() usi l'argomento, in questo caso un'espressione lambda, perché .filter () non ha un'implementazione o almeno ne richiede uno in fase di compilazione. Cerco questa implementazione sconosciuta nel sito di Oracle ma ci sono solo poche parole che spiegano come funziona e nessun codice.

Questa implementazione è nascosta o viene creata automaticamente dal compilatore java?

Un'operazione di aggregazione ne ha bisogno?

double average = roster
  .stream()
  .filter(p -> p.getGender() == Person.Sex.MALE)
  .mapToInt(Person::getAge)
  .average()
  .getAsDouble();

roster è un'istanza List<Person> di ArrayList<Person>

Person è una semplice classe che rappresenta una persona

    
posta user3727894 14.06.2014 - 01:46
fonte

2 risposte

1

L'oggetto lambda viene creato automaticamente dal compilatore.

Qualsiasi interfaccia "funzionale" (ovvero un'interfaccia con una sola funzione) può essere l'obiettivo per uno. Il codice equivalente non lambda sarebbe:

double average = roster
.stream()
.filter(new Predicate<Person>(){
          public boolean test(Person p){
              return p.getGender() == Person.Sex.MALE;
           }
      })
.mapToInt(Person::getAge)
.average()
.getAsDouble();

E avrebbe potuto essere implementato in questo modo dal compilatore, ma erano interessati all'efficienza e volevano che le persone potessero essere in grado di fare riferimento direttamente ai metodi. Quindi, invece, traducono il lambda in un metodo privato che può essere o non essere statico (a seconda che venga catturato this ) e usare un meta factory che crea l'oggetto lambda effettivo che poi inoltra al codice effettivo nel metodo privato.

Per maggiori informazioni vedi alla pagina seguente.

    
risposta data 14.06.2014 - 02:38
fonte
0

L'interfaccia Collection ora ha un metodo predefinito che implementa il metodo stream() che restituisce il flusso. I metodi predefiniti sono nuovi in Java 8 e consentono alle interfacce di implementare metodi per evolvere l'API. Quindi, questa implementazione del metodo stream() sulla raccolta deve essere la costruzione di un oggetto che implementa l'interfaccia Stream e la restituisce.

Internamente, il metodo di interfaccia Collection stream() inoltra una chiamata alla classe StreamSupport documentata. La classe SteamSupport a sua volta costruisce una classe non documentata chiamata ReferencePipeline che puoi trovare nel codice sorgente java nel java Java 8.

Quindi, apparentemente, è intenzione del progettista dell'API che se vuoi fare un flusso personalizzato, non devi andare oltre la classe StreamSupport.

    
risposta data 06.11.2014 - 21:00
fonte

Leggi altre domande sui tag