I want to apply a function to a collection, map, etc, using Guava.
Basically, I need to resize the rows and columns of a Table
separately so all rows and columns are of equal size, doing something like this:
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);
}
I already have an idea of what the ResizeFunction
should be. However, I need to apply it, not just return a Collection
.
In Guava, you don't convert existing Lists, but instead create a new one using 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);
Output:
[racecar, boxcar]
Or, if you don't need a List
and a Collection
will do, you can use a transformed live view:
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();
}
});
This Collection
is a live view of the underlying one, so changes to list
will be reflected in this Collection
.
What about creating a function like this:
public static <T> void apply(Iterable<T> iterable, Function<T, Void> function) {
for (T input : iterable)
function.apply(input);
}
Sean has already mentioned that Guava don't change the original collection, so you can't really "apply" a function on your existing collection.
It's not clear what your ResizeFunction
function does, if you only changing the value of Cell
in Table<Integer, Integer, Cell>
then you can use Tables#transformValues()
Guava don't allow you to change the values of R
and C
in Table<R, C, V>
(in standard Tables
class) because those are used as keys while returning row or column map (Table#rowMap()
and Table#columnMap()
) and you cannot transform those because all of Guava's methods for transforming and filtering produce lazy results means the function/predicate is only applied when needed as the object is used. They don't create copies. Because of that, though, a transformation can easily break the requirements of a Set.
If you still want to do it then you can wrap Table
object in your own class and provide a required methods.
I think would would be better off setting up the table before population to be the appropriate size / have the appropriate number of cells even if they are empty. Something like:
for (int i=0; i<numRows; i++)
for (int j=0; j<numColumns; j++)
table.put(i,j,null);
This would ensure there is a cell for each position in your table. So long as you only add cells into row, column positions that are within numRows, numColumns you will keep a "square" table.