Можно ли применить функцию к коллекции с помощью Java Guava?

Я хочу применить функцию к коллекции, карте и т. д., используя 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.


person Garrett Hall    schedule 16.09.2011    source источник


Ответы (4)


В 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.

person Sean Patrick Floyd    schedule 16.09.2011
comment
Извините, я не совсем понял природу проблемы (см. выше). Как видите, мне нужно применить функцию к коллекциям строк и столбцов, и я не заинтересован в их возврате. - person Garrett Hall; 16.09.2011
comment
Я согласился, поскольку это правильно, хотя я все еще утверждаю, что в Guava должна быть функция apply(), которая немедленно применяется к коллекции. - person Garrett Hall; 18.09.2011

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

public static <T> void apply(Iterable<T> iterable, Function<T, Void> function) {
    for (T input : iterable)
        function.apply(input);
}
person Garrett Hall    schedule 16.09.2011
comment
Я бы назвал метод applyToEach. И вы можете использовать Function<T,?> в качестве типа параметра, это позволяет использовать функции с возвращаемыми значениями, которые вам просто не интересны. - person Paŭlo Ebermann; 26.02.2014

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

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

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

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

person Premraj    schedule 18.09.2011

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

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

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

person John B    schedule 16.09.2011