Можно ли применить функцию к коллекции с помощью Java Guava? - PullRequest
7 голосов
/ 16 сентября 2011

Я хочу применить функцию к коллекции, карте и т. Д., Используя Guava.

По сути, мне нужно изменить размер строк и столбцов Table отдельно, чтобы все строки и столбцы были равныразмер, делая что-то вроде этого:

    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);
}

У меня уже есть представление о том, каким должен быть ResizeFunction.Однако мне нужно применить это, а не просто вернуть Collection.

Ответы [ 4 ]

13 голосов
/ 16 сентября 2011

В Guava вы не конвертируете существующие списки, а вместо этого создаете новый, используя 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);

Выход:

[гоночный автомобиль, вагон]

Или, если вам не нужны List и Collection, вы можете использовать преобразованный вид в реальном времени:

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();
        }
    });

Этот Collection является живым представлением нижележащего, поэтому изменения в list будут отражены в этом Collection.

3 голосов
/ 16 сентября 2011

А как насчет создания такой функции:

public static <T> void apply(Iterable<T> iterable, Function<T, Void> function) {
    for (T input : iterable)
        function.apply(input);
}
1 голос
/ 18 сентября 2011

Шон уже упоминал, что Guava не меняет исходную коллекцию, поэтому вы не можете «применить» функцию к вашей существующей коллекции.

Непонятно, что делает ваша функция ResizeFunction, если вы изменяете только значение Cell в Table<Integer, Integer, Cell>, тогда вы можете использовать Tables # transformValues ​​()

Гуава не позволяет изменять значения R и C в Table<R, C, V> (в стандартном классе Tables), поскольку они используются в качестве ключей при возврате карты строк или столбцов (Table#rowMap() и Table#columnMap()) и вы не можете преобразовать их, потому что все методы преобразования и фильтрации в Guava дают ленивые результаты, что означает, что функция / предикат применяется только при необходимости, когда используется объект. Они не создают копии. Однако из-за этого преобразование может легко нарушить требования набора.

Если вы все еще хотите это сделать, вы можете обернуть объект Table в свой собственный класс и предоставить необходимые методы.

0 голосов
/ 17 сентября 2011

Я думаю, что было бы лучше настроить таблицу до того, как население будет иметь соответствующий размер / иметь соответствующее количество ячеек, даже если они пусты.Что-то вроде:

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

Это обеспечит наличие ячейки для каждой позиции в вашем столе.До тех пор, пока вы добавляете только ячейки в строки, позиции столбцов, которые находятся в пределах numRows, numColumns вы будете хранить «квадратную» таблицу.

...