Java8学习:Lambda表达式与Functional接口

简介:

Lambda表达式(也称为闭包)是整个Java 8发行版中最受期待的在Java语言层面上的改变,Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据:函数式程序员对这一概念非常熟悉。在JVM平台上的很多语言(Groovy,Scala,……)从一开始就有Lambda,但是Java程序员不得不使用毫无新意的匿名类来代替lambda。

关于Lambda设计的讨论占用了大量的时间与社区的努力。可喜的是,最终找到了一个平衡点,使得可以使用一种即简洁又紧凑的新方式来构造Lambdas。在最简单的形式中,一个lambda可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。例如:

public static void main(String[] args) {
 
 // 一个简单的lambda可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。
 Arrays.asList("a", "b", "d").forEach(e -> System.out.println(e));
 
 // Lambda可以引用类的成员变量与局部变量 //(如果这些变量不是final的话,它们会被隐含的转为final,这样效率更高)。 // 例如,下面两个代码片段是等价的: // 这里编译器会识别类型,String换成Integer就会提示错误
 Arrays.asList("a", "b", "d").forEach((String e) -> System.out.println(e));
 
 // 请注意参数e的类型是由编译器推测出来的, //相当于我们JDK6在循环里用到的list.get(i)或array[i], // 当然这一切在jdk8里边的如此简单,也让人不大习惯,呵呵,用多就习惯了。 // 同时,你也可以通过把参数类型与参数包括在括号中的形式直接给出参数的类型:
 Arrays.asList(1, 3, 2).forEach(e -> {
 if (e == 3)
 System.out.println("xiaosaner~");
 else
 System.out.println(e);
 });
}

Lambda表达式可能会有返回值,编译器会根据上下文推断返回值的类型。如果lambda的语句块只有一行,不需要return关键字。下面两个写法是等价的:

public static void main(String[] args) {
 // 首先对集合进行排序,这里的e1、e2浮现起当年写排序的画面,而现在变的如此简单啊。 // 直接用2个匿名变量比较就O了
 List<String> strList = Arrays.asList( "a", "d", "b" );
 strList.sort( ( e1, e2 ) -> e1.compareTo( e2 ) );
 System.out.println(strList);
 
 //下面的写法和上面一样
 strList.sort( ( e1, e2 ) -> {
 return e1.compareTo( e2 );
 } );
}

语言的设计者们思考了很多如何让现有的功能和lambda表达式友好兼容。于是就有了函数接口这个概念。函数接口是一种只有一个方法的接口,像这样地,函数接口可以隐式地转换成lambda表达式。

//这样写是没问题的,函数式接口 //如果有人在里面加了方法,其他调用就会报错 new Runnable() { 
 public void run() { }
};

//为了克服函数式接口的这种脆弱性并且能够明确声明接口作为函数式接口的意图, //Java 8增加了一种特殊的注解@FunctionalInterface(Java 8中所有类库的已有接口都添加了@FunctionalInterface注解)。

@FunctionalInterface
public interface Demo2 { 
 void method(); 
 //这里的默认方法有点像抽象类的父类实现哈  default void defaultMethod() { 
 System.out.println("hello java8"); 
 }
}

接口的默认方法与静态方法

private interface Defaulable {
 // Interfaces now allow default methods, the implementer may or  // may not implement (override) them. default String notRequired() { 
 return "Default implementation"; 
 } 
}
 
private static class DefaultableImpl implements Defaulable {
}
 
private static class OverridableImpl implements Defaulable {
 @Override public String notRequired() {
 return "Overridden implementation";
 }
}

接口 Defaulable 声明一个默认的方法 必需的() 使用关键字 默认的 方法定义的一部分。 的一个类, DefaultableImpl 实现这个接口并继承了接口的notRequired实现。 另一个, OverridableImpl 覆盖接口子类实现其功能。

java8还提供了一个有趣的对象,接口可以定义静态方法并实现它,那这样的话的我们一起的接口只做常量类,现在可以做工具类了,static的方法写进去so cool~~

private interface DefaulableFactory {
 // Interfaces now allow static methods static Defaulable create( Supplier< Defaulable > supplier ) {
 return supplier.get();
 }
}

public static void main( String[] args ) {
 Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new );
 System.out.println( defaulable.notRequired() );
	 
 defaulable = DefaulableFactory.create( OverridableImpl::new );
 System.out.println( defaulable.notRequired() );
}

