2010-04-08 15 views
10

Quiero implementar un método de javascript en java, ¿es esto posible?Objeto de función en Java

decir que tengo una clase Persona:

public class Person { 
private String name ; 
private int age ; 
// constructor ,accessors are omitted 
} 

y una lista con los objetos Persona:

Person p1 = new Person("Jenny",20); 
Person p2 = new Person("Kate",22); 
List<Person> pList = Arrays.asList(new Person[] {p1,p2}); 

yo quiero poner en práctica un método como este:

modList(pList,new Operation (Person p) { 
    incrementAge(Person p) { p.setAge(p.getAge() + 1)}; 
}); 

modlist recibe dos params, uno es una lista, el otro es el "Objeto de función", hace un bucle en la lista y aplica esta función a cada elemento en la lista. En el lenguaje de programación funcional, esto es fácil, no sé cómo Java hace esto? Tal vez podría hacerse a través del proxy dinámico, ¿eso tiene una compensación de rendimiento en comparación con el ciclo nativo?

+0

posible duplicado de http: //stackoverflow.com/questions/122105/java-what-is-the-best-way-to-filter-a-collection –

+0

En una inspección más cercana: no es un duplicado, pero las respuestas pueden ayudarte. –

+0

Si quieres ese tipo de poder, entonces valdría la pena echar un vistazo a Groovy. En Groovy escribirías 'pList.each {it.age ++}' –

Respuesta

14

Puede hacerlo con una interfaz y una clase interna anónima implementarla, como

Person p1 = new Person("Jenny",20); 
Person p2 = new Person("Kate",22); 
List<Person> pList = Arrays.asList(p1, p2); 

interface Operation { 
    abstract void execute(Person p); 
} 

public void modList(List<Person> list, Operation op) { 
    for (Person p : list) 
    op.execute(p); 
} 

modList(pList, new Operation { 
    public void execute(Person p) { p.setAge(p.getAge() + 1)}; 
}); 

Tenga en cuenta que con varargs en Java5, la llamada a Arrays.asList se puede simplificar como se muestra arriba.

Actualización: Una versión generified de lo anterior:

interface Operation<E> { 
    abstract void execute(E elem); 
} 

public <E> void modList(List<? extends E> list, Operation<E> op) { 
    for (E elem : list) 
    op.execute(elem); 
} 

modList(pList, new Operation<Person>() { 
    public void execute(Person p) { p.setAge(p.getAge() + 1); } 
}); 

Tenga en cuenta que con la anterior definición de modList, puede ejecutar una Operation<Person> en, por ejemplo, a List<Student> también (siempre que Student sea una subclase de Person). Un tipo de parámetro simple List<E> no permitiría esto.

+0

Buenos puntos, lo que necesito es un código genérico, que se aplique a la Lista . – Sawyer

+0

@Tony ver mi actualización. –

+0

inspirador, gracias. – Sawyer

3

Eche un vistazo al proyecto lambdaj. Este es un ejemplo de la página principal del proyecto:

List<Person> personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma")); 
forEach(personInFamily).setLastName("Fusco"); 
+0

Sí, ya he comprobado el código fuente, quiero escribir mi propia versión de este método de utilidad. – Sawyer

+0

Enlace de interés, exactamente lo que necesito para un proyecto mío. ¡Gracias! – Alfonso

2

Mire el google collections library. Mire los métodos de transformación en Iteradores e Iterables. Eso debería poder conseguirte lo que quieres.

+0

+1 para el enlace de Guava; biblioteca bastante ordenada, ¡tengo que echarle un vistazo! –

0

Sí, esto es fácil en un lenguaje de programación funcional .. en Java que es un poco más complejo, pero se puede trabajar en algo como esto, utilizando también los genéricos tipos cuando sea posible:

public class TestCase { 
    static interface Transformable {}; 

    static class Person implements Transformable { 
     Person(String name, int age) { 
      this.name = name; 
      this.age = age; 
     } 

     public String name; 
     public int age; 
    } 

    static interface Modifier<T extends Transformable> { 
     void modify(Transformable object); 
    } 

    static class AgeIncrementer implements Modifier<Person> { 
     public void modify(Transformable p) { 
      ++((Person)p).age; 
     } 
    } 

    static void applyOnList(List<? extends Transformable> objects, Modifier<? extends Transformable> modifier) {  
     for (Transformable o : objects) { 
      modifier.modify(o); 
     } 
    } 

    public static void main(String[] args) { 
     ArrayList<Person> l = new ArrayList<Person>(); 
     l.add(new Person("John", 10)); 
     l.add(new Person("Paul", 22)); 
     l.add(new Person("Frank", 35)); 

     applyOnList(l, new AgeIncrementer()); 

     for (Person p : l) 
      System.out.println(p.age); 
    } 
} 
+0

'Modificador.modify' debe tener un parámetro de tipo 'T' en lugar de' Transformable' para hacer innecesarios downcasts e incrementar la seguridad del tipo. –