文章目录
1、函数式接口介绍
函数式接口指的是有且仅有一个抽象方法的接口。 因为在Java 8中,新增了Lambda表达式,Lambda表达式为了实现自己推导方法,所使用的接口必须只能有一个抽象方法。所以,函数式接口就是专为Lambda而产生的特殊接口。
要定义一个函数式接口,那么该接口只能有一个抽象方法。为了确保只有一个抽象方法,同时也可以告诉别人这是一个抽象方法,我们通常在接口上添加一个注解:@FunctionalInterface。如果这个接口中的定义不满足函数式接口,那么就会报错。但是注解不是必需的,只是写上注解是良好的编程习惯。
/**
* @author RuiMing Lin
* @date 2020-03-16 20:38
*/
@FunctionalInterface
public interface MyFunctionalInterface {
public abstract void method1(); // 抽象方法
// 虽然函数式接口只能定义一个抽象方法,但是可以定义静态方法、默认方法、私有方法等
public static void method2(){
// ...
}
}
2、函数式接口的使用
定义一个函数式接口:
/**
* @author RuiMing Lin
* @date 2020-03-16 20:38
*/
@FunctionalInterface
public interface MyFunctionalInterface {
public abstract void method1(); // 抽象方法
}
定义一个函数式接口的实现类:
/**
* @author RuiMing Lin
* @date 2020-03-16 21:56
*/
public class MyFunctionalInterfaceImpl implements MyFunctionalInterface{
@Override
public void method1() {
System.out.println("使用实现类方式实现抽象方法");
}
}
定义一个测试类:
/**
* @author RuiMing Lin
* @date 2020-03-16 21:58
*/
public class Demo1 {
// 定义一个静态方法,调用函数式接口
public static void print(MyFunctionalInterface myFunctionalInterface){
myFunctionalInterface.method1();
}
public static void main(String[] args) {
// 1.使用方式一:实现类方式
print(new MyFunctionalInterfaceImpl());
// 2.使用方式二:使用匿名内部类方式
print(new MyFunctionalInterface() {
@Override
public void method1() {
System.out.println("使用匿名内部类方式实现抽象方法");
}
});
// 3.使用方式三:使用Lambda表达式
print(() -> System.out.println("使用Lambda实现抽象方法"));
}
}
关于Lambda的内容,可以看我另一篇博客的内容:
3、JDK内置的函数式接口
3.1、Supplier接口
Supplier 接口是java.util.function包下的一个函数式接口,该接口的抽象方法是一个无参的方法:T get() ,用来获取一个泛型参数指定类型的对象数据。
使用Supplier接口案例一:
import java.util.function.Supplier;
public class Demo2 {
private static String getString(Supplier<String> supplier) {
return supplier.get();
}
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "World";
System.out.println(getString(() ‐> str1 + str2));
}
}
使用Supplier接口案例二:
public class Demo3 {
public static int getMax(Supplier<Integer> supplier){
return supplier.get();
}
public static void main(String[] args) {
int arr[] = {1,3,100,300,10,30};
int maxNum = getMax(()‐>{
//计算数组的最大值
int max = arr[0];
for(int i : arr){
f(i > max){
max = i;
}
}
return max;
});
System.out.println(maxNum);
}
}
3.2、Consumer接口
Consumer 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。 它提供了一个抽象方法:void accept(T t) ,作用是使用一个指定泛型的数据。
import java.util.function.Consumer;
/**
* @author RuiMing Lin
* @date 2020-03-19 0:14
*/
public class ConsumerTest {
private static void consumeString(String string, Consumer<String> consumer) {
consumer.accept(string);
}
public static void main(String[] args) {
String str = "123456789";
consumeString(str, (s) -> {
StringBuffer reverse = new StringBuffer(s).reverse();
System.out.println("reverse = " + reverse);
});
}
}
3.3、Predicate接口
Predicate 接口用来对某种类型的数据进行判断,该接口包含一个抽象方法:boolean test(T t) 。
import java.util.function.Predicate;
/**
* @author RuiMing Lin
* @date 2020-03-19 0:26
*/
public class PredicateTest {
private static void method(String string, Predicate<String> predicate) {
boolean flag = predicate.test(string);
if (flag){
System.out.println("该字符串长度大于10");
}else {
System.out.println("该字符串长度不大于10");
}
}
public static void main(String[] args) {
String string = "abcde123456789";
method(string,s -> {
return s.length() > 10;
});
}
}
此外,Predicate接口还提供了三个默认方法,and()、or()、negate()
and()使用方式如下:
import java.util.function.Predicate;
/**
* @author RuiMing Lin
* @date 2020-03-19 0:26
*/
public class PredicateTest {
private static void method(String string, Predicate<String> predicate1, Predicate<String> predicate2) {
boolean flag = predicate1.and(predicate2).test(string);
if (flag){
System.out.println("该字符串长度大于10且小于等于20");
}
}
public static void main(String[] args) {
String string = "abcde123456789";
method(string,s -> {
return s.length() > 10;
},s -> {
return s.length() <= 20;
});
}
}
or()使用方式如下
import java.util.function.Predicate;
/**
* @author RuiMing Lin
* @date 2020-03-19 0:26
*/
public class PredicateTest {
private static void method(String string, Predicate<String> predicate1, Predicate<String> predicate2) {
boolean flag = predicate1.or(predicate2).test(string);
if (flag){
System.out.println("该字符串长度大于10或者小于等于5");
}
}
public static void main(String[] args) {
String string = "123";
method(string,s -> {
return s.length() > 10;
},s -> {
return s.length() <= 5;
});
}
}
negate()使用方式如下
import java.util.function.Predicate;
/**
* @author RuiMing Lin
* @date 2020-03-19 0:26
*/
public class PredicateTest {
private static void method(String string, Predicate<String> predicate) {
boolean flag = predicate.negate().test(string); // 对原结果取非
if (flag){
System.out.println("该字符串长度不大于10");
}
}
public static void main(String[] args) {
String string = "123";
method(string,s -> {
return s.length() > 10;
});
}
}
3.4、Function接口
Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。 Function 接口提供的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。
import java.util.function.Function;
/**
* @author RuiMing Lin
* @date 2020-03-19 0:40
*/
public class FunctionTest {
private static void method(String numStr,Function<String, Integer> function) {
// 将数字字符串转化为integer类型
int num = function.apply(numStr);
System.out.println(num + 20);
}
public static void main(String[] args) {
method("100",(str) -> {
return Integer.parseInt(str);
});
}
}
有错误的地方敬请指出!觉得写得可以的话麻烦给个赞!欢迎大家评论区或者私信交流!