1、 定义

函数式接口即是有且仅有一个抽象方法的接口。

注意:
(1)函数式接口只对于抽象方法有要求,对于接口中的默认方法,静态方法,私有方法数量并不作特殊要求。
(2)既然函数式接口定义了抽象方法,则对于函数式接口进行实现的类必须要实现其定义的抽象方法。

2、 函数式接口的创建

(1)直接定义一个只包含一个抽象方法的接口即可。
(2)在创建类时,使用@FunctionalInterface注解。示例如下:

@FunctionalInterface
interface MyFunctionInterface{
    //定义一个抽象方法
    public abstract void method();
}

3、 函数式接口的作用

函数式接口一般可以作为方法的参数或返回值类型。举一个应用的列子:

public class FunctionInterfaceUse {
    //定义一个方法,参数使用函数式接口
    public static void show(MyFunctionInterface myinter) {
        myinter.method();
    }

    public static void main(String[] args) {
         //调用show方法,因为方法的参数是一个接口,
        //所以可以传递接口的匿名内部类
        show(new MyFunctionInterface() {
            @Override
            public void method() {
                System.out.println("使用匿名内部类,重写接口中的抽象方法");
            }
        });

        //调用show方法,因为方法的参数是一个函数式接口,
        //所以可以使用Lambda表达式
        show(()->{
            System.out.println("使用lambda表达式,重写接口中的抽象方法");
        });
    }
}

4、常用的函数式接口

4.1 Supplier接口:生产型接口。

Supplier接口的泛型是什么类型, 调用Supplier接口中唯一的抽象方法get时,就会生产什么类型的数据。
抽象方法 T get();
代码示例:

public class MultiFuntionInterface {
    //Supplier的使用
    public static String getString(Supplier<String> sup) {
        return sup.get();
    }

 public static void main(String[] args) {
        //调用getstring方法
        String s=getString(()->{
            //生产一个字符串并返回
            return "jay";
        });
        System.out.println(s);
	}
}
4.2 Consumer接口:消费性接口。

Consumer接口中的泛型为什么类型,就可以使用Consumer接口中的抽象方法accept接收什么类型的数据,至于如何使用,需要对于该方法进行自定义实现。
抽象方法 void accept(T t);
默认方法 Consumer andThen(Consumer<? super T> after);
andThen方法用于连接两个消费性接口,共享同一个接受数据。两个消费性接口谁在前,谁先消费。
代码示例:

public class MultiFuntionInterface {
  //Consumer接口的使用
    public static void method(String name,Consumer<String> con){  	  			
			con.accept(name);
    }

 //Consumer接口的使用,两种使用
    public static void method2(String name,Consumer<String> con1,Consumer<String> con2) {
        con1.accept(name);
        con2.accept(name);
        //使用andThen方法,将两个接口连接,再进行消费
        con1.andThen(con2).accept(name);//该语句与以上两个语句效果等价
    }
public static void main(String[] args) {
        //Consumer接口的使用method
        method("jj",(name)->{
            //对传递的字符进行消费
            System.out.println(name);
            //消费方式:把字符串翻转
            String aname=new StringBuilder(name).reverse().toString();
            System.out.println(aname);
        });

        //Consumer接口的使用method2
        method2("jay",(name)->{
            System.out.println(name.toUpperCase());
        },(name)->{
            System.out.println(name.toLowerCase());
        });
	}
}
4.3 predicate接口:判断型接口

predicate接口对test方法的输入参数和泛型类型的数据进行判断,相等为true,不等为false,从而得到一个boolean值。
抽象方法: boolean test(T t);
默认方法: 默认方法用来连接多个判断性接口对于数据的判断接口。逻辑运算方法有以下三种:

Predicate<T> and(Predicate<? super T> other):与
    Predicate<T> or (Predicate<? super T> other):或
    Predicate<T> not(Predicate<? super T> other):非

代码示例:

public class MultiFuntionInterface {
  //Predicate函数式接口的使用
    public static boolean judgeMethod(String s,Predicate<String> pre){
       return  pre.test(s);
    }

    //Predicate函数式接口的使用,两个条件
    public static boolean judgeMethod1(String s,Predicate<String> pre,Predicate<String> pre1){
        //return pre.test(s)&&pre1.test(s);
        return pre.and(pre1).test(s);
        //return pre.or(pre1).test(s);
        //return pre.negate().test(s);
    }

   public static void main(String[] args) {
           //Predicate的使用
        String s1="abcd";
        boolean b=judgeMethod(s1,(String str)->{
            return str.length()>5;
        });
        System.out.println(b);

        boolean b1=judgeMethod1(s1,(String str)->{
            //判断字符串长度是否大于5
            return str.length()>5;
        },(String str)->{
            //判断字符串中是否包含a
          return str.contains("a");
        });
        System.out.println(b1);
	}
}
4.4 Function<T,R>:转换型接口。

Function<T,R>接口中的抽象方法apply将一个类型T的数据转化后得到另一个类型R的数据。
抽象方法: R apply(T t); 输入形参类型为T,返回值类型为R。
默认方法: 用以组合操作,区别如下:
andThen(Function<? super R,? extends V> after):谁调用的andThen,谁执行时在前。
compose(Function<? super V,? extends T> before):谁调用的compose,谁执行时在后。
代码示例:

public class MultiFuntionInterface {
  	 //Function<T,R>类型的使用
       public static void changeType(String s, Function<String,Integer> f){
        Integer in=f.apply(s);//接收String类型,返回Integer类型
        System.out.println(in);
   	 }

   	 public static void main(String[] args) {
		//Function接口的使用
        changeType(s,(String str)->{
            //接口的具体实现
            return Integer.parseInt(str);
        });
	//默认方法andThen的使用
	Function<String, String> function = a -> a + " 小明!";
	Function<String, String> function1 = a -> a + " 张三!";
	String greet = function.andThen(function1).apply("你好");
	System.out.println(greet); // 你好 小明! 张三!
	
	//默认方法compose的使用
	Function<String, String> function = a -> a + " 小明!";
	Function<String, String> function1 = a -> a + " 张三!";
	String greet = function.compose(function1).apply("你好");
	System.out.println(greet); // 你好 张三! 小明! 
}