2009-11-04 4 views
1

У меня есть класс Аннотация итератора, который имеет эту функциюКак выполнить итерацию и выполнить произвольную операцию для каждого элемента?

void iterate(){ 
    while(this.hasnext()){ 
     ..this.next().. 
    } 
} 

Как пройти в любой произвольной функции, которая будет применяться к следующему элементу. Например, есть ли способ сделать iterate(print)?

ответ

9

В Java невозможно напрямую передавать функции в качестве параметров. Вместо этого вам нужно настроить интерфейс с одним методом, как так:

interface Operate { 
    public void operate(Object o); 
} 

Затем вам нужно реализовать интерфейс для каждой отдельной операции, которую вы хотели бы выполнить на Object.

Пример реализации.

class Print implements Operate { 
    public void operate(Object o){ 
     System.out.println(o.toString()); 
    } 
} 

Реализация в вашем коде:

iterate(Operate o){ 
    while(this.hasnext()){ 
     o.operate(this.next()); 
    } 
} 
+2

В принципе, это единственная возможность на данный момент, никаких закрытий даже в Java 7. – Esko

+1

Решение удалить их было печальным решением :( – Malaxeur

+2

Это правильно, просто подумал, что я бы сказал, что это называется Command Pattern, очень полезный шаблон, который вы начнете использовать инстинктивно после того, как вы его использовали несколько раз. – vickirk

0

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

void apply(Object arg) 

Вы можете создавать различные классы, реализующие функции и передавать их в ваш метод итерации. В вашем примере, вы могли бы сделать что-то вроде этого, возможно:

public class PrintFunction implements Function { 
     void apply(Object arg) { 
       System.out.println(arg.toString()); 
     } 
    } 
1

Я хотел бы пересмотреть именование для уточнения семантики:

Имея метод в итератора:

public <T> Object[] apply (Action<T> action, Object context) { 
    List<T> results = new ArrayList<T>(); 
    while(hasNext()) { 
     results.add(action.invoke(this.next(), context)); 
    } 
    T[] r = new T[results.size()]; 
    return results.toArray(r); 
} 


public interface Action <T> { 
    public T invoke (Object target, Object context); 
} 

Контекст может быть null, но в некоторых случаях вам действительно нужно какое-то псевдокрытие для принятия действий, требующих контекста. Чтобы сделать это более надежным, вы можете рассмотреть возможность добавления обработки исключений.

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