2010-04-08 9 views
10

Chcę zaimplementować javascript jak metoda w java, jest to możliwe?Obiekt funkcji w Javie

Powiedz, mam klasy Osoba:

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

i listę z obiektami osobę:

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

Ja wanna zaimplementować metody takie jak to:

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

Modlist odbiera dwa parametry, jeden to lista, drugi to "Obiekt funkcji", pętle na liście i zastosowanie tej funkcji do każdy element na liście. W języku programowania funkcjonalnego jest to łatwe, nie wiem jak zrobić to java? Może można to zrobić za pośrednictwem dynamicznego proxy, czy to ma kompromitację wydajności w porównaniu z natywną pętlą for?

+0

możliwe duplikat http: //stackoverflow.com/questions/122105/java-what-is-the-best-way-to-filter-a-collection –

+0

Przy bliższym przyjrzeniu się: nie jest to duplikat, ale odpowiedzi mogą ci pomóc. –

+0

Jeśli chcesz tego rodzaju moc, Groovy może być wart obejrzenia. W Groovy napisałbyś: "pList.each {it.age ++}" –

Odpowiedz

14

Można to zrobić za pomocą interfejsu i anonimowej klasy wewnętrznej wykonawczego go, jak

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

Należy zauważyć, że z varargs w java5, wywołaniu Arrays.asList można uprościć, jak pokazano powyżej.

Aktualizacja: generified wersja powyższego:

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

Należy pamiętać, że z powyższej definicji modList można wykonać na przykład Operation<Person> również List<Student> (pod warunkiem, że Student jest podklasą Person). Zwykły typ parametru List<E> nie pozwalałby na to.

+0

Dobrze, potrzebuję wygenerowanego kodu, który ma zastosowanie do Listy . – Sawyer

+0

@Tony zobacz moją aktualizację. –

+0

inspirujące, dzięki. – Sawyer

3

Spójrz na projekt lambdaj. Oto przykład ze strony domowej projektu:

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

tak, już sprawdziłem kod źródłowy, chcę napisać własną wersję tej metody narzędzia. – Sawyer

+0

Interesujący link, dokładnie to, czego potrzebuję do mojego projektu. Dzięki! – Alfonso

2

Spójrz na google collections library. Spójrz na metody transformacji na Iteratory i Iterables. To powinno dać ci to, czego chcesz.

+0

+1 dla łącza Guava; całkiem porządna biblioteka, muszę to sprawdzić! –

0

Tak, to jest łatwy w funkcjonalnym językiem programowania .. w Javie jest to trochę bardziej skomplikowane, ale można wypracować coś takiego, wykorzystując także leków generycznych typów, jeśli to możliwe:

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

'Modyfikator.modify' powinien mieć parametr typu 'T' zamiast' Transformable', aby uczynić downcasts zbędnym i zwiększyć bezpieczeństwo typu. –

Powiązane problemy