functional interfaces of java 8 in java 7
Asked Answered
J

5

22

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.

Justinajustine answered 7/4, 2014 at 7:1 Comment(2)
Which interface are you interested in? Any interface that defines a single method is a functional interface, but the concept is not too useful without lambda expressionsKarole
It's basically that particular case of the Strategy pattern where the implementor classes implement only one abstract method. In Java 8 it's just syntactic sugar.Bluetongue
K
20

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.

Knapweed answered 7/4, 2014 at 7:58 Comment(6)
To add onto it, the interface needs to have one and only one non-default and non-static method. (Static methods are also allowed in functional interfaces)Ogren
@Ogren indeed amended.Knapweed
Since your own interfaces have to reside in a different package (you are not allowed to add to java. …), you can even name it Consumer rather than MyConsumer. And if the signature matches exactly, you can turn your own Consumer into a sub-interface of java.util.function.Consumer when migrating to Java 8.Conquest
As most answers here, this misses an important point. Doing so probably violates the JDK license if you ship this with a proprietary software.Dismember
@Dismember that would be a stretch considering that we are talking about well known patterns (supplier, consumer etc) with no implementation. But then IANAL...Knapweed
Tell that to Oracle lawyers. The famous Google vs Oracle lawsuit, which has been going on for more than a decade, is precisely on whether API interfaces are protected by the license or not.Dismember
M
10

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);
}
Mythology answered 30/7, 2014 at 16:22 Comment(0)
T
1

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/).

Tarragona answered 28/8, 2014 at 3:42 Comment(1)
They are limited for a reason. A generic 8-params function with 8 generic parameters is almost guaranteed to confuse whoever runs into that code.Piecework
P
0

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.

Piecework answered 13/11, 2017 at 9:27 Comment(0)
N
0

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.

Neurath answered 17/9, 2022 at 9:42 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.