salida paso pasar parametros parametro metodo mandar llamar funciones funcion ejemplo con como java

paso - ¿Cómo pasar una función como parámetro en Java?



pasar funciones como parametros en java (8)

Expresiones lambda

Para agregar a la excelente respuesta de jk. , Ahora puede pasar un método más fácilmente utilizando Lambda Expressions (en Java 8). En primer lugar, algunos antecedentes. Una interfaz funcional es una interfaz que tiene uno y solo un método abstracto, aunque puede contener cualquier número de métodos predeterminados (nuevos en Java 8) y métodos estáticos. Una expresión lambda puede implementar rápidamente el método abstracto, sin toda la sintaxis innecesaria necesaria si no usa una expresión lambda.

Sin expresiones lambda:

obj.aMethod(new AFunctionalInterface() { @Override public boolean anotherMethod(int i) { return i == 982 } });

Con expresiones lambda:

obj.aMethod(i -> i == 982);

Aquí hay un extracto del tutorial de Java sobre Lambda Expressions :

Sintaxis de las expresiones Lambda

Una expresión lambda consiste en lo siguiente:

  • Una lista separada por comas de parámetros formales encerrados entre paréntesis. El método CheckPerson.test contiene un parámetro, p, que representa una instancia de la clase Person.

    Nota : Puede omitir el tipo de datos de los parámetros en una expresión lambda. Además, puede omitir los paréntesis si solo hay un parámetro. Por ejemplo, la siguiente expresión lambda también es válida:

    p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25

  • La ficha de flecha, ->

  • Un cuerpo, que consiste en una sola expresión o un bloque de declaración. Este ejemplo usa la siguiente expresión:

    p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25

    Si especifica una sola expresión, entonces el tiempo de ejecución de Java evalúa la expresión y luego devuelve su valor. Alternativamente, puede utilizar una declaración de retorno:

    p -> { return p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25; }

    Una declaración de retorno no es una expresión; en una expresión lambda, debe incluir instrucciones entre llaves ({}). Sin embargo, no tiene que incluir una invocación de método void entre llaves. Por ejemplo, la siguiente es una expresión lambda válida:

    email -> System.out.println(email)

Tenga en cuenta que una expresión lambda se parece mucho a una declaración de método; puede considerar las expresiones lambda como métodos anónimos, métodos sin nombre.

Aquí es cómo puede "pasar un método" usando una expresión lambda:

Nota: esto utiliza una nueva interfaz funcional estándar, java.util.function.IntConsumer .

