美文网首页Java 杂谈Java开发那些事
Java8新特性 Lambda表达式

Java8新特性 Lambda表达式

作者: 93fcd27d4832 | 来源:发表于2017-09-28 15:10 被阅读0次

1. Lambda表达式简介

Lambda表达式是java8的重要更新,也是一个被广大程序员期待已久的新特性,Lambda表达式允许使用更加简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例.

Lambda表达式的主要作用是代替匿名内部类的烦琐的语法,他主要由三部分组成:

  • 形参列表 :形参列表允许省略形参类型.如果形参列表里只有一个参数,甚至形参列表的圆括号都可 以省略.

  • (箭头(->) :必须通过英文输入法中横线和大于号组成.

  • 代码块 :如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号, 如果代码块已有一行return语句,甚至可以省略return关键字.

2.Lambda表达式使用示例

interface Eatable{
    void teste();
}

interface Flyable{
    void fly(String name);
}

interface Addable{
    int add(int a,int b);
}

public class LamdbaQs{
    
    //调用Eatable接口对象
    public void eat(Eatable e){
                System.out.println(e);
        e.teste();
    }
    
    //调用Flyable
    public void drive(Flyable f){
                System.out.println(f);
        f.fly("哈哈!");
    }
    
    //调用Addable
    public void test(Addable a){
                System.out.println(a);
        System.out.println("长方形的面积为:"+a.add(5,3));
    }
    
    
    public static void main(String[] args){
        LamdbaQs lq=new LamdbaQs();
        
        //实例1:  Lamdba表达式的代码块只有一行代码的时候可以省略花括号;
        //不用Lambda表达式的写法;
        lq.eat(new Eatable(){
            public void teste(){
                System.out.println("苹果味道不错!");
            }
        });
        //使用Lambda表达式的写法;
        lq.eat(()-> System.out.println("苹果味道不错!"));

        //实例2: Lambda表达式的形参列表只有一个参数的时候可以省略 参数列表的圆括号;
        //不用Lambda表达式的写法;;
        lq.drive(new Flyable(){
            public void fly(String name){
                System.out.println("今天天气真不错,我和"+name+"出去玩!");
            }
        });
        
        //使用Lambda的写法;
        lq.drive(name -> {
            System.out.println("今天天气真不错!"+name+"出去玩!");
        });
        
        
        //实例3: Lambda表达式的代码块只有一条语句的时候,可以省略花括号,即使该表达式需要返回值,也可以省略return;关键字!
        //不用Lambda表达式的写法;
        lq.test(new Addable(){
            public int add(int a ,int b){
                return a*b;
            }
        });
        //使用Lambda表达式的写法
        lq.test((a,b)-> a*b);
    }
}

上面程序中可以看到有这么几行代码:

System.out.println(e);

System.out.println(f);

System.out.println(a);

他们的打印结果为:

cow.LamdbaQs$$Lambda$1/1510467688@5acf9800

cow.LamdbaQs$$Lambda$2/2055281021@5ca881b5

cow.LamdbaQs$$Lambda$3/798154996@28a418fc

可以看出他们传入的并不是 Eatable, Flyable, Addable 这三个接口 ,而是三个Lamdba表达式
而且上边的程序可以正常编译,运行 这说明Lambda表达式实际上会被当成一个"任意类型"至于到底需要当成何种类型的对象,就要取决于运行环境的需要了.

3.Lambda表达式与函数式接口

Lambda表达式也被成为"目标类型",Lambda表达式的目标类型必须是"函数式接口"(只有一个抽象方法的接口被成为函数式接口,函数式接口可以包含很多的默认方法,类方法,但只能声明一个抽象方法,换句话说只要有一个以上的抽象方法它就不是函数式接口).如果使用匿名内部类的方式来创建函数式接口的实例只需要实现一个抽象方法,这种情况完全可以用Lambda表达式来创建对象,该表达式创建出来的对象的目标类就是这函数式接口.
.
..

既然Lambda表达式是任意类型,目标类型,而且它的结果也会被当成对象来处理,那我们程序中完全可以使用Lambda表达式进行赋值.

//Runnable  java本身提供的函数式接口
//Runnable接口中只包含一个抽象方法, Lambda表达式实现了这个接口里的唯一的,无参数的方法 因此下面的Lambda表达式则创建了一个Runnable对象
Runnable r = () -> {
    for(int i= 1 ; i < 200 ; i++){
           /////////////////////
    }
}

//函数式接口
@FunctionalInterface
interface FInterface{
    void run();
}


public void test(){
        //使用函数式接口将Lambda表达式进行强制装换,这样就可以确定该表达式的目标类型为FInterface函数式接口.
        Object obj=(FInterface) ()-> {
            for(int i=0 ; i<100 ; i++){
                ///////////////
            }
        };
    }
3.1.Lambda两个限制
  • Lambda表达式的目标类型必须是明确的函数式接口

  • Lambda表达式只能为函数式接口创建对象,Lambda表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口(函数式接口)创建对象.

根据限制我们再来看一个示例:

Object obj=() -> {
        for(int i=0; i<100 ; i++){
                ////////////////////////
        }
}

上面这段程序运行后报错:不兼容类型,Object不是函数式接口.
那么我们来改一下呢:

  Object obj=(Runnable) ()-> {
            for(int i=0 ; i<100 ; i++){
                ///////////////
            }
        };

这样就好了, 我们把Lambda表达式强制装换为Runnable类型,这样就可以确定该表达式的目标类型为Runnable函数式接口.

提示: Java8专门为函数式接口提供了@FunctionalInterface注解,该注解通常放在接口定义前面,它对程序没有任何作用,只告诉编辑器必须严格检查这个必须是函数式接口,否则编译器就会报错.

4.方法引用与构造器引用

前面已经介绍过如果Lambda表达式的代码块只有一条代码,程序就可以省略Lambda表达式中代码块的花括号.不进如此如果Lambda表达式的代码块只有一条大妈,还可以在代码块中使用方法引用和构造器引用.

方法引用和构造器引用可以让Lambda表达式的代码更加简洁.他们都需要使用两个英文冒号.Lambda表达式支持下表这些引用方法:

种类 实例 对应的Lambda表达式
引用类方法 类名 :: 类方法 (a,b)->类名.类方法(a,b,...)
引用特定对象的实例方法 特定对象::实例方法 (a,b)->特定对象.实例方法(a,b,...)
引用构造器 类名::new (a,b,...)->new 类名(a,b,...)

实例:
YourTest.java

import java.awt.*;
import javax.swing.*;

@FunctionalInterface
public interface YourTest{
    JFrame win(String title);
}

Converter.java

@FunctionalInterface
public interface Converter{
    Integer convert (String from);
}

MyTest.java


import java.awt.*;
import javax.swing.*;

public class MyTest {
    
    public void test(Converter con){
        System.out.println(con.convert("111111"));
    }
    
    
    public static void main(String[] args){
        
        //引用类方法
        //普通写法
        Converter con2=new Converter(){
            public Integer convert(String name){
                return Integer.valueOf(name);
            }
        };
        System.out.println(con2.convert("111111"));
        
        
        
        //使用匿名内部类的常规写法;
        MyTest test=new MyTest();
        test.test(new Converter(){
            public Integer convert(String name){
                return Integer.valueOf(name);
            }
        });
        
    
        //使用Lambda表达式写法;
        Converter con =from -> Integer.valueOf(from);
        Integer i=con.convert("9999");
        System.out.println(i);
        
        
        //方法引用代替Lamdba表达式,引用类方法;
        Converter con3=Integer :: valueOf;
        System.out.println(con3.convert("33333"));
        
        
        
        
        //引用特定对象的实例方法
        //普通写法
        Converter con4=new Converter(){
            public Integer convert(String name){
                return "Java,HaHaHa!".indexOf(name);
            }
        };
        System.out.println(con4.convert("a"));
        
        //Lambda表达式写法
        Converter con5=name -> "Java,HaHaHa!".indexOf(name);
        System.out.println(con5.convert("a"));
        
        //方法引用代替Lamdba表达式,引用特定对象的实例方法
        Converter con6 ="Java,HaHaHa!" :: indexOf;
        System.out.println(con6.convert("J"));
        
        
        //引用构造器
        //Lambda表达式写法
        YourTest yt=(String a) -> new JFrame(a);
        JFrame jf=yt.win("我的窗口!");
        System.out.println(jf);
        
        
        //构造器引用代替Lambda表达式写法
        YourTest yt2 =JFrame :: new;
        JFrame jf2=yt2.win("我的窗口!(构造器引用)");
        System.out.println(jf2);
    }
}

JFrame 是java Swing中的基本容器,与本主题无关只是一个示例.

提示:新手的话不建议直接使用Lambda表达式.

第一次发表文章,希望大家多多支持,多多点赞,多多评论,以后写出更好的文章和大家分享,写的不好的地方,还望大神多多指点,大家共同进步. 祝大家技术越来越好,薪资越来越高.

相关文章

  • Java 8、9 语言新特性

    Java语言新特性 Java8 Java 8 新特性 Lambda 表达式 Lambda表达式(也叫做闭包)是Ja...

  • java8 新特性

    java8 新特性 1 Lambda表达式 lambda 是一个匿名函数, lambda 表达式基本语法: jav...

  • java8

    现代化 Java - Java8 指南 JAVA8新特性(吐血整理) 理解 Lambda 表达式

  • Lambda表达式和函数式接口

    初识lambda表达式 lambda表达式是Java8的新特性,可以将lambda表达式看成是精简语法的匿名内部类...

  • Java8 新特性之 Lambda 表达式

    Lambda表达式 lambda表达式是java8给我们带来的几个重量级新特性之一,借用lambda表达式,可以让...

  • Lambda的基础使用

    Lambda是java8出的新特性,之前很少用Lambda表达式写代码,现在慢慢习惯用Lambda表达式,并且记得...

  • Lambda表达式

    内容整理自bilibili 参考链接 一、lambda表达式的简介 lambda表达式是java8添加的新特性; ...

  • Java8 新增了非常多的特性

    新特性Java8 新增了非常多的特性,我们主要讨论以下几个: Lambda 表达式 − Lambda允许把函数作为...

  • Lambda 表达式

    Lambda 表达式 声明:java8新特性系列为个人学习笔记,参考地址点击这里,侵删!! Lambda 表达式,...

  • Java8新特性

    1、语言新特性 1.1、Lambda表达式(也称闭包) Lambda表达式是Java8最大的卖点,它允许交函数作为...

网友评论

    本文标题:Java8新特性 Lambda表达式

    本文链接:https://www.haomeiwen.com/subject/nwayextx.html