当前位置: 首页 > 科技观察

Lambda表达式详细总结,理论加案例

时间:2023-03-12 10:33:26 科技观察

JDK版本迭代这几年JDK更新非常快。JDK19将于2022年9月20日发布,作为Java语言的使用者,尤其是新人和想入行的人,不要被这么快的更新速度吓到,更不要担心被卖掉,因为大多数版本只是过渡性的,比如JDK19将在2023年3月被JDK20取代,完全不用恐慌,JDK这几年更新这么频繁,真正的变化其实在JDK8。本文为系列文章,后续内容将持续发布!从1996年1月JDK1.0正式发布到现在,目前主流的长期支持[LTS]版本有三个:JDK8、JDK11、JDK17。由于JDK11没有特别大的优化更新,46.45%的企业还在使用2014年3月14日发布的JDK8,JDK17使用率仅为0.37%JDK8重要更新以下《??JDK8更新——官网原版详解??》,本文主要介绍JDK更新的重要变化在编码层面,也就是我们一线程序员需要掌握的,网上教程很多,只是教程太多了,看不懂。在一个新功能上花六七个小时是浪费时间。浪费时间,结合实际工作总结了以下几点:Lambda表达式:很重要,一种新的编程语法,可以简化代码,大部分功能也是基于这种语法格式实现的,Spring5源码中也大量使用了Lambda表达式,现阶段开发中广泛使用函数式接口:接口只包含一个抽象方法接口,而Lambda表达式需要使用函数式接口来实现Stream流:对数据进行新的流式操作,不存储数据,只用于数据计算,可以对集合、数组、文件等进行多种计算操作,开发方便,速度快接口增强:接口中可以提供默认方法方法引用:可以直接引用已有的Java类和对象的方法或构造函数,结合Lambda表达式使编程更加紧凑简洁,减少冗余代码日期时间类:新的日期时间API,reasonabledesign,threadsafetyIntroduceOptional:usedtosolvenullpointerexceptionTips:本文主要讲解Lambda表达式Lambda表达式Lambda表达式支持将方法[行为]作为参数传递。这种编程方式被称为【函数式编程】。这种编程方式最大的特点是代码紧凑,减少了冗余代码,使编程更加简洁。Java最大的缺点就是代码臃肿。Python、Scala、JavaScript等语言也引入了函数式编程,而Java通过Lambda表达式实现函数式编程势在必行!语法格式Lembda表达式由左边的参数,右边的表达式,中间一个向右的箭头组成:参数可以为空,也可以没有返回值//有参数和返回值(parameter1,parameter12,...)->{表达式;...returnxxx;}//没有参数和返回值()->{expression;...返回xxx;}//有参数无返回值(parameter1,parameter12,...)->{expression;...}//无参数无返回值()->{expression;...}实现原理lambda表达式函数式接口只有你想用才行,必须依赖函数式接口:即接口中只有一个抽象方法,@FunctionalInterface注解会用于修饰JDK8及以后版本的类型推断:Lambda表达式不需要指定参数类型,程序仍然可以通过编译。Lambda表达式的类型由编译器根据上下文推断。这就是类型推断。重点是掌握Lambda表达式的前提。理解函数式接口Lambda表达式实现语法和例子Lambda表达式简写Lambda对集合、线程等的操作无参练习Lambda表达式的实现需要依赖函数式接口,JDK内置了一些函数式接口,使用Supplier实现Lambda不带参数的讲解,至于如何自定义函数式接口在后面的介绍中会单独做以保证连贯性,函数式接口的其他内容在此不再穿插!Supplier接口是JDK中内置的供应接口。它的特点是没有参数,只有返回值。定义如下:代码:packagecom.stt;importjava.util.function.Supplier;/***无参函数接口*/publicclassNoArgsMain{publicstaticvoidmain(String[]args){//1.实施Suppliers1=newSupplier(){@OverridepublicIntegerget(){return1024;}};//通过get方法获取返回值System.out.println(s1.get());//2.通过Lambda表达式实现Suppliers2=()->>;{返回“Lambda实现”;};//通过get方法获取返回值System.out.println(s2.get());}}简化代码:如果Lambda表达式有返回值,代码体只有一行代码,return和大括号可以省略//1.简化代码如下publicclassNoArgsMain{publicstaticvoidmain(String[]args){/*1.函数体只有一行代码,return可以省略2.只有一行代码大括号可以省略*/Suppliers2=()->"Lambda实现";//通过get方法获取返回值System.out.println(s2.get());}}//2.如果有多行的话,不能省略publicclassNoArgsMain{publicstaticvoidmain(String[]args){//通过Lambda实现的表达式,因为函数体还有其他代码,返回和花括号Suppliers2=()->{System.out.println("IamtheLambdaexpressionbody");返回“Lambda实现”;};//通过get方法获取返回值System.out.println(s2.get());}}带参数的实现是通过JDK内置的Consumer接口实现的,接收参数但不返回值。定义如下:代码实现:packagecom.stt;importjava.util.function.Consumer;publicclassHasArgsMain{publicstaticvoidmain(String[]args){//1.原实现Consumerconsumer1=newConsumer(){@Overridepublicvoidaccept(Integerparam){//无返回值System.out.println("我是消费者接口,只进出!"+param);}};//调用accpet方法消费数据consumer1.accept(1024);//2.Lambda写法,Consumerconsumer2=(str)->{System.out.println("我是LambdaconsumerType接口,"+str);};consumer2.accept("史甜甜");}}简化写法:publicclassHasArgsMain{publicstaticvoidmain(String[]args){/*1.如果只有一个参数,可以省略括号2.如果代码体只有一行代码,你可以省略大括号*/Consumerconsumer2=str->System.out.println("IamaLambdaconsumerinterface,"+str);consumer2.accept("史甜甜");}}总结:如果代码体只有一行代码,不管有没有参数,大括号都可以省略。如果有返回值,代码体只有一行代码,return可以省略。如果只有一个参数,括号可以省略,参数和多个参数都不能省略。是不是有点感觉Lambda表达式简化了代码,让编码更加简洁。接下来,我们将通过更多的案例对比,进一步了解和使用Lambda表达式Lambda是通过Runnable接口实现线程创建的Thread,如果要用Lambda,那么Runnable应该是函数式接口。函数式接口的特点是只有一个抽象方法。Runnable接口的定义如下:代码实现:publicclassThreadMain{publicstaticvoidmain(String[]args){//1.按原来的方式创建线程newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName()+"线程启动");}}).start();//2.使用Lambda表达式速记创建一个线程newThread(()->System.out.println(Thread.currentThread().getName()+"ThreadStart")).start();}}Lambda实现集合遍历集合操作。新的forEach方法接收一个Consumer类型的对象。上面【参考实现】中有介绍。它是一个功能接口代码实现:publicclassCollectionMain{publicstaticvoidmain(String[]args){//创建集合Listlist=newArrayList<>();//添加数据list.add("Ace!");list.add("血清!");list.add("杰克!");list.add("狮子座!");//1.原来的遍历方法list.forEach(newConsumer(){@Overridepublicvoidaccept(Strings){System.out.println(s);}});//2.因为Consumer是一个函数式接口,所以可以使用Lambad//思考:简写形式如何实现?list.forEach((str)->{System.out.println(str);});}}Lambda实现集合排序可以使用sort方法进行集合排序,sort方法接收一个Comparator类型的数据Comparator接口定义提示:接口中有几个默认实现方法和静态方法。因为只有一个抽象方法,所以也是一个函数式接口代码实现:personList.add(newPerson("李小白",24));personList.add(newPerson("张二三",21));personList.add(newPerson("王五六",30));//遍历System.out.println("排序前--------------------");personList.forEach(person->System.out.println(person));//排序,参数1-参数2升序排序System.out.println("排序后-----------------");personList.sort(newComparator(){@Overridepublicintcompare(Personp1,Personp2){返回p1.getAge()-p2.getAge();}});personList.forEach(person->System.out.println(person));//Lambda排序,参数2-参数1降序排序System.out.println("Lambda排序--------------------");//直接简写形式,只有一行代码,大括号和回车可以省略personList.sort((p1,p2)->p2.getAge()-p1.getAge());personList.forEach(person->System.out.println(person));}}总结Lambda表达式简化开发,让编码变得简单Lambda表达式需要依赖函数式接口的实现,在某些情况下可以简化写法。StreamAPI、方法引用等特性需要基于Lambda实现。一开始你可能不习惯Lambda表达式,多点就好,一定要多用!文章来自:田震,如需转载本文,请联系【田震】今日头条号。