Você precisa criar uma interface que forneça as funções que você deseja transmitir. por exemplo:
/**
* A simple interface to wrap up a function of one argument.
*
* @author rcreswick
*
*/
public interface Function1<S, T> {
/**
* Evaluates this function on it's arguments.
*
* @param a The first argument.
* @return The result.
*/
public S eval(T a);
}
Então, quando você precisar passar uma função, poderá implementar essa interface:
List<Integer> result = CollectionUtilities.map(list,
new Function1<Integer, Integer>() {
@Override
public Integer eval(Integer a) {
return a * a;
}
});
Por fim, a função map usa o passado na Function1 da seguinte maneira:
public static <K,R,S,T> Map<K, R> zipWith(Function2<R,S,T> fn,
Map<K, S> m1, Map<K, T> m2, Map<K, R> results){
Set<K> keySet = new HashSet<K>();
keySet.addAll(m1.keySet());
keySet.addAll(m2.keySet());
results.clear();
for (K key : keySet) {
results.put(key, fn.eval(m1.get(key), m2.get(key)));
}
return results;
}
Geralmente, você pode usar o Runnable em vez de sua própria interface, se não precisar passar parâmetros, ou pode usar várias outras técnicas para tornar a contagem de parâmetros menos "fixa", mas geralmente é uma troca com a segurança de tipo. (Ou você pode substituir o construtor do objeto de função para passar os parâmetros dessa maneira. Existem muitas abordagens e algumas funcionam melhor em determinadas circunstâncias.)