2010-12-21 13 views
15

Me gustaría transformar fácilmente una colección (lista) de objetos de la clase A en una colección de objetos de la clase B, tal como lo hace la función de mapa de Python. ¿Hay alguna implementación "conocida" de esto (algún tipo de biblioteca)? Ya lo busqué en Apache's commons-lang pero sin suerte.¿Hay un equivalente de Java para la función de mapa de Python?

+0

En Python 'map()' no sería la forma preferida de hacerlo, en su lugar, la mayoría utilizaría una expresión del generador o comprensión de la lista –

Respuesta

6

todavía no existe

programación funcional se añadirán características en Java 8 - Project Lambda

Creo Google Guava es mejor para sus necesidades ahora

+1

Sí, Collections2.transform parece hacer lo que necesito. – gregorej

1

Usted puede tratar de guayaba, pero es probable encontrar que si utiliza una clase anónima su va a ser más complicado y más largo que acaba de usar un bucle.

List<OldType> list1 = 
List<NewType> list2 = new ArrayList<NewType>(list1.size()); 
for(OldType element: list1); 
    list2.add(transform(element)); 

Vale la pena recordar que Java no es un lenguaje funcional y que a menudo es mejor simplemente usar un bucle. Tal vez cuando Java tiene cierres ... suspiro.

+0

Buen punto, pero a veces es más legible definir estos tipos de f operaciones en una instrucción. Incluso si la definición de clase anónima es más larga. Además, tenía curiosidad;) – gregorej

+0

Diría que es mucho más claro si estás acostumbrado a leer el código de esa manera. Lamentablemente, Java no ayuda mucho. :( –

3

Hay varias bibliotecas funcionales mencionados here, la mayoría de los cuales probablemente cubre mapa:

http://www.cs.chalmers.se/~bringert/hoj/ programador (incluye Java 5.0 genéricos soporte). Poca documentación.

http://jakarta.apache.org/commons/sandbox/functor/ Parece que no se mantiene, no es compatible con los genéricos. Little documentación.

http://devnet.developerpipeline.com/documents/s=9851/q=1/ddj0511i/0511i.html biblioteca.

http://functionalj.sourceforge.net

http://www.functologic.com/orbital/

http://jga.sourceforge.net/ de programación en Java (incluye genéricos). En espera de más documentación , tal vez mejor organización de la API.

-1

Esta es mi solución:

public abstract class MapF<T,S> 
    { 
     public abstract T f(S s) throws Exception; 

     public List<T> map(List<S> input) throws Exception 
     { 
      LinkedList<T> output = new LinkedList<T>(); 
      for (S s: input) 
       output.add(f(s)); 
      return output; 
     } 
    } 

Simplemente, amplía esta clase definiendo su función f y llamando al mapa de métodos en la lista.

7

A partir de Java 8, se puede hacer gracias al uso de un Stream API appopriate asignadorFunction que vamos a utilizar para convertir nuestras instancias de la clase A a instancias de la clase B.

El pseudo código sería:

List<A> input = // a given list of instances of class A 
Function<A, B> function = // a given function that converts an instance 
          // of A to an instance of B 
// Call the mapper function for each element of the list input 
// and collect the final result as a list 
List<B> output = input.stream().map(function).collect(Collectors.toList()); 

Aquí es un ejemplo concreto que convertirá un List de String a un List de Integer usando Integer.valueOf(String) como función mapper:

List<String> input = Arrays.asList("1", "2", "3"); 
List<Integer> output = input.stream().map(Integer::valueOf).collect(Collectors.toList()); 
System.out.println(output); 

Salida:

[1, 2, 3] 

Para versiones anteriores deJava, todavía se puede utilizar FluentIterable de Google guayaba para reemplazar el Stream y utilizar com.google.common.base.Function en lugar de java.util.function.Function como función asignador.

El ejemplo anterior se podría reescribir como a continuación:

List<Integer> output = FluentIterable.from(input) 
    .transform(
     new Function<String, Integer>() { 
      public Integer apply(final String value) { 
       return Integer.valueOf(value); 
      } 
     } 
    ).toList(); 

Salida:

[1, 2, 3] 
0

Desde Java 8, el equivalente de Java para el mapa de Python se llama ... mapa !

package stackOverflow; 

import java.util.Arrays; 
import java.util.List; 
import java.util.stream.Collectors; 


public class ListMapExample 
{ 

    public static void main(String[] args) { 
     List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5); 
     List<int[]> arrays = integers.stream().map(size -> new int[size]) 
       .collect(Collectors.toList()); 
     arrays.forEach(ary -> System.out.println(Arrays.toString(ary))); 
    } 

} 

En este ejemplo se convierte una lista de números enteros a una lista de matrices con el tamaño correspondiente:

[0] 
[0, 0] 
[0, 0, 0] 
[0, 0, 0, 0] 
[0, 0, 0, 0, 0] 

También puede escribir más de una sentencia dentro de un mapa:

List<String> strings = Arrays.asList("1", "2", "3", "4", "5"); 
Stream<int[]> arraysStream = strings.stream().map(string -> { 
    int size = Integer.valueOf(string); 
    int size2 = size * 2; 
    return new int[size2]; 
}); 
arraysStream.map(Arrays::toString).forEach(System.out::println); 
Cuestiones relacionadas