Question

are the functional interfaces of java 8 available somewhere (i.e. a jar) so I can use them in a Java 7 project? that way I could later on easier port the code to idiomatic java 8. if not, is that technically possible or do they make use of new features like default methods?

yes, i meant the interfaces in java.util.function. since adding packages with the java prefix seems to be disallowed importing them from somewhere else is not an option.

Was it helpful?

Solution

A functional interface is simply an interface with only one non-default, non-static method. All interfaces that satisfy that definition can be implemented through a lambda in Java 8.

For example, Runnable is a functional interface and in Java 8 you can write: Runnable r = () -> doSomething();.

Many of the functional interfaces brought by Java 8 are in the java.util.function package. The most common are:

  • Consumer<T> which has a void accept(T t)
  • Supplier<T> which has a T get()
  • Function<T, R> which has a R apply(T t)
  • Predicate<T> which as a boolean test(T t)

What you could do at this stage is to use single method interfaces wherever it makes sense, if possible with similar signatures. When you migrate to Java 8 you will be able to easily refactor through your IDE from:

someMethod(new MyConsumer<T>() { public void accept(T t) { use(t); } });

into

someMethod(t -> use(t));

Then change the signature of someMethod(MyConsumer<T> mc) into someMethod(Consumer<T> c), get rid of you MyConsumer interface and you are done.

OTHER TIPS

Here are the signatures of java 8 main functional interfaces as an addition to assylias answer

public interface Consumer<T> {
    void accept(T t);
}

public interface Supplier<T> {
    T get();
}

public interface Function<T, R> {
    R apply(T t);
}

public interface Predicate<T> {
    boolean test(T t);
}

The Java 8 functional interfaces are limited. Use the FunctionalJava types P1, F, F2, F3, ..., F8, TryCatch0, TryCatch1, ..., TryCatch8 to do the same thing now with more functionality.

https://functionaljava.ci.cloudbees.com/job/master/javadoc/

You can use the Retro Lambda project to compile with Java 8 and lambdas, but target the Java 7 VM. This avoids the whole anonymous inner class nonsense. See the FunctionalJava project for an example (http://www.functionaljava.org/).

In addition to the answer by @assylias which I think solves the problem in most cases, there is one more option, and that is, to make your own @FunctionalInterface and keep it that way.

It depends on where you use the functions. All of the aforementioned interfaces can be used by JDK utility classes. Predicate allows filtering, Supplier allows object creation, Function allows mapping ... In fact, Predicate and Supplier are rather straighforward, but Function and Consumer can be often unclear, especially BiFunction. They can also tie your hands in some use cases.

You can write your own interface that has any amount of inputs, throws checked exceptions, has generics only where you need them and its name says what it should be used for.

//@FunctionalInterface
public interface MyCustomInterface {
    <T> MyCustomOutput myCustomAction(MyCustomInput<T> str) throws MyCustomException;
}

So, while the interfaces provided with JDK are useful, sometimes you might prefer to keep your own solution even in Java 8, just with the annotations, and lambdas instead of anonymous classes.

There were few interfaces in Java 7 that can be termed as functional interface since they had only one abstract method which are Runnable, ActionListener, Comparable. Java 8 came with more functional interfaces like Function, Predicate, Consumer and Supplier.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top