Функциональный объект в Java
Я хочу реализовать javascript-метод в 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 для цикла?
Ответы
Ответ 1
Вы можете сделать это с помощью интерфейса и анонимного внутреннего класса, реализующего его, например
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)};
});
Обратите внимание, что с помощью varargs в Java5 вызов Arrays.asList
может быть упрощен, как показано выше.
Обновление: Обобщенная версия выше:
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>
не позволяет этого.
Ответ 2
Взгляните на проект lambdaj. Вот пример с домашней страницы проекта:
List<Person> personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma"));
forEach(personInFamily).setLastName("Fusco");
Ответ 3
Посмотрите библиотеку коллекций google. Посмотрите на методы преобразования на Iterators и Iterables. Это должно быть в состоянии получить то, что вы хотите.
Ответ 4
Да, это просто на функциональном языке программирования.. в Java это немного сложнее, но вы можете что-то с этим поработать, используя также типы generics, когда это возможно:
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);
}
}