【笔记】Java8函数式接口

Java 8 functional interfaces

函数式接口是一个只有单个抽象方法的接口,可以通过默认方法扩充其实现。(以@FunctionalInterface在接口前声明)

内建函数库

java.util.Predicate

1
2
3
4
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}

接受单个参数,返回boolean值

示例

1
2
3
4
5
6
7
Predicate<Trade> largeTrade = (Trade t) -> t.isBigTrade();

Predicate<Trade> cancelledTrade = t -> t.isCancelledTrade();

Predicate<String> emptyStringChecker = s -> s.isEmpty();

Predicate<Employee> isExec = emp -> emp.isExec();
1
2
3
boolean cancelledTrade = cancelledTrade.test(t);

boolean executive = isExec.test(emp);

java.util.Function

1
2
3
4
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}

接受一个T类型的参数,返回一个R类型的结果

示例

1
2
3
4
5
6
7
8
9
// 摄氏度转换为华氏度
Function<Integer,Double> centigradeToFahrenheitInt = x -> new Double((x*9/5)+32);

// String转换为integer
Function<String, Integer> stringToInt = x -> Integer.valueOf(x);

// 测试
System.out.println("Centigrade to Fahrenheit: "+centigradeToFahrenheitInt.apply(centigrade))
System.out.println(" String to Int: " + stringToInt.apply("4"));
1
2
3
4
5
6
7
8
// Function to calculate the aggregated quantity of all the trades - taking in a collection and returning an integer!
Function<List<Trade>,Integer> aggegatedQuantity = t -> {
int aggregatedQuantity = 0;
for (Trade t: t){
aggregatedQuantity+=t.getQuantity();
}
return aggregatedQuantity;
};
1
2
3
4
5
6
7
8
9
10
11
12
// 使用Stream,map和reduce功能

aggregatedQuantity =
trades.stream()
.map((t) -> t.getQuantity())
.reduce(0, Integer::sum);

// 更好的方式
aggregatedQuantity =
trades.stream()
.map((t) -> t.getQuantity())
.sum();

其它方法

Consumer,Supplier

1
2
3
4
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
1
2
3
4
@FunctionalInterface
public interface Supplier<T> {
T get();
}

拓展

Java8还提供了这些方法的特殊版本.
UnaryOperator继承自Function,但之作用于相同的类型。当输入和输出的类型相同时,使用UnaryOperator而不是Function
UnaryOperator<String> toLowerUsingUnary = (s) -> s.toLowerCase();

也有应用于基本类型的方法版本,像DoubleUnaryOperator,LongUnaryOperator,IntUnaryOperator这些。
就像Function有子接口来应用于特殊情况,其他方法也有子接口像是IntPredicate,LongConsumer,BooleanSupplier等。IntPredicate代表一个整型值方法,LongConsumer则期望一个long类型的数值且不返回任何结果,BooleanSupplier则提供boolean类型的值。

两个参数的方法

1
2
3
4
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}

像这种的接口还有BiPredicate,BiConsumer,BiFunction,相比较之前的接口会多一个类型参数。
同样也有特殊版本,例如

1
2
3
//BinaryOperator是BiFunction的特殊版本

public interface BinaryOperator<T> extends BiFunction<T,T,T> { .. }