函数式接口

函数式接口

函数式接口:有且仅有一个抽象方法的接口
格式:(只要确保接口中有且仅有一个抽象方法即可)

修饰符 interface 接口名称{
   public abstract 返回值类型 方法名称(可选参数信息)
// 其他非抽象方法内容
}

由于接口当中抽象方法的public abstract 是可以省略的:

public interface MyFunctionalInterface {
void myMethod();
}

@FunctionalInterface注解
@FunctionalInterface,该注解可用于一个接口的定义上:

@FunctionalInterface
public interface MyFunctionalInterface {
void myMethod();
}

ps:一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错
自定义函数式接口

public class Demo09FunctionalInterface {
// 使用自定义的函数式接口作为方法参数
private static void doSomething(MyFunctionalInterface inter) {
inter.myMethod(); // 调用自定义的函数式接口方法
}
public static void main(String[] args) {
// 调用使用函数式接口的方法
doSomething(()> System.out.println("Lambda执行啦!"));
}
}

常用函数接口

Supplier接口

java.util.function.Supplier 接口仅包含一个无参的方法: T get() 。用来获取一个泛型参数指定类型的对
象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。

package LambdaInterfaceDemo;

import java.util.function.Supplier;

public class Demo01Supplier {
    public static void main(String[] args) {
        String  s=getString(()->{
            return "胡歌";

        });
        System.out.println(s);
    }

    public static String getString(Supplier<String> sup){
        return sup.get();
    }
}

package LambdaInterfaceDemo;
/*练习:求数组元素最大值
使用Supplier接口作为方法参数类型,通过Lambda表达式求出int数组中最大值
提示:接口泛型请使用Java.lang.Interger
*/

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;

public class Demo02Suplier {
    //定义一个方法,用于获取int类型数组中元素的最大值,方法参数传递Supplier接口,泛型使用Integer
    public static int getMax(Supplier<Integer> sup){
        return sup.get();

    }
    public static void main(String[] args) {
        int[] arr ={10,2,4,-19,44};
        final int[] max = {arr[0]};
        //调用getMax方法,方法的参数Supplier是一个函数式接口,所以可以传递Lambda表达式
       int result = getMax(()->{
           //比遍历数组,获取数组其他元素
           for (int i:arr){
               if (i> max[0]){
                   max[0] =i;
               }
           }
           //返回最大值
           return max[0];
        });
        System.out.println(result);
    }
}

Consumer接口

java.util.function.Consumer 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。
抽象方法:accept

package LambdaInterfaceDemo;

import java.util.function.Consumer;
/*
Consumer接口中包含抽象方法void accept(T t),意为消费一个指定泛型的数据
定义一个方法
方法的参数传递一个字符串姓名
方法的参数传递Consumer接口,泛型使用String
可以使用Consumer接口消费字符串的姓名
*/

public class Demo02Consumer {
    public static void main(String[] args) {
       method1("赵丽颖",(String name)->{
           //System.out.println(name);
           String reName = new StringBuffer(name).reverse().toString();
           System.out.println(reName);
        });
    }

    public static void method1(String name,Consumer<String> con){
        con.accept(name);
    }
}

默认方法:andThen

package LambdaInterfaceDemo;

import java.util.function.Consumer;

/*Comsumer 默认方法andThen
作用:把两个Consumer接口组合到一起对数据进行消费
Consumer<String> con1
Consumer<String> con2
String s ="hello;
con1.accept(s);
con.2accept(s);
连接两个consumer接口在进行消费
con1.andThen(con).accept(s)

*/
public class Demo02AndThen {
    public static void main(String[] args) {
        method("Hello", (String s)->{
            System.out.println(s.toLowerCase());
        }, (String s)->{
            System.out.println(s.toUpperCase());
        });
    }

    public static void method(String s, Consumer<String> con1,Consumer<String> con2){
        //con1.accept(s);
        //con2.accept(s);
        con1.andThen(con2).accept(s);
    }

}

练习:格式化打印信息

package LambdaInterfaceDemo;
/*练习:字符串数组中存有多条信息,请按照格式“姓名:XX。性别:XX。”的格式将信息打印出来
要求将打印姓名的动作作为第一个Consumer接口的Lambda实例
将打印性别的动作作为打印Consumer接口的Lambda实例
将两个Consumeer接口按顺序拼接在一起
*/

import java.util.function.Consumer;

