Punteros de función en Java


Answers

Puede sustituir un puntero de función con una interfaz. Supongamos que quiere ejecutar una colección y hacer algo con cada elemento.

public interface IFunction {
  public void execute(Object o);
}

Esta es la interfaz que podríamos pasar a algunos para decir CollectionUtils2.doFunc (Collection c, IFunction f).

public static void doFunc(Collection c, IFunction f) {
   for (Object o : c) {
      f.execute(o);
   }
}

Como ejemplo digamos que tenemos una colección de números y le gustaría agregar 1 a cada elemento.

CollectionUtils2.doFunc(List numbers, new IFunction() {
    public void execute(Object o) {
       Integer anInt = (Integer) o;
       anInt++;
    }
});
Question

Esto puede ser algo común y trivial, pero parece que tengo problemas para encontrar una respuesta concreta. En C # hay un concepto de delegados, que se relaciona fuertemente con la idea de indicadores de función de C ++. ¿Hay una funcionalidad similar en Java? Dado que los indicadores están algo ausentes, ¿cuál es la mejor manera de hacerlo? Y para ser claros, estamos hablando de primera clase aquí.




No, las funciones no son objetos de primera clase en Java. Puede hacer lo mismo implementando una clase de controlador: así se implementan las devoluciones de llamada en el Swing, etc.

Sin embargo, hay propuestas de cierres (el nombre oficial de lo que estás hablando) en futuras versiones de java: Javaworld tiene un artículo interesante.







Para lograr una funcionalidad similar, puede usar clases internas anónimas.

Si tuviera que definir una interfaz Foo :

interface Foo {
    Object myFunc(Object arg);
}

Cree una bar método que recibirá un 'puntero de función' como argumento:

public void bar(Foo foo) {
    // .....
    Object object = foo.myFunc(argValue);
    // .....
}

Finalmente llame al método de la siguiente manera:

bar(new Foo() {
    public Object myFunc(Object arg) {
        // Function code.
    }
}



Java8 ha introducido lambdas y referencias de métodos . Por lo tanto, si su función coincide con una interfaz funcional (puede crear la suya propia), puede utilizar una referencia de método en este caso.

Java proporciona un conjunto de interfaces funcionales comunes . mientras que podrías hacer lo siguiente:

public class Test {
   public void test1(Integer i) {}
   public void test2(Integer i) {}
   public void consumer(Consumer<Integer> a) {
     a.accept(10);
   }
   public void provideConsumer() {
     consumer(this::test1);   // method reference
     consumer(x -> test2(x)); // lambda
   }
}



Links