《剖析Java8的lamda表达式02》
在《剖析Java8的lamda表达式01》中,相信大家已经对lamda表达式有了一定的认识和明确基本语法和用法。那么接下来本章我们再继续了解和学习lamda表达式。
来看看上一章中的一个例子:
Runnable t1 = () -> System.out.println(Thread.currentThread().getId());
上述程序示例中,由lamda表达式生成了Runnable接口的实例,那么大家思考一下,编译器在编译时是如何做到自动类型推断的呢?也就是说,编译器是如何知道lamda表达式对应的目标类型。不知大家是否还记得,函数式接口只允许定义1个抽象接口(函数描述符),那么上述代码在编译的时候,编译器会根据lamda的上下文进行自动推断目标类型是什么样的。
并且lamda的参数列表除了可以显式的声明参数类型外,编译器仍然也可以自动对类型进行推断,如下所示:
@FunctionalInterface public interface Compare { public boolean compare(String str1, String str2); } /* 自动类型推断 */ Compare compare = (str1, str2) -> str1.equals(str2); compare.compare("a", "b");
其实说到底,编译器在编译的时候就是匹配方法签名和lamda表达式签名来实现自动类型推断。
lamda表达式主体除了可以使用参数列表中的参数外,还可以使用局部变量,当然这里大家需要注意,局部变量必须是final,当然Java8中并不需要显示的将匿名类中对外层作用域中定义的变量显式声明为final,但实际上局部变量仍然是final,只是它是隐式的而已:
/* 隐式定义的fina常量 */ String str = "id:"; /* lamda用法 */ new Thread(() -> { System.out.println(str + Thread.currentThread().getId()); }).start();
接下来,我们再来看看如何使用方法引用来简化lamda表达式,是的,更加简洁的操作,何乐而不为。简单来说,方法引用可以被看作仅仅调用特定方法的lamda表达式的一种快捷写法。如果一个lamda代表的是“直接调用这个方法”,那并不需要去描述如何调用它,而是用名称来调用它:
List<String> list = Arrays.asList("a", "b", "c"); /* 使用lamda表达式进行迭代 */ list.forEach((str) -> System.out.println(str)); /* 使用方法引用进行迭代 */ list.forEach(System.out::println);
/* 使用lamda表达式获取字符串长度 */ Consumer<String> com = (str) -> str.length(); /* 使用方法引用获取字符串长度 */ com = String::length;
和方法引用类似,对于构造函数而言,我们可以利用类型名称和关键字new(className::new)来创建一个对象引用:
public class Main { public static void main(String[] args) { /* 使用lamda表达式 */ Function<String, Integer> function = (str) -> new Integer(str); function.apply("123"); /* 使用lamda表达式 */ function = Integer::new; function.apply("321"); /* 使用lamda表达式 */ FunctionaTest<String, String, String, Test> fTest = (str1, str2, str3) -> new Test(str1, str2, str3); fTest.get("a", "b", "c"); /* 使用lamda表达式 */ fTest = Test::new; fTest.get("d", "e", "f"); } } /* 带多个参数的构造函数 */ class Test<T, U, V> { Test(T t, U u, V v) { } } @FunctionalInterface interface FunctionaTest<T, U, V, R> { public R get(T t, U u, V v); }
上述程序示例中,笔者演示了如何通过构造函数引用来创建对象引用。在此大家需要注意,如果构造函数带参数,无论参数个数有多少,构造函数引用的语法始终是className::new,那么构造函数引用的签名一定要与函数式接口的方法签名相互匹配。
相关推荐
本课程主要针对于Java 8(JDK 1.8)的新特性Lamda表达式进行了全面讲解。讲解了java基于函数编程的语法,以及与Lamda表达式操作有关的内建接口、批处理、MapReduce数据分析汇总处理。
Java 8 是一个重要的Java平台版本,因为它引入了许多新特性,其中最显著的就是Lambda表达式。Lambda表达式是函数式编程的关键元素,它允许我们以更简洁、更易读的方式编写代码,特别是在处理集合和并发任务时。在这...
### 如何使用Lambda表达式 #### Lambda表达式简介 Lambda表达式是一种简洁的、内联方式定义函数的方法,常用于创建匿名函数。这种表达式在许多编程语言中都有应用,尤其是在支持面向对象或函数式编程的语言中更为...
C# Lamda表达式简单运用
8. **异步编程**:在C# 5.0及更高版本中,Lambda表达式与`async`和`await`关键字结合,可实现异步方法。例如: ```csharp public async Task<string> DownloadAsync(string url) => await client.GetStringAsync...
**Lambda表达式(LAMDA Expression)** Lambda表达式是C# 3.0引入的新特性,它提供了一种更简洁的方式来表示匿名方法。Lambda表达式使用“=>”操作符,左边是输入参数(如果有的话),右边是表达式或语句块。Lambda...
Lambda表达式是Java 8中引入的一个重要新特性,它允许开发者以一种更加简洁的方式编写函数式接口实现代码。Lambda表达式本质上是一个匿名函数,能够作为一个参数传递给方法调用或存储在变量中,这使得Java支持了更高...
### Java 8 Lambda 表达式之函数式接口详解 #### 一、引言 Java 8 的引入带来了一系列重大的变化,其中 Lambda 表达式作为最具革命性的特性之一,极大地简化了代码编写,提高了程序的可读性和可维护性。在前两篇...
jdk1.8的特性
随着技术的发展,开发者们探索出一种新的方式来实现路由功能——基于Lamda表达式的强类型Routing。 首先,传统的路由注册方式是通过在路由配置文件RouteConfig.cs中使用MapRoute方法来定义路由模板。然而,随着MVC ...
在C#编程语言中,匿名函数和Lambda表达式是两种非常重要的特性,它们极大地提高了代码的简洁性和可读性。本压缩包中的源代码详细展示了这两种技术的使用方法,并且带有注释,方便理解。 首先,让我们来了解一下匿名...
### Lambda 表达式及其在 C# 中的应用 在 C# 的高级编程中,Lambda 表达式的理解和应用是至关重要的。随着 C# 4.0 的推出,一系列新的编程特性如 LINQ 和 Lambda 表达式等为开发者提供了更多便利和强大的功能。本文...
在 Java 8 中,Lambda 表达式可以与 Stream API 结合使用来实现循环累加求和操作。下面是一个简单的示例代码: ```java public void test() { List<Person> people = new ArrayList(); people.add(new Person(...
【C++ function、bind及lambda表达式】 C++0x引入了多项新特性,其中lambda表达式、std::function对象和bind机制是提升代码灵活性和可读性的重要工具。这三者之间的紧密联系在于它们都能在处理回调函数时提供便利。...
Lambda表达式是Java 8引入的一种新特性,它极大地简化了函数式编程,使得代码更加简洁、优雅。在本文中,我们将深入探讨Lambda表达式的概念、语法以及如何在实际编程中应用它们,以实现高效、易读的代码。 首先,...
lamda出来很久了最近老师说用lamda表达式来做一个Button的按钮事件,初略的将自己的做法和感想分享给大家 先说 AS 如何支持 Lambda 表达式 1.首先确定你的AndroidStudio中使用的是大于jdk1.8的版本 2、在项目的根...
在本文中,我们将深入探讨Qt库中的线程池(Thread Pool)机制,以及如何结合使用信号槽(Signals and Slots)和跨线程的lambda表达式。这些技术在多线程编程中扮演着至关重要的角色,特别是在GUI应用中,能够帮助...