public class Demo02Practice {
    public static void main(String[] args) {
        //定义一个字符串型数组
        String[] str = {"迪丽热巴,女","古力娜扎,女","马儿扎哈,男"};
        //调用method方法,传递一个字符串数组和两个Lambda表达式
       /* method(str,(message)->{
            String name = message.split(",")[0];
            System.out.println(name);
        },(message)->{
            String sex =message.split(",")[1];
            System.out.println(sex);

        });*/
    }
    public static void method(Consumer<String> con1,Consumer<String> con2,String[] s){
        for (String message:s){
            con1.andThen(con2).accept(message);

        }

    }
}

Predicate接口

有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用java.util.function.Predicate 接口。
抽象方法:test
Predicate 接口中包含一个抽象方法: boolean test(T t) 。用于条件判断的场景:

package LambdaInterfaceDemo;

import java.util.function.Predicate;
/*
Predicate<T>接口作用:
对某种数据类型的数据进行判断,结果返回一个Boolean值
Predicate方法中包含一个抽象方法
boolean test(T t)//用来对指定数据类型进行判断的方法
*/
public class Demo02Predict {
    public static void main(String[] args) {
        String str= "ASCdfs";
        boolean boo =checkMethod(str,s->{
            return s.length()>8;
        });
        System.out.println(boo);

    }
    public static boolean checkMethod(String s, Predicate<String> pre){
        return pre.test(s);
    }
}

默认方法:and
既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个Predicate 条件使用“与”逻辑连接起来实现“并且”的效果时,可以使用default方法and

package LambdaInterfaceDemo;
/*逻辑表达式:可以连接多个判断的条件
&&:与运算符,有false则为false
||:或运算符,有true则为true
!:非(取反)运算符,非真则假,非假则真*/

import java.util.function.Predicate;

public class Demo02Predict_and {
    public static void main(String[] args) {
        String str="qwe123";
        boolean boo =checkString(str,s -> {
            return s.length()<4;
        },s -> {
            return s.length()>7;
                });
        System.out.println(boo);
    }

    public static boolean checkString(String s, Predicate<String>pre1,Predicate<String>pre2){
        return pre1.and(pre2).test(s);

    }
}

默认方法:or
与and 的“与”类似,默认方法or 实现逻辑关系中的“或”。
默认方法:negate
“与”、“或”已经了解了,剩下的非”(取反)也会简单。默认方法negate

Function接口

java.util.function.Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。
抽象方法:apply
Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。使用的场景例如:将String 类型转换为Integer 类型。

package LambdaInterfaceDemo;

import java.util.function.Function;

public class Demo02Function_apply {
    /*定义一个方法
    方法的参数传递一个字符串类型的整数
    方法的参数传递一个Function接口,泛型使用<String,Integer>
    使用Function接口中的apply,把字符串类型的整数,转换成Integer类型的整数
    */
    public static void main(String[] args) {
        //定义一个字符串类型整数
     /*   String str="567";
        change(str,(String,s)->{
            return Integer.parseInt(s);
        });
        */
    }
    public static void change(String s, Function<String,Integer> fun){
        int in=fun.apply(s);
        System.out.println(in);

    }

}

默认方法:andThen
Function 接口中有一个默认的andThen 方法,用来进行组合操作

package LambdaInterfaceDemo;

import java.util.function.Function;

public class Demo02Function_andThen {
    public static void main(String[] args) {
        String str ="123";
        change(str,(String s)->{
            return Integer.parseInt(s)+10;},
            (Integer i)->{
                return i+"";
        });
    }

    public static void change(String s, Function<String, Integer> fun1, Function<Integer, String> fun2){
        String ss=fun1.andThen(fun2).apply(s);
        System.out.println(ss);
    }
}

练习:自定义函数模型拼接

package LambdaInterfaceDemo;
/*练习:自定义函数拼接(使用Function)
String str = "赵丽颖,20";
分析:
1、截取字符串得到年龄部分的字符串
Function<String String> "赵丽颖,20"->"20"
2、将上一步的字符串转换int类型的数字
Function<String,Integer>"20"->20
3、将上一步的int数字累加100,得到结果int数字
Function<Integer,Integer>20->120
*/

import java.util.function.Function;

public class Demo02FunctionPractice {
   /* 定义一个方法
    参数传递包含姓名和年龄的字符串
    参数再传递3个Function接口用于类型转换*/
    public static void main(String[] args) {
        String ss = "赵丽颖,20";
        int num = method(ss, (String s) -> {
                    return s.split(",")[1];
                }, (String s) -> {
                    return Integer.parseInt(s);
                },
                (Integer i) -> {
                    return i + 100;
                });
        System.out.println(num);

    }
    public static int method(String s, Function<String,String> fun1,Function<String,Integer>fun2,Function<Integer,Integer> fun3){
        return fun1.andThen(fun2).andThen(fun3).apply(s);

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值