一、Lambda表达式基础
1. 什么是Lambda表达式?
匿名函数 :没有名称的函数函数式编程 :可作为参数传递的代码块简洁语法 :替代匿名内部类的更紧凑写法
2. 基本语法
( parameters) -> expression
或
( parameters) -> { statements; }
3. 与传统匿名类的对比
Runnable r1 = new Runnable ( ) {
@Override
public void run ( ) {
System . out. println ( "Hello World" ) ;
}
} ;
Runnable r2 = ( ) -> System . out. println ( "Hello World" ) ;
二、函数式接口
1. 什么是函数式接口?
单抽象方法接口 :只有一个抽象方法的接口可用@FunctionalInterface
注解标记
2. Java内置核心函数式接口
接口 方法 用途 Supplier<T>
T get()
无参返回结果 Consumer<T>
void accept(T t)
接收单个参数无返回 Function<T,R>
R apply(T t)
接收T类型返回R类型 Predicate<T>
boolean test(T t)
接收T返回布尔值 UnaryOperator<T>
T apply(T t)
一元操作(同类型转换) BiFunction<T,U,R>
R apply(T t, U u)
接收T,U返回R
3. 自定义函数式接口
@FunctionalInterface
interface StringProcessor {
String process ( String input) ;
default void info ( ) {
System . out. println ( "String processing interface" ) ;
}
}
StringProcessor toUpper = s -> s. toUpperCase ( ) ;
System . out. println ( toUpper. process ( "hello" ) ) ;
三、Lambda使用场景
1. 集合遍历
List < String > names = Arrays . asList ( "Alice" , "Bob" , "Charlie" ) ;
for ( String name : names) {
System . out. println ( name) ;
}
names. forEach ( name -> System . out. println ( name) ) ;
names. forEach ( System . out:: println ) ;
2. 线程创建
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
System . out. println ( "Running in thread" ) ;
}
} ) . start ( ) ;
new Thread ( ( ) -> System . out. println ( "Running in thread" ) ) . start ( ) ;
3. 条件过滤
List < Integer > numbers = Arrays . asList ( 1 , 2 , 3 , 4 , 5 , 6 ) ;
List < Integer > evens = numbers. stream ( )
. filter ( n -> n % 2 == 0 )
. collect ( Collectors . toList ( ) ) ;
4. 排序
List < String > words = Arrays . asList ( "banana" , "apple" , "pear" ) ;
Collections . sort ( words, new Comparator < String > ( ) {
@Override
public int compare ( String a, String b) {
return a. compareTo ( b) ;
}
} ) ;
Collections . sort ( words, ( a, b) -> a. compareTo ( b) ) ;
words. sort ( Comparator . naturalOrder ( ) ) ;
四、方法引用
1. 四种方法引用类型
类型 语法 对应的Lambda 静态方法 ClassName::staticMethod
(args) -> ClassName.staticMethod(args)
实例方法 instance::method
(args) -> instance.method(args)
任意对象的实例方法 ClassName::method
(obj, args) -> obj.method(args)
构造方法 ClassName::new
(args) -> new ClassName(args)
2. 使用示例
Function < String , Integer > parser = Integer :: parseInt ;
String str = "Hello" ;
Supplier < Integer > lengthSupplier = str:: length ;
Function < String , String > upperCase = String :: toUpperCase ;
Supplier < List < String > > listSupplier = ArrayList :: new ;
五、Stream API与Lambda
1. 流操作三阶段
创建流 :集合、数组等数据源中间操作 :过滤、映射等处理终止操作 :收集、遍历等结果处理
2. 常用流操作
List < String > names = Arrays . asList ( "Alice" , "Bob" , "Charlie" , "David" ) ;
List < String > longNames = names. stream ( )
. filter ( name -> name. length ( ) > 4 )
. collect ( Collectors . toList ( ) ) ;
List < Integer > nameLengths = names. stream ( )
. map ( String :: length )
. collect ( Collectors . toList ( ) ) ;
List < String > sorted = names. stream ( )
. sorted ( ( a, b) -> b. compareTo ( a) )
. collect ( Collectors . toList ( ) ) ;
Optional < String > longest = names. stream ( )
. max ( Comparator . comparingInt ( String :: length ) ) ;
3. 并行流
long count = names. parallelStream ( )
. filter ( name -> name. length ( ) > 4 )
. count ( ) ;
六、Lambda高级特性
1. 变量捕获
int threshold = 5 ;
List < Integer > numbers = Arrays . asList ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ) ;
List < Integer > aboveThreshold = numbers. stream ( )
. filter ( n -> n > threshold)
. collect ( Collectors . toList ( ) ) ;
2. 组合函数
Function < String , Integer > strToInt = Integer :: parseInt ;
Function < Integer , Integer > square = n -> n * n;
Function < String , Integer > squareOfNumber = strToInt. andThen ( square) ;
System . out. println ( squareOfNumber. apply ( "5" ) ) ;
Predicate < String > isLong = s -> s. length ( ) > 10 ;
Predicate < String > containsA = s -> s. contains ( "a" ) ;
Predicate < String > longAndContainsA = isLong. and ( containsA) ;
3. 闭包示例
Function < Integer , Function < Integer , Integer > > adder = x -> y -> x + y;
Function < Integer , Integer > add5 = adder. apply ( 5 ) ;
System . out. println ( add5. apply ( 3 ) ) ;
七、异常处理
1. Lambda中的异常处理
List < String > numbers = Arrays . asList ( "1" , "2" , "three" , "4" ) ;
numbers. forEach ( s -> {
try {
System . out. println ( Integer . parseInt ( s) ) ;
} catch ( NumberFormatException e) {
System . out. println ( "Invalid number: " + s) ;
}
} ) ;
2. 编写可抛出异常的Lambda
@FunctionalInterface
interface ThrowingConsumer < T , E extends Exception > {
void accept ( T t) throws E ;
}
static < T > Consumer < T > wrap ( ThrowingConsumer < T , Exception > consumer) {
return t -> {
try {
consumer. accept ( t) ;
} catch ( Exception e) {
throw new RuntimeException ( e) ;
}
} ;
}
List < String > files = Arrays . asList ( "file1.txt" , "file2.txt" ) ;
files. forEach ( wrap ( file -> {
Files . readAllLines ( Paths . get ( file) ) . forEach ( System . out:: println ) ;
} ) ) ;
八、实际应用案例
1. 事件处理
JButton button = new JButton ( "Click" ) ;
button. addActionListener ( e -> System . out. println ( "Button clicked" ) ) ;
Button fxButton = new Button ( "Click" ) ;
fxButton. setOnAction ( event -> System . out. println ( "FX Button clicked" ) ) ;
2. 缓存模式
public class Cache < K , V > {
private final Map < K , V > map = new HashMap < > ( ) ;
private final Function < K , V > loader;
public Cache ( Function < K , V > loader) {
this . loader = loader;
}
public V get ( K key) {
return map. computeIfAbsent ( key, loader) ;
}
}
Cache < String , BigDecimal > priceCache = new Cache < > ( productId ->
fetchPriceFromDatabase ( productId) ) ;
BigDecimal price = priceCache. get ( "P1001" ) ;
3. 策略模式
interface PaymentStrategy {
void pay ( BigDecimal amount) ;
}
class PaymentProcessor {
private PaymentStrategy strategy;
public void setStrategy ( PaymentStrategy strategy) {
this . strategy = strategy;
}
public void processPayment ( BigDecimal amount) {
strategy. pay ( amount) ;
}
}
PaymentProcessor processor = new PaymentProcessor ( ) ;
processor. setStrategy ( amount ->
System . out. println ( "Paying " + amount + " via Credit Card" ) ) ;
processor. processPayment ( new BigDecimal ( "100.00" ) ) ;
processor. setStrategy ( amount ->
System . out. println ( "Paying " + amount + " via Alipay" ) ) ;
processor. processPayment ( new BigDecimal ( "200.00" ) ) ;
九、性能考虑
1. Lambda vs 匿名类
初始化性能 :Lambda首次调用稍慢,后续调用更快内存占用 :Lambda通常占用更少内存最佳实践 :在热点代码中避免频繁创建Lambda
2. 方法引用优化
list. stream ( ) . map ( x -> x. toString ( ) ) . collect ( Collectors . toList ( ) ) ;
list. stream ( ) . map ( Object :: toString ) . collect ( Collectors . toList ( ) ) ;
3. 并行流注意事项
数据量小(<1000元素)时顺序流更快 确保操作是无状态的 避免共享可变状态
十、常见问题与陷阱
1. 变量修改
int sum = 0 ;
numbers. forEach ( n -> {
sum += n;
} ) ;
int [ ] sumHolder = { 0 } ;
numbers. forEach ( n -> sumHolder[ 0 ] += n) ;
2. this关键字
public class LambdaThis {
private String value = "Enclosing" ;
public void doWork ( ) {
Runnable r = ( ) -> {
System . out. println ( this . value) ;
} ;
r. run ( ) ;
}
}
3. 重载问题
interface Adder {
int add ( int a, int b) ;
}
interface SmartAdder {
int add ( double a, double b) ;
}
class Calculator {
void calculate ( Adder adder) { }
void calculate ( SmartAdder adder) { }
}
十一、Java 8+ Lambda增强
1. Java 8 - 基本Lambda支持
2. Java 11 - 局部变量语法
var list = List . of ( "a" , "b" , "c" ) ;
list. forEach ( ( var s) -> System . out. println ( s) ) ;
3. Java 17 - 密封接口
sealed interface MathOperation permits Add , Subtract {
int operate ( int a, int b) ;
}
final class Add implements MathOperation {
public int operate ( int a, int b) { return a + b; }
}
final class Subtract implements MathOperation {
public int operate ( int a, int b) { return a - b; }
}
MathOperation add = ( a, b) -> a + b;
十二、最佳实践
保持简洁 :Lambda体最好不超过3行使用方法引用 :使代码更清晰避免副作用 :纯函数式操作更安全命名参数 :复杂Lambda应使用有意义的参数名类型推断 :通常省略参数类型,必要时显式声明文档注释 :复杂Lambda应添加注释说明
通过掌握Lambda表达式,您可以编写出更简洁、更易读的Java代码,特别是在处理集合和并发编程时。随着函数式编程在Java中的不断演进,Lambda已成为现代Java开发不可或缺的部分。