一、函数式接口
理解FunctionalInterface(函数式接口)是学习Java8 Lambda表达式的基础。
函数式接口的定义
- 函数式接口是指在接口中只有一个抽象方法,可以使用 @FunctionalInterface注解来约束,有多个抽象方式就会报错(但若抽象方法为Object类中的方法,并不会报错)
- 函数式接口只能有一个抽象方法,所以在使用lambda表达式时,编译器可以根据上下文直接找到接口中的方法。
函数式接口的用处
- Java8中在java.util.function包下为我们提供了很多的函数式接口,如下图所示:
- 提供的函数式接口中最主要的有四个,其他函数式接口都是根据这四个进行扩展的,以方便我们的开发。
四个函数式接口
我只讲述下接口的抽象方法,至于默认方法和静态方法大家可以自行了解。
- 1、Consumer接口
接受一个T类型参数,但并不返回值
@FunctionalInterface
public interface Consumer<T> {
/**
* 接受一个T类型的参数,但并不返回值
* @param t 接收一个参数
*/
void accept(T t);
}
- 2、Function接口
接收一个T类型参数,返回一个R类型结果
@FunctionalInterface
public interface Function<T, R> {
/**
* @param t 接收一个参数
* @return 返回一个结果
*/
R apply(T t);
}
- 3、Supplier接口
不接收参数,返回一个结果
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
- 4、Predicate接口
接收T类型参数并返回boolean
@FunctionalInterface
public interface Predicate<T> {
/**
* @param 接受一个T类型参数
* @return 返回一个boolean值
*/
boolean test(T t);
}
Lambda表达式
- Java中Lambda表达式又被成为“闭包”或“匿名方法”,其格式:(param1、param2) ‐>{函数体};
使用Lambda来演示Consumer接口
public class TestConsumer {
public static void main(String[] args) {
// 创建一个List集合,集合元素为Integer
List<Integer> list = Arrays.asList(1,2,3,4,5);
System.out.println("-----------");
// (i)就是Consumer中所传递的参数,而{System.out.println(i);}则是通过lambda创建的实例对象
list.forEach((i) -> {System.out.println(i);});
System.out.println("-----------");
List<String> list2 = Arrays.asList("hello","lambda","hello lambda");
list2.forEach((i) -> {System.out.println(i);});
}
}
控制台输出结果如下:
-----------
1
2
3
4
5
-----------
hello
lambda
hello lambda
使用Lambda来演示Function接口
public class TestFunction {
public static void main(String[] args) {
// 创建一个TestFunction对象
TestFunction test = new TestFunction();
// (value) -> value * value 这部分就是通过lambda式创建出来的Function实例
// 作用就是将传进来的value进行平方,然后返回出去,这正好符合Function的定义,传入一个参数,返回一个结果
System.out.println("----------------");
System.out.println(test.calculate((value) -> value * value,3));
System.out.println("----------------");
System.out.println(test.calculate((value) -> value * value,4));
}
/**
* @Description: calculate用于计算一个函数值
* @param function 传入一个Function函数作为参数
* @param value 传入一个Integer参数用来计算的
* @return
*/
public int calculate(Function<Integer, Integer> function,Integer value){
return function.apply(value);
}
}
控制台输出:
----------------
9
----------------
16
使用Lambda来演Supplier接口
public class TestSupplier {
public static void main(String[] args) {
TestSupplier test = new TestSupplier();
// () -> Arrays.asList(1,2,3,5) 此处就是Supplier的一个实现
// 不传值获取一个List集合,Supplier常用于工厂模式中
List<Integer> result = test.getIntegerList(() -> Arrays.asList(1,2,3,5));
System.out.println("---------------------");
//遍历集合 (value) -> System.out.println(value) 此处相当于一个Consumer集合
result.forEach((value) -> System.out.println(value));
System.out.println("---------------------");
// 函数式接口实例还可以通过方法引用的方式来创建,这里就不再进行详解,我会在下篇文章进行介绍。
result.forEach(System.out::println);
}
/**
*
* @Description: 返回一个List
* @param supplier 传入一个supplier函数
* @return
*/
public List<Integer> getIntegerList(Supplier<List<Integer>> supplier){
return supplier.get();
}
}
控制台输出:
---------------------
1
2
3
5
---------------------
1
2
3
5
使用Lambda来演示Predicate接口
public class TestPredicate {
public static void main(String[] args) {
TestPredicate test = new TestPredicate();
// (value) -> value > 5 这部分其实就是lambda表达式生成的Predicate实例
// 作用:判断穿进去参数是否大于5,时则返回true,否则为false
System.out.println("---------------");
System.out.println(test.testMethod((value) -> value > 5 ,5));
}
public boolean testMethod(Predicate<Integer> predicate,Integer value){
return predicate.test(value);
}
}
控制台输出为:
---------------
false