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(), …

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

目录
相关文章
|
10月前
|
存储 Oracle Java
java零基础学习者入门课程
本课程为Java零基础入门教程,涵盖环境搭建、变量、运算符、条件循环、数组及面向对象基础,每讲配示例代码与实践建议,助你循序渐进掌握核心知识,轻松迈入Java编程世界。
754 0
|
10月前
|
负载均衡 Java API
grpc-java 架构学习指南
本指南系统解析 grpc-java 架构,涵盖分层设计、核心流程与源码结构,结合实战路径与调试技巧,助你从入门到精通,掌握高性能 RPC 开发精髓。
924 8
|
10月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
473 1
|
10月前
|
Java Go 开发工具
【Java】(9)抽象类、接口、内部的运用与作用分析,枚举类型的使用
抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类abstract static不能同时修饰一个方法。
372 1
|
11月前
|
算法 安全 Java
除了类,Java中的接口和方法也可以使用泛型吗?
除了类,Java中的接口和方法也可以使用泛型吗?
292 11
|
11月前
|
Java
Java基础学习day08-作业
本作业涵盖Java中Lambda表达式的应用,包括Runnable与Comparator接口的简化实现、自定义函数式接口NumberProcessor进行加减乘及最大值操作,以及通过IntProcessor处理整数数组,实现遍历、平方和奇偶判断等功能,强化函数式编程实践。
161 5
|
11月前
|
Java API 容器
Java基础学习day08-2
本节讲解Java方法引用与常用API,包括静态、实例、特定类型方法及构造器引用的格式与使用场景,并结合代码示例深入解析。同时介绍String和ArrayList的核心方法及其实际应用。
261 1
|
Java Unix 数据库管理
java定时框架:表达式设置
Quartz中时间表达式的设置-----corn表达式 (注:这是让我看比较明白的一个博文,但是抱歉,没有找到原作者,如有侵犯,请告知)   时间格式: ,   分别对应: 秒>分>小时>日>月>周>年,  举例: 1.
1123 0
|
10月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
441 1
|
10月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
411 1