默认的方法实现对JVM支持的是非常有效的,对方法调用字节码指令。 默认方法允许现有的Java接口进化没有打破了编译过程。 好的例子是过多的添加方法 java.util.Collection 接口: stream(), parallelStream(), forEach(), removeIf(), …

虽然是强大的,默认应该谨慎使用方法:声明方法默认之前最好三思而后行,如果它是真正需要的,因为它可能会导致歧义和编译错误在复杂的层次结构。 更多细节请参考 官方文档

目录
相关文章
|
1月前
|
机器学习/深度学习 人工智能 NoSQL
JAVA接入DeepSeek大模型接口开发---阿里云的百炼模型
随着大模型的越来越盛行,现在很多企业开始接入大模型的接口,今天我从java开发角度来写一个demo的示例,用于接入DeepSeek大模型,国内的大模型有很多的接入渠道,今天主要介绍下阿里云的百炼模型,因为这个模型是免费的,只要注册一个账户,就会免费送百万的token进行学习,今天就从一个简单的可以执行的示例开始进行介绍,希望可以分享给各位正在学习的同学们。
218 3
JAVA接入DeepSeek大模型接口开发---阿里云的百炼模型
|
11天前
|
Java 编译器 API
Java Lambda 表达式:以 Foo 接口为例深入解析
本文深入解析了 Java 8 中 Lambda 表达式的用法及其背后的函数式接口原理,以 `Foo` 接口为例,展示了如何通过简洁的 Lambda 表达式替代传统匿名类实现。文章从 Lambda 基本语法、函数式接口定义到实际应用层层递进,并探讨默认方法与静态方法的扩展性,最后总结常见误区与关键点,助你高效优化代码!
33 0
|
11天前
|
Java
java中一个接口A,以及一个实现它的类B,一个A类型的引用对象作为一个方法的参数,这个参数的类型可以是B的类型吗?
本文探讨了面向对象编程中接口与实现类的关系,以及里氏替换原则(LSP)的应用。通过示例代码展示了如何利用多态性将实现类的对象传递给接口类型的参数,满足LSP的要求。LSP确保子类能无缝替换父类或接口,不改变程序行为。接口定义了行为规范,实现类遵循此规范,从而保证了多态性和代码的可维护性。总结来说,接口与实现类的关系天然符合LSP,体现了多态性的核心思想。
22 0
|
1月前
|
SQL Rust Java
怎么理解Java中的lambda表达式
Lambda表达式是JDK8引入的新语法,用于简化匿名内部类的代码写法。其格式为`(参数列表) -&gt; { 方法体 }`,适用于函数式接口(仅含一个抽象方法的接口)。通过Lambda表达式,代码更简洁灵活,提升Java的表达能力。
|
2月前
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
395 5
|
4月前
|
Java API 开发者
Java中的Lambda表达式与Stream API的协同作用
在本文中,我们将探讨Java 8引入的Lambda表达式和Stream API如何改变我们处理集合和数组的方式。Lambda表达式提供了一种简洁的方法来表达代码块,而Stream API则允许我们对数据流进行高级操作,如过滤、映射和归约。通过结合使用这两种技术,我们可以以声明式的方式编写更简洁、更易于理解和维护的代码。本文将介绍Lambda表达式和Stream API的基本概念,并通过示例展示它们在实际项目中的应用。
|
5月前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。
|
5月前
|
安全 Java API
Java中的Lambda表达式与Stream API的高效结合####
探索Java编程中Lambda表达式与Stream API如何携手并进,提升数据处理效率,实现代码简洁性与功能性的双重飞跃。 ####
62 0
|
7月前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的探索
【9月更文挑战第24天】本文将深入浅出地介绍Java 8中的重要新特性——Lambda表达式和Stream API,通过实例解析其语法、用法及背后的设计哲学。我们将一探究竟,看看这些新特性如何让Java代码变得更加简洁、易读且富有表现力,同时提升程序的性能和开发效率。
|
8月前
|
Java API
Java 8新特性:Lambda表达式与Stream API的深度解析
【7月更文挑战第61天】本文将深入探讨Java 8中的两个重要特性:Lambda表达式和Stream API。我们将首先介绍Lambda表达式的基本概念和语法,然后详细解析Stream API的使用和优势。最后,我们将通过实例代码演示如何结合使用Lambda表达式和Stream API,以提高Java编程的效率和可读性。