Java) Functional Interfaces / util.function
Java) Functional Interfaces / util.function
This post was migrated from Tistory. You can find the original here.
Lambda expressions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@FunctionalInterface
interface MyFunction {
void run(); // public abstract void run();
}
class Main {
static void execute(MyFunction f) { // a method whose parameter type is MyFunction
f.run();
}
static MyFunction getMyFunction() { // a method whose return type is MyFunction
MyFunction f = () -> System.out.println("f3.run()");
return f;
}
public static void main(String[] args) {
// Implement MyFunction's run() with a lambda expression
MyFunction f1 = ()-> System.out.println("f1.run()");
// A lambda expression is an object of an anonymous class.
// Its type must be an interface that defines a method equivalent to the lambda.
MyFunction f2 = new MyFunction() { // implement run() with an anonymous class
public void run() { // public must be specified
System.out.println("f2.run()");
}
};
MyFunction f3 = getMyFunction();
f1.run();
f2.run();
f3.run();
execute(f1);
execute( ()-> System.out.println("run()") );
}
}
Result
f1.run()
f2.run()
f3.run()
f1.run()
run()
Being able to treat a lambda expression as a reference variable means methods can now be passed around just like variables.
Look closely at the comment on f2 — under the hood, what’s actually being passed around is an object, not a method, so fundamentally nothing has changed.
Functional interfaces provided by java.util.function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.function.*;
class Main{
public static void main(String[] args) {
Supplier<Integer> supply = () -> 1;
System.out.println(supply.get());
Consumer<Integer> consumer = v -> System.out.println(v);
consumer.accept(2);
Function<Integer, String> func = String::valueOf;
System.out.println(func.apply(3));
Predicate<Integer> func2 = v-> v>5;
System.out.println(func2.test(4));
}
}
Result
1
2
3
false
There are also others, such as java.lang.Runnable, BiConsumer<T, U>, BiPredicate<T, U>, BiFunctionM<T, U, R>.
1
2
3
4
5
6
7
Predicate<Integer> p = i -> i < 100;
Predicate<Integer> q = i -> i < 200;
Predicate<Integer> r = i -> i%2 == 0;
Predicate<Integer> notP = p.negate(); // i >= 100
Predicate<Integer> all = notP.and(q.or(r)); // 100<=i && (i<200 || i% 2==0)
System.out.println(all.test(150)); // true
Predicate<T> instances can be combined.
Functional interfaces in the Collections Framework
1
2
3
4
5
6
(Collection).removeIf(Predicate<E> f);
(List).replaceAll(UnaryOperator<E> f);
(Iterable).forEach(Consumer<T> f);
(Map).forEach(BiConsumer<K,V> f);
(Map).compute(K key, BiFunction<K,V,V> f) // performs operation f on the given key
These are methods in the Collections Framework that make use of functional interfaces.
This post is licensed under CC BY-NC 4.0 by the author.