函数式编程

函数式接口

简单来说,函数式接口是只包含一个抽象方法的接口。

当然可以包含其他方法,(默认,静态,私有)方法。

java 8提供 @FunctionalInterface作为注解,检测是否是函数式接口

函数式编程

Lambda的延迟执行

有些场景代码执行后,结果不一定会被使用,从而造成性能浪费,而Lambda是延迟执行的,这正好可以解决作为结局方案,提升性能。

例如如下代码,

public static void shouLog(int level,String message){
        if(level==1){
            System.out.println(message);
        }
    }

    public static void main(String[] args) {
        String msg1="hallo";
        String msg2="world";
        String msg3="java";
        shouLog(1,msg1+msg2+msg3);
    }

可以知道,当   level==1 时,会执行三个字符串的拼接,并且输出拼接字符串,而level 不等于1时,任然会执行三个字符串的拼接,但是不输出任何结果。于是这种情况里就出现了,性能浪费的时候。

利用Lambda延迟执行如下:

使用Lambda函数式的前提必须继承函数式接口;

@FunctionalInterface
public interface MessageBuilder {
    //定义一个函数式接口里的拼接字符的抽象方法
    public abstract String builderString();
}

public class DemoLogger {
    public static void shouLog(int level,MessageBuilder message){
        if(level==1){
            System.out.println(message.builderString());
        }
    }

    public static void main(String[] args) {
        String msg1="hallo";
        String msg2="world";
        String msg3="java";
        shouLog(1,()-> {return msg1+msg2+msg3;});
    }
}

执行结果,完全相同;

  shouLog(2, ()->{
            System.out.println("不满足条件不执行");
            return msg1+msg2+msg3;
        });

而此时,当我们将level不等于1时,不会调用builderString的方法。并没有打印出“不满足条件不执行”。

这就很好的解决了性能浪费的问题。

函数式接口作为方法的参数

在线程当中,Runnable接口就是典型的函数式接口,里面只有一个run方法。所以在线程的调用过程中,我们就可以使用Runnable这样的接口作为函数的参数。

public class Demo01Runnable {
    public static void main(String[] args) {
        startThread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程启动了"+"-->"+Thread.currentThread().getName());
            }
        });
    }

    //定义一个方法,开启线程
    public static void startThread(Runnable run){
        new  Thread(run).start();
    }

 用Lambda表达式优化:

//Lambda表达式简化后
startThread(()-> 
    System.out.println("线程启动了"+"-->"+Thread.currentThread().getName())
);

总结两种方式的区别:

根本在于,前者是创建了一个匿名内部类,进行方法重写之后的调用,实际上创建了一个匿名对象,而后者则是省略了对象的创建。提高了性能。

 执行结果:

函数式接口作为返回类型时:

如Comparator 比较器;只有Compare的抽象方法;

(可以理解为定义一种比较方式,比较的时候用Arrays.sort(参数就放,自己重写的compare方法),这里返回的正式这种排序方式)

public class DemoCompare {
    public static void main(String[] args) {
        String[] arr={"aaa","bb","aaaaaa","cccc"};
        System.out.println(Arrays.toString(arr));
        Arrays.sort(arr,getCompare());
        System.out.println(Arrays.toString(arr));
    }
    public static Comparator<String> getCompare(){
//        return new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o2.length()-o1.length();
//            }
//        };
        //优化
        return (o1, o2) ->o2.length()-o1.length();
    }
}

结果:

 注:     jdk中提供了大量的函数式接口以丰富Lamnda表达式的使用场景,它们主要在Java.util.function包中被提供。如:supplier,Comsumer接口等,lambda表达式,省略了,对接口的创建继承实现类,将方法的重写步骤放置到了,调用我们需要用到的个方法时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值