一、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开发不可或缺的部分。