Functions

Functions are one of the main components of op4j. They are implementations of the org.op4j.functions.IFunction<T,R> interface, being T the input type and R the result type.

For example: IFunction<String,Integer> defines a function which takes a String as input and returns an Integer.

Inside expressions, functions are executed by the exec(...) action or by any of its variants: map(...), execAsArray(...), etc.

Predefined functions: Function hub classes

op4j provides more than 200 functions out-of-the-box. They are usually obtained by calling static methods in function hub classes. For example:

Function<String,String> fn = FnString.toUpperCase();

FnString is one of the predefined function hub classes (most of them start with Fn), and the toUpperCase() static method returns a function which takes a String input and returns a String result (IFunction<String,String>).

All predefined functions, as well as functions defined with function expressions are org.op4j.functions.Function objects, which are an implementation of IFunction adding a special execute(T input) method for easily calling them even outside op4j expressions.

Let's see some random examples:

Function<String,String> fn = FnString.trim();
Function<String,Calendar> fn = FnString.toCalendar("dd/MM/yyyy");
Function<Number,BigDecimal> fn = FnNumber.toBigDecimal(2, RoundingMode.HALF_UP);
Function<Iterable<Double>,Double> fn = FnDouble().avg();
Function<Iterable<Integer>,Integer> fn = FnInteger().max();
Function<String[],String[]> fn = FnArray.ofString().distinct();

As we can see, some function hub classes like FnArray are a little bit special because they require specialization (type parameterization), which is what is done with the ofString() method.

Let's see another example of specialization:

Type<User> type = ...;
Function<List<User[]>,List<User>> fn = FnList.ofArrayOf(type).flattenArrays();

User-defined functions

Function expressions

Functions can be created by means of Fn.on expressions:

Function<List<String>,List<Calendar>> fnParseStringDates =
    Fn.onListOf(Types.STRING).map(FnString.toCalendar("dd/MM/yyyy")).get();

As functions created with function expressions return org.op4j.functions.Function objects they can be easily called even outside op4j expressions:

List<Calendar> calendars = fnParseStringDates.execute(stringDates);  

Custom functions

Creating a custom function without using a function expression is as simple as implementing the one-method IFunction interface:

public class MyFunction implements IFunction<Integer,String> {

    public String execute(Integer input, ExecCtx ctx) throws Exception {
        return "The input number is: " + input;
    }
        
}

...which can also be done anonymously:

String result = 
    Op.on(value).exec(new IFunction<Integer,String>() {
        public String execute(Integer input, ExecCtx ctx) throws Exception {
            return "The input number is: " + input;
        }
    }).get();