前言
lambda表达式是Java JDK8的新特性,可以避免定义多过的匿名内部类,写出更优雅的Java代码。但是它有一个前提,调用的接口必须是函数式接口,要求接口里只有一个待实现的抽象方法,通常会在接口头部写上注解@FunctionalInterface。
// 接口定义
@FunctionalInterface
interface MyFunctional {
void do(String str);
}
// 接口使用
MyFunctional functional = str -> System.out.println(str);
functional.do("something");
一、Consumer(消费型)
接收一个类型T的参数,没有返回值。
源码介绍
@FunctionalInterface
public interface Consumer<T> {
/**
* 接收一个类型T的参数,没有返回值。
*/
void accept(T t);
/**
* 相当于链式操作,对给定的参数进行多次操作。
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
代码示例
public static void main(String[] args) {
// 方法一:普通方法
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
consumer.accept("hello world");
// 方法二:lambda表达式
Consumer<String> consumer2 = str-> System.out.println(str);
consumer2.accept("gogogo");
// andThen 方法
consumer.andThen(consumer2).accept("xiaoming");
}
二、Supplier(供给型)
不接受任何参数,返回类型T的结果。
源码介绍
@FunctionalInterface
public interface Supplier<T> {
/**
* 不接受任何参数,返回类型T的结果。
*/
T get();
}
代码示例
public static void main(String[] args) {
// 方法一:普通方法
Supplier<String> supplier = new Supplier() {
@Override
public String get() {
return "hello world";
}
};
System.out.println(supplier.get());
// 方法二:lambda表达式
Supplier<String> supplier2 = () -> "hello world";
System.out.println(supplier2.get());
}
三、Function(函数型)
接收一个类型T参数,返回一个类型R的结果。
源码介绍
@FunctionalInterface
public interface Function<T, R> {
/**
* 接收一个类型T参数,返回一个类型R的结果。
*/
R apply(T t);
/**
* 相当于链式操作,先将给定的参数传入before进行操作,操作结果再使用外层函数进行操作。
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 相当于链式操作,先将给定的参数传入外层函数进行操作,操作结果再使用after进行操作。
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* 返回该函数的参数。
*/
static <T> Function<T, T> identity() {
return t -> t;
}
}
代码示例
public static void main(String[] args) {
// 方法一:普通方法
Function<Integer, Integer> function = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer i) {
return i + i;
}
};
System.out.println(function.apply(2));
// 方法二:lambda表达式
Function<Integer, Integer> function2 = (i) -> i * i;
System.out.println(function2.apply(3));
// compose 方法
System.out.println(function.compose(function2).apply(4));
// andThen 方法
System.out.println(function.andThen(function2).apply(4));
// identity 方法 相当于 this -> this
Arrays.asList("a", "b", "c").stream()
.map(Function.identity()) // <- This,
.map(str -> str) // <- is the same as this.
.collect(Collectors.toMap(
Function.identity(), // <-- And this,
str -> str)); // <-- is the same as this.
}
四、Predicate(断言型)
接收一个类型T的参数,给出判断结果。
源码介绍
@FunctionalInterface
public interface Predicate<T> {
/**
* 接收一个类型T的参数,给出判断结果。
*/
boolean test(T t);
/**
* 先使用外层方法判断,再使用other方法判断,理解为:this&&other
*/
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
/**
* 先使用外层方法判断,将结果值进行取反,理解为:!this
*/
default Predicate<T> negate() {
return (t) -> !test(t);
}
/**
* 先使用外层方法判断,再使用other方法判断,理解为:this||other
*/
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
/**
* 使用外层方法判断,再和other方法结果进行比较,理解为:this==other
*/
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
代码示例
public static void main(String[] args) {
// 方法一:普通方法
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
return s.isEmpty();
}
};
System.out.println(predicate.test("1024"));
// 方法二:lambda表达式
Predicate<String> predicate2 = (str) -> str.isEmpty();
System.out.println(predicate2.test(""));
// and 方法
System.out.println(predicate.and(predicate2).test("1024"));
// or 方法
System.out.println(predicate.or(predicate2).test("1024"));
// negate 方法
System.out.println(predicate.negate().test("1024"));
// isEqual 方法
System.out.println(Predicate.isEqual("1024"));
}
五、总结
整理:
| 函数式接口 | 参数类型 | 返回类型 | 用途 |
|---|---|---|---|
| Consumer | T | void | 接收一个类型T的参数,没有返回值。 |
| Supplier | 无 | T | 不接受任何参数,返回类型T的结果。 |
| Function<T,R> | T | R | 接收一个类型T参数,返回一个类型R的结果。 |
| Predicate | T | boolean | 接收一个类型T的参数,给出判断结果. |
作用:
- 函数式接口里有默认方法和静态方法,不需要重写即可使用。
- 结合Java的面向对象编程思想,函数式接口就是将方法当做“对象”进行传输。
- 在Java jdk8 新特性stream流中,函数式接口被大量使用。