JDK8新特性--lambda表达式

简介: 面向对象思想强调:必须通过对象的形式来做事情

1.lambda表达式

面向对象思想强调:必须通过对象的形式来做事情

函数:强调做什么,而不是以什么形式去做

1.1 标准格式

  • 分析:

     ():里面没有内容,可以看成是方法形式参数为空

     ->:指向后面要做的事情

     {}:包含一段代码,称为代码块,可以看成是方法体中的内容

  • 格式三要素:形式参数、箭头、代码块

  • 格式:(形式参数)->{代码块}

     形式参数:如果多个参数,用逗号隔开,没有参数就留空

     ->:指向动作

     代码块:具体要做的事情,方法体内容

使用的前提:

  1. 有一个接口
  1. 接口有且仅有一个抽象方法

无参方法无返回值:()->{}

有参方法无返回值:(String s)->{}

有参方法有返回值:(int x,int y)->{return x+y}

1.2 省略模式


1. 参数类型可以省略,但是有多个参数的情况下,不能只省略一个

(x,y)->{return x+y}

​

2. 参数只有一个,小括号可以省略

x->{return x}

​

3. 代码块语句只有一条,可以省略大括号和分号

x->System.out.println("");

​

4. 代码块语句只有一条,如果有return,return也可以省略

(x,y)->x+y

*注意事项*

  1. 有一个接口,接口有且仅有一个抽象方法

  1. 必须有上下文环境,才能推导出lambda对应的借口(要一个接口类型的参数)

  1. 不能单独写,因为推断不出来是干嘛用的

1.3 lambda表达式和匿名内部类区别

  1. 所需类型不同

     匿名内部类:可以是接口、抽象类、具体类

     lambda:只能接口

  1. 使用限制不同

     接口只有一个抽象方法,两个都可以用,多个抽象方法只能匿名内部类

  1. 实现原理不同

     匿名内部类:编译后,会产生一个单独的.class字节码文件

     lambda:编译后,不会产生一个单独的.class字节码文件。对应的字节码会在运行时动态生成

2.接口组成更新

  1. 接口组成

     常量(public static final)抽象方法(public abstract)

     默认方法(java8)静态方法(java8)私有方法(java9)

  1. 默认方法

     格式:修饰符 default void 方法名(参数列表){}

     注:默认方法不是抽象方法,不强制重写,重写不需要带default,public可以省略

  1. 静态方法

     格式:修饰符 static void 方法名(参数列表){}

     注:静态方法只能被接口调用 ,不能通过实现类名或者对象名调用,public可以省略

  1. 私有方法

     格式:

  • private 返回值类型 方法名(参数列表){}

  • private static 返回值类型 方法名(参数列表){}

     注:默认方法可以调用私有静态方法和私有方法,静态方法只能调用私有静态方法

  1. 方法引用

     方法引用符( :: )

     注:可推导就是可省略的

           所在的表达式称为方法引用


x->System.out.println("")

方法引用可写成如下:

System.out::println(相当于println给了x)

2.1 推导与省略

     如果使用lambda,根据“可推导就是可省略”原则,无需指定参数类型,也无需指定的重载形式,他们都将被自动推导

如果使用方法引用,也同样可以根据上下文进行推导

方法引用和lambda的孪生兄弟

2.2 常见引用方式

  1. 引用类方法

     引用类的静态方法

     格式:类名::静态方法

     注:把形式参数全部传递给静态方法作为参数

  1. 引用对象的实例方法

     引用类中的成员方法

     格式:对象::成员方法

     注:形式参数全部传递给该方法作为参数

  1. 引用类的实例方法

     引用类中的成员方法

     格式:类名::成员方法

     注:第一参数作为调用者,后面的参数全部传递给该方法作为参数

  1. 引用构造器

     引用构造方法

     格式:类名::new

     注:形式参数全部传递给构造器作为参数

3.函数式接口

  1. 有且仅有一个抽象方法的接口(lambda表达式的前提)

  1. 可用于局部变量

     @FunctionInterface:选填,不加只要满足函数式接口的条件,也是函数式接口

  1. 作为方法的参数

     方法的参数是一个函数式接口,可以使用lambda表达式作为参数传递

  1. 作为方法的返回值

     方法的返回值是一个函数式接口,可以使用lambda表达式作为结果返回

  1. 常用函数式接口

  • Supplier接口:(Supplier,生产型接口)

     包含一个无参的方法

     T get():获取接口

请在此添加图片描述

  • Consumer接口:(Consumer,消费型接口)


void accept(T t):对给定的参数执行此操作

default Consumer<T> andThen(Consumer after):返回一个组合的Consumer,依次执行此操作,然后执行after操作

con1.andThen(con2).accept(name):con1先消费name,con2再消费name

  • Predicate接口:(Predicate判断参数是否满足指定的条件)


boolean test(T t):对给定的参数进行判断(判断逻辑由lambda表达式实现)

default Predicate<T> negate():返回一个逻辑的否定,对应逻辑非

default Predicate<T> and(Predicate other):返回一个组合判断,对应短路与

