您好,欢迎访问一九零五行业门户网

Java实例详解之Lambda表达式

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于lambda表达式的相关问题,lambda表达式在java语言中引入了一个操作符**“->”**,该操作符被称为lambda操作符或箭头操作符,下面一起来看一下,希望对大家有帮助
推荐学习:《java视频教程》
一、lambda初识我们知道,在java中,接口是不能实例化的,但是接口对象可以指向它的实现类对象。如果接口连实现对象都没有呢?那还可以使用匿名类的方式,如下:
public class javatest {    public static void main(string[] args) {        fly fly = new fly() {            @override            public void fly(string name) {                system.out.println(name + 飞行);            }        };        fly.fly(张三);    }}interface fly{    abstract void fly(string name);}
但是,使用匿名内部的方式,代码量其实并不是非常简洁,而为了使代码更加的简洁,java引进了lambda表达式的写法,通过更简单的语法,去实现这样功能,使用lambda表达式简化的代码如下:
public class javatest {    public static void main(string[] args) {        fly fly = name -> system.out.println(name + 飞行);        fly.fly(张三);    }}interface fly{    abstract void fly(string name);}
通过lambda表达式完成了同样的效果,但是代码量却精简了非常对,这就是lambda表达式的魅力。
二、 函数式接口在学习lambda表达式的语法之前,首先要知道什么是函数式接口, 只有一个待实现方法 的接口,就叫做函数式接口。
//接口中只有一个待实现的方法 fly,所以这是函数式接口interface fly{     void fly(string name);}//接口中有两个待实现的方法 这是不是函数式接口interface run{    void fastrun();    void slowrun();}//接口中有两个方法,但其中一个是已经定义好的default方法,真正需要子类去实现的方法只有一个 这是函数式接口interface jump{    void jump();    default void highjump(){        system.out.println(跳的更高);    }}
可以在接口上加**@functionalinterface注解,去断言这个接口是函数式接口,如果这个接口不是函数式接口,编译就会提示错误。
为什么要知道什么是函数式接口呢?因为lambda表达式去简化一个接口的匿名类实现方式,它只能对函数式接口起作用**。
这很容易理解,如果一个接口有多个待实现的方法,lambda表达式就不能分辨出它现在是对接口中哪个方法进行实现。
三、lambda表达式语法lambda表达式在java语言中引入了一个操作符**“->”**,该操作符被称为lambda操作符或箭头操作符。它将lambda分为两个部分:
左侧:指定了lambda表达式需要的所有参数
右侧:制定了lambda体,即lambda表达式要执行的功能。
像这样:
(parameters) -> expression或(parameters) ->{ statements; }
lambda表达式的除了->和lambda体,其他的比如参数,小括号,中括号都是可以更加参数类型、方法体代码行数进行省略的。
以如下函数式接口的实现为例:
interface mathoperation {        int operation(int a, int b);    }    interface greetingservice {        void saymessage(string message);    }    private int operate(int a, int b, mathoperation mathoperation){        return mathoperation.operation(a, b);    }        interface noparam{        int returnone();    }
以下是lambda表达式的重要特征:
可选类型声明:lambda表达式可以不用声明实现方法的参数类型,编译器可以统一识别参数值。        // 类型声明        mathoperation addition = (int a, int b) -> a + b;        // 不用类型声明        mathoperation subtraction = (a, b) -> a - b;
可选的参数圆括号:一个参数无需定义圆括号,但没有参数或者多个参数需要定义圆括号。      // 不用括号        greetingservice greetservice1 = message ->                system.out.println(hello  + message);        // 用括号        greetingservice greetservice2 = (message) ->                system.out.println(hello  + message);
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。     // 多条语句不可以省略大括号        mathoperation multiplication = (int a, int b) -> {            int num = a+1;            num = a + b;            return a * b + num;        };        // 单条语句可以省略大括号        mathoperation pision = (int a, int b) -> a / b;
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。  // 多条语句的lambda表达式如果有返回值,需要使用return        mathoperation multiplication = (int a, int b) -> {            int num = a+1;            num = a + b;            return a * b + num;        };        // 单条语句可以省略return        mathoperation pision = (int a, int b) -> a / b;
四、lambda表达式的使用范围lambda表达式并不只是单单的用来简化一个匿名类的创建,它还有更多的用法。
1、为变量赋值上文中,对lambda表达式的用法都是为变量赋值的写法,这样可以简化匿名内部类赋值的代码段,提高阅读效率。
mathoperation subtraction = (a, b) -> a - b;
2、作为return结果interface mathoperation {        int operation(int a, int b);    }    mathoperation getoperation(int a, int b){        return (a1, b1) -> a+b;    }
3、作为数组元素mathoperation math[] = {                (a,b) -> a+b,                (a,b) -> a-b,                (a,b) -> a*b        };
4、作为普通方法或者构造方法的参数public static void main(string args[]){        java8tester java8tester = new java8tester();        java8tester.operate(1,2,((a, b) -> a*b));    }    private int operate(int a, int b, mathoperation mathoperation){        return mathoperation.operation(a, b);    }    interface mathoperation {        int operation(int a, int b);    }
五、lambda表达式的作用域范围lambda表达式表达体内,可以访问表达体外的变量,但无法对其他变量进行修改操作。
六、lambda表达式的引用写法在学习lambda的时候,还可能会发现一种比较奇怪的写法,例如下面的代码:
// 方法引用写法greetingservice greetingservice = system.out::println;        greetingservice.saymessage(hello world);
这里出现了一个从来没见过的符号 :: ,这种写法就叫做方法的引用。
显然使用方法引用比普通的lambda表达式又简洁了一些。
如果函数式接口的实现恰好可以通过调用一个方法来实现,那么我们可以使用方法引用。
public class java8tester {    public static void main(string args[]){        // 静态方法引用--通过类名调用        greetingservice greetingservice = test::mynamestatic;        greetingservice.saymessage(hello);        test t = new test();        //实例方法引用--通过实例调用        greetingservice greetingservice2 = t::myname;        // 构造方法方法引用--无参数        supplier<test> supplier = test::new;        system.out.println(supplier.get());    }    interface greetingservice {        void saymessage(string message);    }}class test {    // 静态方法    public static void mynamestatic(string name) {        system.out.println(name);    }    // 实例方法    public void myname(string name) {        system.out.println(name);    }    // 无参构造方法    public test() {    }}
7、lambda表达式的优缺点优点:更少的代码行-lambda表达式的最大好处之一就是减少了代码量。我们知道,lambda表达式只能与功能接口一起使用。例如,runnable 是一个接口,因此我们可以轻松地应用lambda表达式。
通过将行为作为方法中的参数传递来支持顺序和并行执行-通过在java 8中使用stream api,将函数传递给collection方法。现在,集合的职责是以顺序或并行的方式处理元素。
更高的效率-过使用stream api和lambda表达式,可以在批量操作集合的情况下获得更高的效率(并行执行)。 此外,lambda表达式有助于实现集合的内部迭代,而不是外部迭代。
缺点运行效率-若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热才显示出效率优势)很难调试-lambda表达式很难打断点,对调式不友好。不容易看懂-若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂(我学lambda表达式的原因是看不懂同事写的lambda表达式代码)推荐学习:《java视频教程》
以上就是java实例详解之lambda表达式的详细内容。
其它类似信息

推荐信息