2011-04-26 17 views
5

Leí un artículo sobre Joel On Software sobre la idea de usar funciones de orden superior para simplificar en gran medida el código mediante el uso del mapa y reducir. Mencionó que esto era difícil de hacer en Java. El artículo: http://www.joelonsoftware.com/items/2006/08/01.html¿Cómo puedo escribir una función de orden superior como map o reducir en java?

El ejemplo del artículo de más abajo, los bucles a través de una matriz, y utiliza la función fn que se ha pasado como un argumento en cada elemento de la matriz:

function map(fn, a) 
{ 
    for (i = 0; i < a.length; i++) 
    { 
     a[i] = fn(a[i]); 
    } 
} 

Esto se invoca similares a la continuación en la práctica:

map(function(x){return x*2;}, a); 
map(alert, a); 

Idealmente me gustaría escribir una función de mapa para trabajar en las matrices, o colecciones de cualquier tipo, si es posible.

He estado buscando en Internet, y estoy teniendo dificultades para encontrar recursos sobre el tema. En primer lugar, ¿son posibles las funciones anónimas en Java? ¿Es esto posible de otra manera? ¿Estará disponible en una versión futura de java? Si es posible, ¿cómo puedo hacerlo?

Imagino que si esto no es posible en Java existe algún tipo de 'patrón'/técnica que la gente usa para lograr el mismo efecto, ya que imagino que las funciones anónimas son una herramienta muy poderosa en el mundo del software. la única pregunta similar que pude encontrar fue esta: Java generics - implementing higher order functions like map y no tiene absolutamente ningún sentido para mí.

Respuesta

6

Guava proporciona un mapa (pero se llama transform lugar, y está en clases de utilidad como Lists y Collections2). Sin embargo, no proporciona fold/reduce.

En cualquier caso, la sintaxis para usar transform se siente muy torpe en comparación con el uso de map en Scheme. Es como intentar escribir con la mano izquierda, si eres diestro. Pero, esto es Java; Qué esperas. :-P

3

Las clases anónimas de método único proporcionan una forma similar, pero mucho más detallada, de escribir una función anónima en Java. Por ejemplo, usted podría tener:

Iterable<Source> foos = ...; 
Iterable<Destination> mappedFoos = foos.map(new Function<Source, Destination>() 
{ 
    public Destination apply(Source item) { return ... } 
}); 

Para un ejemplo de una biblioteca de Java con un estilo funcional, ver Guava

+1

De hecho, parece que si/cuando Java finalmente obtiene expresiones lambda, serán convertibles en una clase anónima. – hammar

2
interface Func<V,A> { 
    V call (A a); 
} 

static <V,A> List<V> map (Func<V,A> func, List<A> as) { 
    List<V> vs = new ArrayList<V>(as.size()); 
    for (A a : as) { 
     Vs.add(func.call(a)); 
    } 
    return vs; 
} 
0

Paguro has an open-source implementation of higher order functions. La prueba inicial muestra que es 98% más rápido que Java nativo para cada ciclo. Las operaciones que admite se aplican de forma perezosa sin modificar la colección subyacente. Da salida a versiones seguras de tipo de las colecciones Clojure inmutables (ya veces mutables). Transformable is built into Paguro's unmodifiable and immutable collections and interfaces. Para usar una colección java.util cruda como entrada, solo envuélvala con la función xform().

Cuestiones relacionadas