2011-09-16 12 views
7

Quiero aplicar una función a una colección, mapa, etc., usando guayaba.¿Es posible aplicar una función a una colección usando Java Guava?

Básicamente, tengo que cambiar el tamaño de las filas y columnas de una Table por separado para todas las filas y columnas son de igual tamaño, haciendo algo como esto:

Table<Integer, Integer, Cell> table = HashBasedTable.create(); 
    Maps.transformValues(table.columnMap(), new ResizeFunction(BlockDimension.WIDTH)); 
    Maps.transformValues(table.rowMap(), new ResizeFunction(BlockDimension.HEIGHT)); 

public interface Cell { 
    int getSize(BlockDimension dimension); 
    void setSize(BlockDimension dimension); 
} 

ya tengo una idea de lo que el ResizeFunction debe ser. Sin embargo, necesito aplicar, no solo devolver un Collection.

Respuesta

13

En guayaba, no se convierten las listas existentes, sino que crear uno nuevo utilizando Iterables.transform:

final List<String> list = Arrays.asList("race", "box"); 
final List<String> transformed = 
    Lists.newArrayList(Iterables.transform(list, new Function<String, String>() { 

     @Override 
     public String apply(final String input) { 
      return new StringBuilder().append(input).append("car").toString(); 
     } 
    })); 
System.out.println(transformed); 

Salida:

[auto de carreras, furgón]

O, si no necesita un List y un Collection lo hará, puede utilizar una vista en vivo transformada:

final Collection<String> transformed = 
    Collections2.transform(list, new Function<String, String>() { 

     @Override 
     public String apply(final String input) { 
      return new StringBuilder().append(input).append("car").toString(); 
     } 
    }); 

Este Collection es una vista en vivo del subyacente, por lo que los cambios en list se reflejarán en este Collection.

+0

Lo siento, no estaba claro sobre la naturaleza del problema (ver arriba). Como puede ver, necesito aplicar la función a las colecciones de fila + columna y no estoy interesado en devolverlas. –

+0

Acepté porque esto es correcto, aunque todavía sostengo que la guayaba debería tener una función de aplicar() que se aplica inmediatamente a una colección. –

3

¿Qué pasa con la creación de una función como esta:

public static <T> void apply(Iterable<T> iterable, Function<T, Void> function) { 
    for (T input : iterable) 
     function.apply(input); 
} 
+0

Yo nombraría el método 'applyToEach'. Y puede usar 'Función ' como el tipo de parámetro, esto permite usar funciones con valores de retorno, en las que simplemente no está interesado. –

0

que creo que sería mejor de la creación de la mesa antes de que la población sea el tamaño apropiado/tiene el número apropiado de células, incluso si están vacíos. Algo así como:

for (int i=0; i<numRows; i++) 
    for (int j=0; j<numColumns; j++) 
     table.put(i,j,null); 

Esto garantizaría hay una celda para cada posición en la tabla. Siempre que solo agregue celdas en filas, posiciones de columnas que están dentro de numRows, numColumns, mantendrá una tabla "cuadrada".

1

Sean ya ha mencionado que la guayaba no cambia la colección original, por lo que no se puede "aplicar" una función a su colección existente.

No está claro lo que hace su función ResizeFunction, si sólo cambiando el valor de Cell en Table<Integer, Integer, Cell> entonces puede utilizar Tables#transformValues()

guayaba no le permiten cambiar los valores de R y C en Table<R, C, V> (en la clase estándar Tables) porque se utilizan como claves al devolver el mapa de fila o columna (Table#rowMap() y Table#columnMap()) y no se pueden transformar porque todos los métodos de Guava para transformar y filtrar producen resultados flojos significa que la función/predicado solo se aplica cuando es necesario el objeto es usado. Ellos no crean copias. Debido a eso, sin embargo, una transformación puede romper fácilmente los requisitos de un conjunto.

Si aún desea hacerlo, puede ajustar el objeto Table en su propia clase y proporcionar los métodos necesarios.

Cuestiones relacionadas