2010-04-08 2 views
10

Я хочу реализовать javascript как метод в java, возможно ли это?Объект функции в Java

Скажем, у меня есть класс Person:

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

и список объектов Person:

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

Я хочу реализовать метод, как это:

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

ModList получает два параметра, один - список, другой - «Объект функции», он перебирает список и применяет эту функцию к каждый элемент в списке. На языке функционального программирования это легко, я не знаю, как это сделать java? Может быть, это можно сделать с помощью динамического прокси-сервера, имеет ли производительность компромисс по сравнению с native for loop?

+0

возможно дубликат HTTP: //stackoverflow.com/questions/122105/java-what-is-the-best-way-to-filter-a-collection –

+0

При ближайшем рассмотрении: это не дубликат, но ответы могут по-прежнему вам помочь. –

+0

Если вам нужна такая сила, тогда Groovy может стоить взгляда. В Groovy вы должны написать 'pList.each {it.age ++}' –

ответ

14

Вы можете сделать это с интерфейсом и анонимным внутренним классом, реализующим его, как

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)}; 
}); 

Обратите внимание, что с переменным числом аргументов в Java5, призыв к Arrays.asList можно упростить, как показано выше.

Update: обобщен версия выше:

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); } 
}); 

Обратите внимание, что с приведенным выше определением modList, вы можете выполнить Operation<Person> на, например, a List<Student> (при условии, что Student является подклассом Person). Обычный тип параметра List<E> не позволяет этого.

+0

Хорошие баллы, мне нужен генератор кода, который применяется к списку . – Sawyer

+0

@ Тони вижу мое обновление. –

+0

вдохновляющий, спасибо. – Sawyer

3

Посмотрите на проект lambdaj. Вот пример из проекта домашней страницы:

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

Да, я уже проверил исходный код, я хочу написать свою собственную версию этого метода утилиты. – Sawyer

+0

Интересная ссылка, именно то, что мне нужно для моего проекта. Благодаря! – Alfonso

2

Посмотрите на google collections library. Посмотрите на методы преобразования на Iterators и Iterables. Это должно быть в состоянии получить то, что вы хотите.

+0

+1 для ссылки Guava; довольно аккуратная библиотека, я должен проверить это! –

0

Да, это легко в функциональном языке программирования .. в Java это немного сложнее, но вы можете работать что-то вроде этого, используя также дженериков типы, когда это возможно:

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

'Модификатор.modify' должен иметь параметр типа 'T' вместо' Transformable', чтобы сделать ненужные нисходящие потоки и повысить безопасность типа. –

Смежные вопросы