Is it possible to apply a function to a collection using Java Guava?
Solution 1
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
.
Solution 2
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);
}
Solution 3
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.
Garrett Hall
Updated on June 07, 2022Comments
-
Garrett Hall almost 2 years
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 aCollection
. -
Garrett Hall over 12 yearsSorry I wasn't clear about the nature of the problem (see above). As you can see I need to apply the function to the row+column collections and I am not interested in returning them.
-
Garrett Hall over 12 yearsI accepted since this is correct, although I still contend Guava should have an apply() function that immediately applies to a collection.
-
Paŭlo Ebermann about 10 yearsI would name the method
applyToEach
. And you can useFunction<T,?>
as the parameter type, this allows using functions with return values, in which you just aren't interested.