1. Stepan Koltsov
  2. bolts

Wiki

Clone wiki

bolts / Ru / Function

Перейти к оглавлению * In English

Объекты-функции

Функция в bolts — это наследник одного из абстрактных классов Function*. Классы Function* — это:

Function — самый простой, честный, главный класс, описывающий функцию с одним аргументом, возвращающий объект. Все остальные классы функций — частные случаи.

Все абстрактные классы функций Function* содержат ровно один абстрактный метод apply, и все классы различаются сигнатурой этого метода.

Про метод apply

Сигнатура метода apply класса Function — R apply(P1).

Для остальных классов Function* применяются такие соглашения: Цифра показывает количество аргументов. Буква, если она присутствует, показывает тип возвращаемого значения: B — boolean, I — int, V — void.

Например,

класс Function2I<P1, P2> содержит метод int apply(P1, P2)

класс Function1B<P1> содержит метод boolean apply(P1)

Простое объяснение

Но вообще, всё это понимать необязательно. Для большинства случаев достаточно запомнить, что класс Function — это mapper — т. к. функция, превращающая один объект в другой, а Function1B — это предикат — функция, возвращающая по объекту значение — истина или ложь.

Как построить объекты функции

Основные способы построения объекты функций — это написание анонимныых классов, комбинация других функций и связывание аргументов.

Анонимный класс

Примеры двух функций. Допустим, есть класс User с полем String login. Нужна функция, которая будет доставать из класса User поле login. Обычно это делается так:

class User {
  String login;
  ...
  public static Function<User, String> loginF() {
    return new Function<User, String>() {
      public String apply(User user) {
        return user.login;
      }
    };
  }
}

Получается достаточно много кода, но современные IDE (Idea, Eclipse) позволяют писать такой код очень быстро.

Пример другой функции: предикат, который возвращает, пустая ли строка:

static Function1B<String> emptyF() {
  return new Function1B<String>() {
    public boolean apply(String string) {
      return string == null || string.length == 0;
    }
  }
}

Комбинация функций

Допустим, надо построить предикат от класса User — он будет возвращать истину, когда логин непустой. Это можно сделать комбинацией функций, описанных выше: должна применяться функция loginF, к её результату должен применяться предикат emptyF, и к результату должно применяться отрицание. В коде выглядит это так:

User.loginF().andThen(StringUtils.emptyF()).notF();

Комбинирование функций — очень мощный механизм.

связывание аргумента (bind)

Из функции с N аргументами можно сделать функцию с N-1 аргументом связав некоторый аргумент с некоторым значением. Для этого во всех классах Function* есть методы bindK, 0 <= K < N. Пример. Допустим, есть функция, которая конкатенирует строки:

Function2<String, String, String> plusF() {
  return new Function2<String, String, String>() {
    public void apply(String a, String b) {
      return a + b;
    }
  };
}

Это функция от двух аргументов. Из неё можно получить функцию с одним, аргументом, которая добавляет префикс к строке:

plusF().bind1("(") // функция добавляет скобку в начало строки
plusF().bind2(")") // функция добавляет скобку в конец строки

Таким образом, функция, которая строку заключает в скобки может выглядеть так:

plusF().bind1("(").andThen(plusF().bind2(")"))

Коллекции

Чаще всего функции используются для операций над коллекциями.

Updated