default Predicate<T> or(Predicate other):返回一个组合判断,对应短路或

  • Function接口:(Function对于参数进行处理,转换处理逻辑由lambda表达式实现,然后返回一个新的值)


apply(T t):将此函数应用于给定的参数

default<V> Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后after函数应用于结果

4.stream流

4.1 生成方式

流的使用:

  1. 生成流

     通过数据源(集合、数组等)生成流 比如:list.stream()

  1. 中间操作

     一个流后面可以跟随0个或者多个中间操作,目的是为了打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用,比如:filter()

  1. 终结操作

     一个流只能有一个终结操作,这个操作后,流就被使用完了,无法再进行操作。比如:forEach()

4.2 常见生成流的方式

  1. Collection体系的集合生成流:stream()
  1. Map体系间接生成流
  1. 数组通过Stream接口的静态方法of(T...valus)生成流

请在此添加图片描述

4.3 常见中间操作


fliter(Predicate predicate):用于对流中数据进行过滤(基于test(T t)方法)

limit(long maxSize):返回此流中的元素组成的流,截取前指定参数个数的数据

skip(long n):跳过指定参数个数的数据,返回由该流的剩余元素组成的流(前面n个跳过)

concat(Stream a,Stream b):static修饰,合并a b 两个流成为一个

distinct():返回由该流的不同元素(根据Object.equals(Object))组成的流

sorted():返回由此流的元素组成的流,并按照自然排序

sorted(Comparator com):返回由此流的元素组成的流,并按照Compatator排序

​

<R> Stream<R> map(Function mapper):返回由给定函数应用于此流的元素的结果组成的流(基于apply(T t)方法)

Intstream mapToInt(ToIntFunction mapper):返回一个Intstream其中包含将给定函数应用于此流的元素结果

Intstream:表示原始int流

ToIntFunction:int applyAsInt(T value)

请在此添加图片描述

请在此添加图片描述

请在此添加图片描述

4.4 常见终结操作方法

  1. forEach(Consumer action):对此流的每个元素执行操作(基于accept(T t)方法,对给定的参数执行此操作)
  1. long count():返回此流中的元素个数

**4.5 收集操作**

怎么把流放在集合中?

Stream流的收集方法


R collect(Collector col)参数是一个Collector接口

​

Collectors提供的收集方式:

public static <T> Collector toList():元素收集到list集合

public static <T> Collector toSet():元素收集到set集合

public static Collector toMap(Function key,Function value):元素收集到map集合

请在此添加图片描述

相关文章
|
1月前
|
Oracle Java 关系型数据库
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解
|
1月前
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
|
18天前
|
Java 编译器 API
JDK8新特性--lambda表达式
JDK8的Lambda表达式是Java语言的一大进步。它为Java程序提供了更多的编程方式,让代码更加简洁,也让函数式编程的概念在Java中得到了体现。Lambda表达式与Java 8的其他新特性,如Stream API、新的日期时间API一起,极大地提高了Java编程的效率和乐趣。随着时间的流逝,Java开发者对这些特性的理解和应用将会越来越深入,进一步推动Java语言和应用程序的发展。
8 0
|
1月前
|
算法 Java iOS开发
JDK8到JDK27版本升级的新特性问题之JDK 17中G1在资源占用方面有何变化
JDK8到JDK27版本升级的新特性问题之JDK 17中G1在资源占用方面有何变化
|
1月前
|
XML JSON Java
JDK8到JDK26版本升级的新特性问题之在JDK 13中,字符串文本块改进字符串嵌入是如何实现的
JDK8到JDK26版本升级的新特性问题之在JDK 13中,字符串文本块改进字符串嵌入是如何实现的
|
3天前
|
Java
安装JDK18没有JRE环境的解决办法
安装JDK18没有JRE环境的解决办法
|
1月前
|
Java 关系型数据库 MySQL
"解锁Java Web传奇之旅:从JDK1.8到Tomcat,再到MariaDB,一场跨越数据库的冒险安装盛宴,挑战你的技术极限!"
【8月更文挑战第19天】在Linux上搭建Java Web应用环境,需安装JDK 1.8、Tomcat及MariaDB。本指南详述了使用apt-get安装OpenJDK 1.8的方法,并验证其版本。接着下载与解压Tomcat至`/usr/local/`目录,并启动服务。最后,通过apt-get安装MariaDB,设置基本安全配置。完成这些步骤后,即可验证各组件的状态,为部署Java Web应用打下基础。
40 1
|
1月前
|
Oracle Java 关系型数据库
Mac安装JDK1.8
Mac安装JDK1.8
286 4
|
2月前
|
Java Linux
Linux复制安装 jdk 环境
Linux复制安装 jdk 环境
50 3
|
1月前
|
Java 开发工具
开发工具系列 之 同一个电脑上安装多个版本的JDK
这篇文章介绍了如何在一台电脑上安装和配置多个版本的JDK,包括从官网下载所需JDK、安装过程、配置环境变量以及如何查看和切换当前使用的JDK版本,并提到了如果IDEA和JDK版本不兼容时的解决方法。
开发工具系列 之 同一个电脑上安装多个版本的JDK