This project consists of some useful helper classes and interfaces, which help to write more functional Java code.
This project consists of some useful helper classes and interfaces, which help to write more functional Java code.
The classes are:
-
FList
- contains static methods returning mostlyjava.util.List
s and acceptingIterable
s and arrays, likemap
,flatMap
,filter
, … -
F0
,F1
,F2
, … - Interfaces representing a function with n args where n is already in the name -
Procedure0
,Procedure1
,Procedure2
- Interfaces representing a procedure with n args where n is given by the name -
Optional
- An immutable class representing an optional value -
Either
- An immutable class representing either one of two values -
Tuple2
,Tuple3
, … - Classes representing tuples with n args where n is given by the name
All those classes and interfaces can be used with Java 5 and above. Although by their use, your code will not get more compact, but hopefully less errorprone.
import java.util.*;
import de.tototec.utils.functional.*;
import static de.tototec.utils.functional.FList.*;
List<String> names = Arrays.asList("Alice", "Bob", "Carlie", "Dylan");
// --> [Alice, Bob, Carlie, Dylan]
// Filtering
List<String> namesWithE = filter(names, new F1<String, Boolean>() {
public Boolean apply(String name) {
return name.contains("e");
}
});
// --> [Alice, Carlie]
// Java 8
List<String> namesWithE_ = filter(names, name -> name.contains("e"));
// Apply a function to all elements
List<String> namesUppercase = map(names, new F1<String, String>() {
public String apply(String name) {
return name.toUppercase();
}
});
// --> [ALICE, BOB, CARLIE, DYLAN]
// Java 8
List<String> namesUppercase_ = map(names, name -> name.toUppercase());
// --> [ALICE, BOB, CARLIE, DYLAN]
(Example will come later)
Functional Utils is available from Maven central repository.
Maven users can use the following dependency declaration:
<dependency>
<groupId>de.tototec</groupId>
<artifactId>de.tototec.utils.functional</artifactId>
<version>0.6.0</version>
</dependency>
SBuild users can use the following dependency:
"mvn:de.tototec:de.tototec.utils.functional:0.6.0"
Writing functional code can be much more pleasant if Java 8 Lambda expressions can be used. The function and procedure interfaces all fulfil the requirements for functional interfaces and can be thus implicitly inferred when lambda expressions are used.
Using the Java 8 lamdba expressions can grealty improve the functional experience. If you need to target an older Java Runtime, down to Java 5, you can still compile your code with a Java 8 compiler and afterwards postprocess the classfiles with the retrolambda tool. As long as you only use the Lambda syntax but no other new API from Java 8, your code will also run in Java 7 and before.
To use Retrolambda in your Maven project, you need to add something like this (please refer also to the Retrolambda website for more up to date information):
<plugin>
<groupId>net.orfjackal.retrolambda</groupId>
<artifactId>retrolambda-maven-plugin</artifactId>
<version>1.6.1</version>
<executions>
<execution>
<goals>
<goal>process-main</goal>
<goal>process-test</goal>
</goals>
</execution>
</executions>
</plugin>
Addionally, you should take extra measure to ensure no Java8 API slips through. This can be achieved with the animal-sniffer Maven plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.11</version>
<executions>
<execution>
<id>signature-check</id>
<phase>test</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java17</artifactId>
<version>1.0</version>
</signature>
</configuration>
</plugin>