2016-04-15 21 views
12

ho diversi "processori" statiche Predifined esecuzione lo stesso metodo, ad esempio:riferimento statica (con ::) per un metodo che restituisce un'interfaccia

default double process(double num){ 

Esempio:

public class Test { 
    public static void main(String[] args) { 
     test(Test::processor1, 1d); 
     test(Test::processor2, 1d); 
    } 

    static double processor1(double num){ 
     return num * 10; 
    } 

    static double processor2(double num){ 
     return num * 20; 
    } 
    //... 

    static void test(Function<Double, Double> f, double d){ 
     // Do something util here 
     System.out.println(f.apply(d)); 
    } 
    ... 

Ora immaginate che ho degli oggetti che possono fornire una lista di ulteriori "processori".

Sto tentando di utilizzare uno interface per definire quei "processori" aggiuntivi.

static interface IProcessor{ 
     double process(double num); 
    } 

Realizzazione di un oggetto con l'aggiunta di "processori":

static class SomeObject{ 
     // Just return one but should be a list... 
     static IProcessor getExtraProccessors(){ 
      return new IProcessor(){ 
       public double process(double num){ 
        return num * 30; 
       } 
      }; 
     } 
    } 

Quassù tutto compila e funziona bene. Ma ora sono bloccato.

Utilizzo di SomeObject::getExtraProccessors Ho un riferimento su un metodo statico che restituisce un'interfaccia, come posso richiamare il metodo dell'interfaccia?

Il mio primo tentativo è stato con

test(SomeObject::getExtraProccessors::process, 1d); 

Ma questo non può essere compilato dando un The target type of this expression must be a functional interface

Quindi, per favore mi può dire se è possibile a questo e se sì come ? E se non è possibile, come dovrei farlo?

+2

È possibile utilizzare 'DoubleUnaryOperator' anziché' Function 'e invece di' IProcessor'. –

+1

Non è necessario creare un'istanza di classe interna anonima di 'IProcessor', invece restituire un lambda:' return n -> n * 30; '. E se hai bisogno di una lista: restituisci 'Arrays.asList (n -> n * 30, n -> n/2, ...)'. Inoltre, come ha detto @PaulBoddington, 'DoubleUnaryOperator' è l'interfaccia fornita da Java per operare su un unico operando' double'. –

risposta

7
test(SomeObject.getExtraProccessors()::process, 1); 
  • SomeObject.getExtraProccessors() restituisce un'istanza di interfaccia funzionale IProcessor.
  • SomeObject::getExtraProccessors è un riferimento al metodo statico getExtraProccessor della classe SomeObject.
3

ne dite di usare un'espressione lambda al posto del metodo di riferimento:

test(d-> SomeObject.getExtraProccessors().process(d), 1d); 
2

penso che non c'è bisogno di creare un anonimo istanza di una classe interna che implementa IProcessor. In realtà, se hai intenzione di operare con un double, non hai affatto bisogno dell'interfaccia IProcessor. Java fornisce l'interfaccia DoubleUnaryOperator che si intende esattamente per quello.

Se si desidera restituire una lista di "processori", allora si potrebbe fare in questo modo:

static class SomeObject { 

    static List<DoubleUnaryOperator> getExtraProccessors() { 
     return new ArrayList<>(Arrays.asList(Test::processor1, Test::processor2)); 
    } 
} 

Poi, dato si cambia il metodo di test a:

static void test(DoubleUnaryOperator f, double d) { 
    // Do something util here 
    System.out.println(f.applyAsDouble(d)); 
} 

Si potrebbe utilizzarlo come segue:

test(SomeObject.getExtraProcessors().get(0), 1);