Jdk8新特性三:jdk8之函数式编程Function

Jdk8新特性三:jdk8之函数式编程Function

文章目录

      • Jdk8新特性三:jdk8之函数式编程Function
        • Function接口的使用
        • BiFunction接口解决传入两个参数问题
        • JDK8函数式编程消费型接口Consumer\

Function接口的使用

  1. Lambda表达式必须先定义接口,创建相关方法后才能使用,这样弄十分不便,干脆开发者就直接内置了接口,所有标注@FunctionalInterface注解的接口都是函数式接口。
  2. jdk8内置的四大核心函数式接口

Consumer:消费型接口,有入参,无返回值。

​ void accept(T t);

Supplier:供给型接口:无入参,有返回值

​ T get();

Function:函数型接口,有入参,有返回值

​ R apply(T t);

Predicate:断言型接口,有入参,有返回值,返回值类型确定是boolean

​ boolean test(T,t);

  1. Function:传入一个值,经过函数的计算返回另一个值(T,入参类型,R:出参类型)
//这个就相当于声明了一个函数变量,和js很像,然后调用这个函数。之所以能这样写是因为
Function<Integer,Integer> func=p->{
    System.out.println("我是函数");
    return p*100;
};
func.apply(5);
  1. 如果用lambda表达式可以这样写
//也可以这样写,定义了一个函数的行为。p->p*12,因为Function本身就是一个函数式编程,可以将函数作为参数进行传递。
Function<Integer,Integer> func2=p->p*12;
System.out.println(func2.apply(5));

BiFunction接口解决传入两个参数问题

  1. 可以通过Ctrl+Shift+n查找BiFunction类。可以看到也是函数式编程。可以传入两个参数。用法和上面一个参数的一样。
System.out.println(opreator(1,2,(a,b)->a+b));
System.out.println(opreator(1,2,(a,b)->a*b));
BiFunction<Integer,Integer,Integer> bin=(a,b)->a+b;
System.out.println(bin.apply(5,10));
BiFunction<Integer,Integer,Integer> bin2=(a,b)->{
    System.out.println("我是bin2");
    return a*b;
};
System.out.println(bin2.apply(5,10));
public static Integer opreator(Integer a, Integer b, BiFunction<Integer,Integer,Integer> bf){
    return bf.apply(a,b);
}

JDK8函数式编程消费型接口Consumer

  1. Consumer 有入参,无返回值。idea中可以通过ctrl+shift+n输入Consumer.java找到源代码。没有返回值主要的应用场景打印日志,发送短信
    Consumer<String> consumer=obj->{
        //这里面可以写很多逻辑
        System.out.println(obj);
        System.out.println("调用短信接口发送短信,或者打印日志");
    };
    //consumer.accept("88888");
    sendMsg("88888",consumer);
    List<String> list= Arrays.asList("aaa","bbb","ccc");
    list.forEach(obj->{ 
        System.out.println(obj);
	});
public static void sendMsg(String phone,Consumer<String> consumer){
    consumer.accept(phone);//consumer代表一个函数,phone是接收的参数。accept()方法表示这个函数运行这个参数。类似于开启新线程中的start()
}

Jdk8函数式编程供给型接口Supplier

  1. Supplier是供给型接口,无入参,有返回值 。也就是没有入参。
  2. 运用场景:如果项目中你需要一些实体类需要有默认值,而有些地方不需要默认值,我们如何处理呢?我们可以设计一个工厂模式,工厂对实体类生产两种产品,一个有默认值,一个没有默认值。
public static Student newStudent(){
    Supplier<Student> supplier=()->{
        Student student=new Student();
        student.setName("默认名称");
        return student;
    };
    return supplier.get();
}
  1. 这样我们只需要实例化这个newStudent就可以了。注意里面写的lambda表达式。是定义一个supplier的函数,然后在结尾supplier.get()方法进行调用,自己调用自己。
Student student=newStudent();
System.out.println(student.getName());

Jdk8函数式编程之断言型接口:Predicate

  1. Predicate:断言型接口,有入参,有返回值,返回值类型确定是boolean.T为入参类型,出参类型为Boolean
  2. 用途:接收一个参数,用于判断是否满足一定的条件,过滤数据。
public static List<String> filter(List<String> list,Predicate<String> predicate){
    List<String> results=new ArrayList<>();
    for(String str:list){
        if(predicate.test(str)){
            results.add(str);
        }
    }
    return results;
}
  1. 调用函数
List<String> list=Arrays.asList("difjisfj","343dfjsj","kfjsidj","34dfjs","djfsi");
System.out.println(list);
List<String> a = filter(list, (obj) -> obj.startsWith("a"));
List<String> filter2 = filter(list, (obj) -> {
    return obj.startsWith("3");
});
System.out.println(a);

Jdk8方法与构造函数的引用

  1. 之前调用方法操作:对象.方法,类名.方法。前面是实例方法,后面是静态方法。
  2. jdk8提供了另外一种调用方式,双冒号 ::

​ 这种调用方式,用来直接访问类和实例已经存在的方法或构造方法。可以通过方法引用,赋值给另外一个变量。

语法:

​ 左边是容器(或者类名,方法名),中间是"::",右边是相应的方法名

**静态方法:**则是ClassName::methodName

**实例方法:**则是(对象)Instance::methodName

**构造函数:**则是类名::new;

Lambda表达式的使用:

​ Function<入参1,返回类型> func= 方法引用

​ 应用:func.apply(入参);

​ BiFunction<入参1,入参2,返回类型> func=方法引用

​ 应用:func.apply(入参1,入参2);

  1. 引用静态方法作为函数传递
Function<String,Integer> fun =Integer::parseInt;
Integer apply = fun.apply("1204");
System.out.println(apply);
  1. 引用非静态方法作为函数传递
//使用双冒号::来构造非静态函数的引用
String text="你好啊!美女";
Function<Integer,String> func2=text::substring;
String apply1 = func2.apply(1);
System.out.println(apply1);
  1. 引用构造函数作为函数传递,含多个参数和单个参数,主要是通过Function<>里面的参数来识别调用的是哪个构造函数。
class User{
    private String name;
    private int age;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "User{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
    }
}
//构造函数引用,多个参数
BiFunction<String,Integer,User> biFunction=User::new;
User user2 = biFunction.apply("张三", 1);
System.out.println(user2);

Function<String,User> funct2=User::new;
User user3 = funct2.apply("张三");
System.out.println(user3);
  1. 可以作为一个函数声明,也可以将函数做为参数传递过去
sayHello(String::toUpperCase,"abcdefg");

public static void sayHello(Function<String,String> func,String paramer){
    String result = func.apply(paramer);
    System.out.println(result);
}

你可能感兴趣的:(java基础笔记)