class A { public static void methodToPass(int i) { // do stuff } }

import java.util.function.IntConsumer; class B { public void dansMethod(int i, IntConsumer aMethod) { /* you can now call the passed method by saying aMethod.accept(i), and it will be the equivalent of saying A.methodToPass(i) */ } }

class C { B b = new B(); public C() { b.dansMethod(100, j -> A.methodToPass(j)); //Lambda Expression here } }

El ejemplo anterior se puede acortar aún más con el operador :: .

public C() { b.dansMethod(100, A::methodToPass); }

Esta pregunta ya tiene una respuesta aquí:

¿Es posible pasar un método a un método Java como parámetro? Si es así, ¿podría alguien guiarme, por favor? Esto no parece trivial


Java 8 y superior

Usando Java 8+ expresiones lambda, si tiene una clase o interfaz con un solo método, por ejemplo:

public interface MyInterface { String doSomething(int param1, String param2); }

luego, en cualquier lugar donde se use MyInterface, puede sustituir una expresión lambda:

class MyClass { public MyInterface myInterface = (p1, p2) -> { return p2 + p1; }; }

Por ejemplo, puedes crear un nuevo hilo muy rápidamente:

new Thread(() -> someMethod()).start();

Y use la sintaxis de referencia del método para hacerlo aún más limpio:

new Thread(this::someMethod).start();

Sin expresiones lambda, estos dos últimos ejemplos se verían así:

new Thread(new Runnable() { someMethod(); }).start();

Antes de Java 8

Un patrón común sería ''envolverlo'' dentro de una interfaz, como Callable , por ejemplo, luego pasas un Callable:

public T myMethod(Callable<T> func) { return func.call(); }

Este patrón se conoce como el patrón de comando .

Tenga en cuenta que sería mejor crear una interfaz para su uso particular. Si eliges usar la opción invocable, deberías reemplazar la T anterior con cualquier tipo de valor de retorno que esperes, como String.

En respuesta a su comentario a continuación usted podría decir:

public int methodToPass() { // do something } public void dansMethod(int i, Callable<Integer> myFunc) { // do something }

entonces llámalo, tal vez usando una clase interna anónima:

dansMethod(100, new Callable<Integer>() { public Integer call() { return methodToPass(); } });

Tenga en cuenta que esto no es un ''truco''. Es el equivalente conceptual básico de java para los punteros de función.


Gracias a Java 8, no es necesario realizar los pasos a continuación para pasar una función a un método, para eso están las lambdas, consulte el tutorial de expresión de Lambda de Oracle . El resto de esta publicación describe lo que solíamos hacer en los viejos tiempos para implementar esta funcionalidad.

Por lo general, declara que su método toma alguna interfaz con un solo método, luego pasa un objeto que implementa esa interfaz. Un ejemplo es en colecciones-comunes, en las que tiene interfaces para cierre, transformador y predicado, y métodos en los que pasa implementaciones. La guayaba es la nueva colección mejorada de comunes, puede encontrar interfaces equivalentes allí.

Entonces, por ejemplo, commons-collections tiene org.apache.commons.collections.CollectionUtils, que tiene muchos métodos estáticos que toman objetos pasados, para elegir uno al azar, existe uno llamado con esta firma:

static boolean exists(java.util.Collection collection, Predicate predicate)

Toma un objeto que implementa la interfaz Predicate, lo que significa que debe tener un método que tome un objeto y devuelva un valor booleano.

Así que puedo llamarlo así:

CollectionUtils.exists(someCollection, new Predicate() { public boolean evaluate(Object object) { return ("a".equals(object.toString()); } });

y devuelve verdadero o falso dependiendo de si someCollection contiene un objeto para el cual el predicado devuelve verdadero.

De todos modos, esto es solo un ejemplo, y las colecciones comunes están desactualizadas. Acabo de olvidar el equivalente en guayaba.


Java no (todavía) soporta cierres. Pero hay otros lenguajes como Scala y Groovy que se ejecutan en la JVM y admiten cierres.


Java soporta cierres muy bien. Simplemente no admite funciones , por lo que la sintaxis a la que estás acostumbrado para los cierres es mucho más incómoda y voluminosa: tienes que envolver todo en una clase con un método. Por ejemplo,

public Runnable foo(final int x) { return new Runnable() { public void run() { System.out.println(x); } }; }

Devolverá un objeto Runnable cuyo método run() "cierra" la x pasada, como en cualquier idioma que admita funciones y cierres de primera clase.


Podrías usar la reflexión de Java para hacer esto. El método se representaría como una instancia de java.lang.reflect.Method .

import java.lang.reflect.Method; public class Demo { public static void main(String[] args) throws Exception{ Class[] parameterTypes = new Class[1]; parameterTypes[0] = String.class; Method method1 = Demo.class.getMethod("method1", parameterTypes); Demo demo = new Demo(); demo.method2(demo, method1, "Hello World"); } public void method1(String message) { System.out.println(message); } public void method2(Object object, Method method, String message) throws Exception { Object[] parameters = new Object[1]; parameters[0] = message; method.invoke(object, parameters); } }


Sé que este es un post bastante antiguo pero tengo otra solución un poco más simple. Podrías crear otra clase dentro y hacerla abstracta. A continuación, haga un método abstracto con el nombre que desee. En la clase original, haga un método que tome la nueva clase como un parámetro, en este método llame al método abstracto. Se verá algo como esto.

public class Demo { public Demo(/.../){ } public void view(Action a){ a.preform(); } /** * The Action Class is for making the Demo * View Custom Code */ public abstract class Action { public Action(/.../){ } abstract void preform(); } }

Ahora puedes hacer algo como esto para llamar a un método desde dentro de la clase.

/... Demo d = new Demo; Action a = new Action() { @Override void preform() { //Custom Method Code Goes Here } }; /.../ d.view(a)

Como dije, sé que es viejo, pero de esta manera creo que es un poco más fácil. Espero eso ayude.


Utilicé el patrón de comando que @jk. mencionado, añadiendo un tipo de retorno:

public interface Callable<I, O> { public O call(I input); }