JDK1.8 函数式编程之函数式接口
1.概述
- 概念:
有且仅有一个抽象方法的接口 - 如何检测一个接口是不是函数式接口
@FunctionalInterface 接口
放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败 - 总结:
适用于lambda,专注做一件事情的接口。
2.常用接口↓↓↓
在函数式接口和Lambda表达式出现后,Java官方为我们提供了一些简单的函数式接口来完成一些操作(支持Stream流操作),Stream流的操作中我们会使用这些接口,因此学习如何使用这些接口是我们后续学习Stream流的前提条件,稍后我们在Stream流的学习中也会提到。
3.Supplier 接口
- 描述
Supplier:供应商
我将其称之为提供者接口,其功能方法是 T get()。
在接口实现中对实例进行构建并返回。
- 代码:T get()
public class Supplier_Practice {
public static void main(String[] args) {
String str = getString(() -> {
return "supplier interface";
});
System.out.println(str);
}
private static String getString(Supplier<String> stringSupplier) {
return stringSupplier.get();
}
}
4.Consumer 接口
- 描述
Consumer :消费者
我将其称之为使用者接口,其功能方法是 void accept(object)。
传入一个参数,对其进行操作,无返回值。
- 代码:void accept(object)
public class Consumer_Practice {
public static void main(String[] args) {
String str = "chenfeilin";
consumerString((String s) -> {
System.out.println(s.toUpperCase());
}, str);
}
private static void consumerString(Consumer<String> stringConsumer, String str) {
stringConsumer.accept(str);
}
}
- 代码:andThen(Consumer<? super T> after)
返回一个组成的 Consumer ,依次执行此操作,然后执行 after操作。
// 一个简单的实体类
public class Student {
private String name;
private int age;
private String address;
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
public class Consumer_Practice {
public static void main(String[] args) {
Student student = new Student();
consumerTwo((Student s1) -> {
s1.setName("chenfeilin");
}, (Student s2) -> {
s2.setAddress("雷克雅未克");
s2.setAge(777);
}, student);
System.out.println(student);
}
private static void consumerTwo(Consumer<Student> stringConsumer1,
Consumer<Student> stringConsumer2, Student student) {
// 依次消费
stringConsumer1.andThen(stringConsumer2).accept(student);
}
}
控制台输出:
Student{name=‘chenfeilin’, age=777, address=‘雷克雅未克’}
- 注意:
对于String 类型,这个消费者的结果不会反应到原引用的值上,我们看实例代码
public class Consumer_Practice {
public static void main(String[] args) {
String str = "chenfeilin";
consumerString((String s) -> {
s = s.toUpperCase();
System.out.println(s);
}, str);
System.out.println(str);
}
private static void consumerString(Consumer<String> stringConsumer, String str) {
stringConsumer.accept(str);
}
}
控制台输出结果:
CHENFEILIN
chenfeilin
String str 对象的值并没有改变。
5.Predicate 接口
- 描述
Predicate :断言
我将其称之为判断者接口,其功能方法是 **boolean test(Object) **。
传入一个参数值,返回一个判断结果。
- 代码:boolean test(Object)
public class Predicate_Practice {
public static void main(String[] args) {
String str = "chenfeilin";
checkString((String s) -> {
return s.length() > 3;
}, str);
}
private static void checkString(Predicate<String> stringPredicate, String str) {
boolean test = stringPredicate.test(str);
if (test) {
System.out.println("OK");
} else {
System.out.println("NG");
}
}
}
输出结果为:OK
-
补充:作为一个断言,其判断条件应该是有组合形式的,例如 && || 等
-
代码:
public class Predicate_Practice {
public static void main(String[] args) {
String str = "chenfeilin";
moreCheck((String s1) -> {
return s1.length() > 5;
}, (String s2) -> {
return s2.startsWith("ccc");
}, str);
}
private static void moreCheck(Predicate<String> stringPredicate1,
Predicate<String> stringPredicate2, String str) {
boolean test1 = stringPredicate1.and(stringPredicate2).test(str);
boolean test2 = stringPredicate1.or(stringPredicate2).test(str);
boolean test3 = stringPredicate1.negate().test(str);
System.out.println(test1);
System.out.println(test2);
System.out.println(test3);
}
}
输出结果:
false
true
false
6.Function 接口
- 描述
Function:功能
我将其称之为加工者接口,其功能方法是 **apply(Object) **。
传入一个参数(T类型),返回一个值(R类型)。
- 代码:apply(Object)
public class Function_Practice {
public static void main(String[] args) {
int count = 33;
function((Integer a) -> {
return String.valueOf(a + 100);
}, count);
}
private static void function(Function<Integer, String> integerStringFunction, int a) {
String result = integerStringFunction.apply(a);
System.out.println(result);
}
}
输出结果为:133
- 代码补充:andThen(Function<? super R,? extends V> after)
例如一个Function1的输入类型为A,输出类型为B,另一个Function2的入力参数类型刚好为B,则其可以形成一个链路,将Function1的返回值作为Function2的入力值,进行多次“加工”
public class Function_Practice {
public static void main(String[] args) {
int count = 33;
moreFunction((Integer a) -> {
return String.valueOf(a + 100);
}, (String str) -> {
return str.length() > 2;
}, count);
}
private static void moreFunction(Function<Integer, String> function1,
Function<String, Boolean> function2, int a) {
Boolean aBoolean = function1.andThen(function2).apply(a);
System.out.println(aBoolean);
}
}