深入理解Java8新特性之Lambda表达式的基本语法和自定义函数式接口

一、Lambda表达式概述
Lambda表达式是Java 8引入的一种匿名函数,可以理解为简化的匿名内部类,它极大地减少了冗长的代码,简化了操作,在Java 8之前,我们通常使用匿名内部类来实现Runnable接口:
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};
runnable.run();
而在Java 8中,我们可以使用Lambda表达式来简化这一过程:
Runnable runnable = () > System.out.println("Hello, World!");
runnable.run();
二、Lambda表达式的语法要点
Lambda表达式的基本语法如下:
(parameters) > expression
或者
(parameters) > { statements; }
1、参数列表:可以有一个或多个参数,若只有一个参数,可以省略括号。
x > x * x
2、箭头符号:> 是Java中Lambda表达式的箭头符号,用于将参数与Lambda主体分开。
3、主体:可以是单一表达式或一个代码块,如果是单一表达式,返回值会自动推断;如果是代码块,必须显式地使用return来返回结果。
(a, b) > a + b
三、Lambda表达式的应用场景
Lambda表达式广泛应用于集合操作(如filter、map、reduce等)、事件处理(如按钮点击等事件的回调处理)以及线程执行(简化Runnable或Callable的创建)。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name > System.out.println(name));
四、函数式接口
1. 函数式接口的定义
函数式接口是Java中仅包含一个抽象方法的接口,通常用来作为Lambda表达式的目标类型,Java 8引入了@FunctionalInterface注解,用来标识函数式接口,这个注解是可选的,但如果加上,会强制编译器检查该接口是否符合函数式接口的定义(只有一个抽象方法)。

@FunctionalInterface
public interface MyFunction {
int apply(int x, int y);
}
2. Java内置函数式接口
Java 8提供了几个常见的函数式接口,主要位于java.util.function包中,这些接口广泛应用于Java的集合操作和流式API中。
| 接口名称 | 方法签名 | 说明 |
| Function |
R apply(T t) | 接受一个参数并返回一个结果 |
| Predicate |
boolean test(T t) | 接受一个参数并返回一个布尔值 |
| Consumer |
void accept(T t) | 接受一个参数但不返回结果 |
| Supplier |
T get() | 无参数,返回一个结果 |
| UnaryOperator |
T apply(T t) | 一元操作符,接受一个参数并返回同类型结果 |
| BinaryOperator |
T apply(T t1, T t2) | 二元操作符,接受两个参数并返回同类型结果 |
| BiFunction |
R apply(T t, U u) | 接受两个参数并返回一个结果 |
示例:使用Function和Predicate接口
Function<Integer, Integer> square = x > x * x;
System.out.println(square.apply(5)); // 输出 25
Predicate<String> isEmpty = s > s.isEmpty();
System.out.println(isEmpty.test("")); // 输出 true
3. 自定义函数式接口
除了Java内置的函数式接口外,开发者也可以根据需求定义自己的函数式接口,任何接口只要满足只有一个抽象方法的要求,就可以用作Lambda表达式的目标类型。
@FunctionalInterface
public interface MyCalculator {
int calculate(int a, int b);
}
// 使用自定义函数式接口
MyCalculator addition = (a, b) > a + b;
System.out.println(addition.calculate(10, 20)); // 输出 30
4. 函数式接口与OOF(面向函数编程)
通过函数式接口,Java将传统的面向对象编程与函数式编程有机结合,这一切都依赖于接口的抽象和Lambda表达式的简化表示,函数式接口为函数式编程的灵活性提供了坚实的基础,使Java既保留了面向对象的模块化设计,又具备了函数式编程的简洁性和高效性。
五、方法引用
1. 什么是方法引用?
方法引用是Java 8引入的另一种简化Lambda表达式的语法形式,它允许开发者直接引用已有的方法,而不必通过Lambda表达式显式地实现,这提高了代码的可读性和复用性,方法引用的基本形式包括:
静态方法引用:ClassName::staticMethod
对象实例方法引用:instance::method
类的实例方法引用:ClassName::method
构造方法引用:ClassName::new

2. 方法引用的种类及示例
| 类型 | 语法形式 | 示例 |
| 静态方法引用 | ClassName::staticMethod |
Math::max |
| 对象实例方法引用 | instance::method |
System.out::println |
| 类实例方法引用 | ClassName::method |
String::length |
| 构造方法引用 | ClassName::new |
ArrayList::new |
示例:使用方法引用
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(System.out::println); // 使用对象的实例方法引用
六、综合案例:Lambda表达式与函数式接口的结合
假设有一组商品数据,我们需要对这些商品进行过滤和折扣处理,以下是具体实现步骤:
1、定义商品类:创建一个包含商品名称和价格的商品类。
2、定义函数式接口:创建一个函数式接口用于折扣计算。
3、使用Lambda表达式和方法引用:对商品进行过滤和折扣处理。
class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() { return name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
}
@FunctionalInterface
interface DiscountStrategy {
double applyDiscount(Product product);
}
public class Main {
public static void main(String[] args) {
List<Product> products = Arrays.asList(
new Product("Laptop", 999.99),
new Product("Smartphone", 499.99),
new Product("Tablet", 299.99)
);
// 使用Lambda表达式和方法引用进行过滤和折扣处理
products.stream()
.filter(product > product.getPrice() > 500) // 过滤价格大于500的商品
.forEach(product > product.setPrice(product.getPrice() * 0.9)); // 应用10%的折扣
// 打印处理后的商品信息
products.forEach(product > System.out.println(product.getName() + ": $" + product.getPrice()));
}
}
相关问题与解答栏目
问题1:如何在Java中使用Lambda表达式实现一个简单的加法运算?
解答:可以使用Lambda表达式结合BinaryOperator接口来实现一个简单的加法运算,以下是具体实现代码:
import java.util.function.BinaryOperator;
public class Main {
public static void main(String[] args) {
BinaryOperator<Integer> add = (a, b) > a + b; // 使用Lambda表达式实现加法运算
int result = add.apply(5, 10); // 计算5 + 10的结果
System.out.println("5 + 10 = " + result); // 输出结果:5 + 10 = 15
}
}
在这个例子中,我们使用了BinaryOperator接口,它是一个函数式接口,用于表示接受两个相同类型的操作数并返回相同类型结果的二元操作,通过Lambda表达式(a, b) > a + b,我们实现了简单的加法运算,并将其应用于两个整数5和10,最终计算出结果并输出。
各位小伙伴们,我刚刚为大家分享了有关“深入理解Java8新特性之Lambda表达式的基本语法和自定义函数式接口”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!














