Utility functions

In order to ease the programmer of writing many redundant code, the library provides a lot of utility functions to deal with fields in the smoothest way possible. Most of theses functions are extension functions on fields of a specific type. While they are mainly a kotlin feature, it's still possible to call them in Java™ code through a static method, but it's a bit cumbersome. For this reason, it is suggested to use kotlin as much possible.

Most functions divide in two categories:

  • Transformations: they provide default implementations for either one-way or two-way transformation of fields.
  • Setters: available only on mutable fields, they easily allow to change the content of the field.

A thing to keep in mind is that the Field class is declared as Field<out T>, so any extension function of Field<A> will also be present in Field<B : A>, so for instance all extension functions of a Field<Collection> can also be called in a Field<List>, Field<Set> and so on. The same thing does not hold for mutable fields.

Furthermore, some functions have been implemented with operator overloading or with infix notation so, additionally to the standard way, they can also be called with their specific syntax.

Java™ usage

link

All these functions can be called in java code statically on their respective utils class. For extension functions the first parameter must always be the field you would call the function on in kotlin followed by the rest of the parameters. The utils class name is always FieldUtils prefixed with the name of the type contained in the field (e.g. for booleans it's BooleanFieldUtils). Example:

f1.and(f2)
BooleanFieldUtils.and(f1, f2);

Non-complete list

link

Here you can find a non-exhaustive list of extension functions. For the complete list as well as a complete description of what they do, please visit the specific page of the documentation.

In the following examples all fields starting with f (f, f1, f2, etc.) are simple Field, while all fields starting with mf (mf, mf1, mf2, etc.) are MutableField.

On all fields

link
//Transformations val f1 : Field<T>? = ... f1.orValue(v) //Yields f1 if f1 is not null, otherwise a constant field containing v f1.orNull() //Yields f1 if f1 is not null, otherwise a constant field containing null val f2 : Field<Field<T>> = ... f2.reduce() //Yields a Field<T> representing the value of the innermost field val f3 : Field<T?> = ... f3.notNull(v) //Yields a Field<T> cotaining the value of f3 if this value is not null, otherwise v val f4 : Field<T> = ... f3 eq f4 //Yields a Field<Boolean> that is true if the values of f3 and f4 are equals() f4 eq v //Yields a Field<Boolean> that is true if the value of f3 and v are equals() f3 neq f4 //Yields a Field<Boolean> that is true if the values of f3 and f4 are NOT equals()
//Transformations Field<T> f1 = ...; //f1 can be null FieldUtils.orValue(f, v); //Yields f1 if f1 is not null, otherwise a constant field containing v FieldUtils.orNull(f); //Yields f1 if f1 is not null, otherwise a constant field containing null Field<Field<T>> f2 = ...; FieldUtils.reduce(f2) //Yields a Field<T> representing the value of the innermost field Field<T> f3 = ...; //the value contained by f3 can be null f3.notNull(v) //Yields a Field<T> cotaining the value of f3 if this value is not null, otherwise v Field<T> f4 = ...; FieldUtils.eq(f3, f4); //Yields a Field<Boolean> that is true if the values of f3 and f4 are equals() FieldUtils.eq(f4, v); //Yields a Field<Boolean> that is true if the value of f4 and v are equals() FieldUtils.neq(f3, f4); //Yields a Field<Boolean> that is true if the values of f3 and f4 are NOT equals()

On Boolean fields

link
//Transformations f.not() f1 and f2 //Also or and xor //Setters mf.toggle()
//Transformations BooleanFieldUtils.not(f); BooleanFieldUtils.and(f1, f2); //Also or and xor //Setters BooleanFieldUtils.toggle(mf);

On Int fields

link
//Transformations (((f1 + 5) / 4) % -f2) * 17 //All operations between two Int fields or a field and an Int f.abs() //Absolute value min(f, 5) //min and max between two Int fields or a field and an Int f.toLong() //Convert to long, float and double //Setters mf.increment() //Also decrement() mf.negate()
//Transformations IntFieldUtils.times(IntFieldUtils.rem(IntFieldUtils.div(IntFieldUtils.plus(f1, 5), 4), IntFieldUtils.unaryMinus(f2)), 17); //All operations between two Integer fields or a field and an Integer. Since in java it's particularly verbose, in this case it is probably better using the transform() function manually IntFieldUtils.abs(f) //Absolute value IntFieldUtils.min(f, 5) //min and max between two Integer fields or a field and an Integer IntFieldUtils.toLong(f) //Convert to long, float and double //Setters IntFieldUtils.increment(mf); //Also decrement() IntFieldUtils.negate(mf);

On Long fields

link

The same functions that are available on Int fields are also available on Long fields with the appropriate modifications.

On Float fields

link
//Transformations (((f1 + 5f) / 4f) % -f2) * 17f //All operations between two Float fields or a field and a Float f1.pow(f2) //f1 elevated to the power of f2 sin(f3) //Sin of f3 f4.roundToLong() //f4 rounded to Long //Setters mf.increment(1.5f) //Also decrement() mf.negate()
//Transformations FloatFieldUtils.times(FloatFieldUtils.rem(FloatFieldUtils.div(FloatFieldUtils.plus(f1, 5f), 4f), FloatFieldUtils.unaryMinus(f2)), 17f); //All operations between two Float fields or a field and an Float. Since in java it's particularly verbose, in this case it is probably better using the transform() function manually FloatFieldUtils.pow(f1, f2) //f1 elevated to the power of f2 FloatFieldUtils.sin(f3) //Sin of f3 FloatFieldUtils.roundToLong(f4) //f4 rounded to Long //Setters FloatFieldUtils.increment(mf, 1.5f); //Also decrement() FloatFieldUtils.negate(mf);

On Double fields

link

The same functions that are available on Float fields are also available on Double fields with the appropriate modifications.

On String fields

link
//Transformations f1 + " world" //Concatenates the strings f1 + f2 //Concatenates the strings
//Transformations StringFieldUtils.concatenate(f1, " world"); //Concatenates the strings StringFieldUtils.concatenate(f1, f2); //Concatenates the strings
//Transformations f.length() //Yields a Field<Int> containing the length of the CharSequence
//Transformations CharSequenceFieldUtils.length(f) //Yields a Field<Integer> containing the length of the CharSequence

On Pair fields

link
//Transformations f.first() //Yields a Field<T> containing the first element of the pair in f f.second() //Yields a Field<T> containing the second element of the pair in f
//Transformations PairFieldUtils.first(f); //Yields a Field<T> containing the first element of the pair in f PairFieldUtils.second(f); //Yields a Field<T> containing the second element of the pair in f

On Triple fields

link
//Transformations f.first() //Yields a Field<T> containing the first element of the triple in f f.second() //Yields a Field<T> containing the second element of the triple in f f.third() //Yields a Field<T> containing the third element of the triple in f
//Transformations TripleFieldUtils.first(f); //Yields a Field<T> containing the first element of the triple in f TripleFieldUtils.second(f); //Yields a Field<T> containing the second element of the triple in f TripleFieldUtils.third(f); //Yields a Field<T> containing the third element of the triple in f

On Comparable fields

link
//Transformations f1 gt f2 //Yields a Field<Boolean> that is true when f1 > f2 f2 lte 5 //Yields a Field<Boolean> that is true when f2 <= 5 4 gte f3 //Yields a Field<Boolean> that is true when 4 >= f3
//Transformations ComparableFieldUtils.gt(f1, f2); //Yields a Field<Boolean> that is true when f1 > f2 ComparableFieldUtils.lte(f2, 5); //Yields a Field<Boolean> that is true when f2 <= 5 ComparableFieldUtils.get(4, f3); //Yields a Field<Boolean> that is true when 4 >= f3

On Collection fields

link
//Transformations f.isEmpty() //Yields a Field<Boolean> that is true when the content of f is empty f.size() //Yields a Field<Int> that contains the size of the collection contained in f //Setters mf.add(x) //Creates a new immutable collection consisting of the collection in f appended with x, then sets it to the field mf.remove(y) //Creates a new immutable collection consisting of the collection in f without y, then sets it to the field
//Transformations CollectionFieldUtils.isEmpty(f); //Yields a Field<Boolean> that is true when the content of f is empty CollectionFieldUtils.size(f); //Yields a Field<Integer> that contains the size of the collection contained in f //Setters CollectionFieldUtils.add(f, x); /Creates a new immutable collection consisting of the collection in f appended with x, then sets it to the field CollectionFieldUtils.remove(f, y); //Creates a new immutable collection consisting of the collection in f without y, then sets it to the field

Nearly all the extension functions of collections of Kotlin™ are available as an utility transformation function in Dataflow. A complete list can be found in the Kotlin documentation.

Most common ways of changing a collection are available but be careful! Each change you perform will create a new immutable list and discard the previous one, so you should consider every operation Ω(n) with respect to the collection size. The reason for this behavior is explained in detail in the section Restrictions on field values.

On Iterable fields

link
//Transformations f.contains(x) //Yields a Field<Boolean> that is true when the x is contained in the field f.filter(/* predicate */) //Yields a Field<Iterable<T>> that contains the values in f that match the predicate f.min() //Available on field of Iterable of numbers and Comparable, yields a Field<T> containing the min value (Also max())
//Transformations IterableFieldUtils.contains(f, x) //Yields a Field<Boolean> that is true when the x is contained in the field IterableFieldUtils.filter(f, /* predicate */) //Yields a Field<Iterable<T>> that contains the values in f that match the predicate IterableFieldUtils.min(f); //Available on numbers and Comparable, yields a Field<T> containing the min value (Also max())

Nearly all the extension functions of iterables of Kotlin™ are available as an utility transformation function in Dataflow. A complete list can be found in the Kotlin documentation.

On List fields

link
//Transformations f.firstOrNull(x) //Yields a Field<T> that contains the first element of the list in f, or null if it doens't exist //Setters mf.add(x) //Creates a new immutable list consisting of the list in f appended with x, then sets this list to the field mf.shuffle() //Creates a new immutable list with the same elements of the old one shuffled, then sets this list to the field
//Transformations ListFieldUtils.firstOrNull(f, x) //Yields a Field<T> that contains the first element of the list in f, or null if it doens't exist //Setters ListFieldUtils.add(mf, x); //Creates a new immutable list consisting of the list in f appended with x, then sets this list to the field ListFieldUtils.shuffle(mf); //Creates a new immutable list with the same elements of the old one shuffled, then sets this list to the field

Nearly all the extension functions of lists of Kotlin™ are available as an utility transformation function in Dataflow. A complete list can be found in the Kotlin documentation.

Most common ways of changing a list are available but be careful! Each change you perform will create a new immutable list and discard the previous one, so you should consider every operation Ω(n) with respect to the list size. The reason for this behavior is explained in detail in the section Restrictions on field values.

On Set fields

link
//Setters mf.add(x) //Creates a new immutable set consisting of the set in f appended with x, then sets it to the field mf.clear() //Creates a new immutable empty set and sets to the field
//Setters SetFieldUtils..add(mf, x); //Creates a new immutable set consisting of the set in f appended with x, then sets it to the field SetFieldUtils.clear(mf); //Creates a new immutable empty set and sets to the field

On Map fields

link
//Transformations f.keys() //Yields a Field<Set<K>> that contains the keys of the map in f f.count { /* predicate */ } //Yields a Field<Int> that contains the number of entries that satisfy the predicate //Setters mf.put(v1, v2) //Creates a new immutable map consisting of the map in f with the mapping (v1)=>(v2) added, then sets it to the field
//Transformations MapFieldUtils.keys(f); //Yields a Field<Set<K>> that contains the keys of the map in f MapFieldUtils.count(f, /* predicate */); //Yields a Field<Integer> that contains the number of entries that satisfy the predicate //Setters MapFieldUtils.put(mf, v1, v2) //Creates a new immutable map consisting of the map in f with the mapping (v1)=>(v2) added, then sets it to the field

Nearly all the extension functions of maps of Kotlin™ are available as an utility transformation function in Dataflow. A complete list can be found in the Kotlin documentation.

Most common ways of changing a map are available but be careful! Each change you perform will create a new immutable map and discard the previous one, so you should consider every operation Ω(n) with respect to the map size. The reason for this behavior is explained in detail in the section Restrictions on field values.