函数式编程

lambda表达式

jdk1.8新特性函数式编程,提供了lambda表达式,此外还支持了在接口中定义静态的方法

对接口中的方法做了改进。不但可以有抽象方法、还可以有普通方法、方法体都可以有的。

@FunctionalInterface
//加了这行注解,就代表是一个函数式接口
interface IMessage {
    static void func() {//1.8之后才有静态方法
        System.out.println("这是一个静态方法");
    }
    void send(String str);
    default void print() {
        System.out.println("!23");
    };
}
public class Main {
    public static void main(String[] args) {
        //也可以这么写IMessage msg = (str) -> System.out.println("发送信息"+str);
        IMessage msg = (str) -> {
            System.out.println("发送信息" + str);
        };
        msg.print();//123
        IMessage.func();//这是一个静态方法
//        msg.func();//这样写是错误的不能通过实例化的对象调用接口中的静态方法
        msg.send("www.mldn.cn");//发送信息www.mldn.cn
    }
}

整个程序中只编写了一行语句,于是利用这种形式就避免了复杂的对象结构化要求

lambda表达式如果想要使用有一个重要的要求,那就是sam,只有一个抽象方法,在这个接口里面发现只有提供一个send() 方法,除此之外没有任何方法,称之为函数式接口,只有函数式接口才能被lambda表达式所使用

default关键字

default方法是在java8中引入的关键字,也可称为Virtual extension methods——虚拟扩展方法。是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。

返回值

@FunctionalInterface
interface IMessage {
    int add(int x,int y);
}
public class Main {
    public static void main(String[] args) {
        IMessage msg = (x,y) ->x+y;//直接return了
        int add = msg.add(1, 2);
        System.out.println(add);//3
    }
}

方法引用

引用数据类型最大的特点是可以进行内存的指向处理,但是在传统的开发中一直所使用的是对象引用操作,jdk1.8之后也有提供了方法的引用,即:不同的名称可以描述同一个方法

  • 引用静态方法:类名称1::static方法名称
  • 引用摸个实例对象的方法:实例化对象::普通方法
  • 引用特定类型的方法:特定类::普通方法
  • 引用构造方法类名称::new
@FunctionalInterface
interface Ifunction <P,R>{
    public R change(P p);
}
public class Main {

    public  String v(Integer a){//被引用的方法必须是静态方法
        return a.toString();
    }
    public static String v2(Integer a){
        return a.toString();
    }

    public static void main(String[] args) {
        Main main = new Main();
        //设置传入的参数为Integer类型,返回值为String
        //把当前类中的v方法的地址传给fun
        Ifunction<Integer,String>fun=main::v;//实例对象的普通方法
        Ifunction<Integer,String>fun2=Main::v2;//类的静态方法
        
        String change = fun.change(123);
        System.out.println(change);//"123"
    }
}

利用方法引用这一概念可以为一个方法定义多个名字,但是要求必须是函数式接口

特定类::普通方法

@FunctionalInterface
interface Ifunction <P>{
    int compare(P p1,P p2);
}
public class Main {
    public static void main(String[] args) {
        // 简单来说,String类的compareTo()方法是用来比较两个字符串的字典顺序。
        //  用字符串1跟字符串2作比较,如果字符串1的字典顺序在字符串2前面,则返回一个负数。若在后面,则返回一个正数。若两个字符串的字典顺序相同,则返回0。
        //  这里的字典顺序指的是ASCII码表中的字符顺序。ASCII表中每个字符都有对应的下标,从0开始升序排列,共128个字符。
        Ifunction<String> fun=String::compareTo;
        int compare = fun.compare("A", "a");
        System.out.println(compare);//-32
    }
}

本程序直接使用了String类中的compareTo方法,由于此操作方法调用时,需要指定对象,所以在使用引用方法的时,就必须传入这俩个参数,与之前引用操作相比,方法引用前不需要定义具体的类对象,而是可以理解为将需要调用的对象作为参数进行传递

也可以这么写进行自定义操作

@FunctionalInterface
interface Ifunction <P>{
    Main compare(P p1,P p2,P p3);
}
public class Main {
    public Main func(Main m,Main m2){
        return m;
    }

    public static void main(String[] args) {
        Main main = new Main();
        Ifunction<Main> fun=Main::func;
    }
}

构造方法

@FunctionalInterface
interface Ifunction <P>{
    Main create(int p1,String p2);
}
public class Main {
    Main(int age,String name){
        this.age=age;
        this.name=name;
    }
    int age;
    String name;

    @Override
    public String toString() {
        return "Main{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public static void main(String[] args) {
        Ifunction<Main>fun=Main::new;
        Main zs = fun.create(1, "张三");
        System.out.println(zs);//Main{age=1, name='张三'}
    }
}

内置函数式接口

在系统中专门提供有一个java.util.function的开发包,里面可以直接使用函数式的接口

功能性接口

function

@FunctionalInterface
public interface Function<T,R>{
    public R apply(T t);
}

主要作用:此接口需要接收一个参数,并且返回一个处理结果

消费型接口

Consumer

@functionalInterface
public interface Consumer<T>{
    public void accept(T t);
}

主要作用:此接口只是负责接受数据,引用数据时,不需要返回我,并且不反悔处理结果

供给型接口

supplier

@FunctionalInterface
public interface Supplier<T>{
    public T get();
}

主要作用:此接口不接受参数,但是可以返回结果

断言型接口

Perdicate

@FunctionalInterface
public interface Perdicate<T>{
    public boolean test(T t);
}

主要作用:进行判断操作使用

使用

import java.util.function.Function;


public class Main {
    public static String func(Boolean b){
        return "!@#";
    }
    public static void main(String[] args) {
        Function<Boolean,String> f=Main::func;
    }
}
Last modification:April 21, 2022
如果觉得我的文章对你有用,请随意赞赏