Java Lambda 表达式:代码世界的神奇魔法棒
嘿,各位 Java 大侠!今天咱来唠唠 Java 8 里超酷的 Lambda 表达式,这玩意儿就像是代码世界的神奇魔法棒,一挥就能让你的代码变得超炫超厉害!
先说说在集合操作里它是咋大显神通的吧。比如说有个整数集合,就像一群小数字在排队,你想把其中的奇数给揪出来,这时候 Lambda 表达式就闪亮登场啦!
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class LambdaFilterExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> oddNumbers = numbers.stream()
.filter(n -> n % 2!= 0)
.collect(Collectors.toList());
System.out.println(oddNumbers);
}
}
瞧见没,filter 方法就像个挑剔的小管家,拿着 Lambda 表达式 n -> n % 2!= 0 这把筛子,把那些偶数小数字都给筛掉了,只留下奇数大侠们在新的列表里耀武扬威。
再看看字符串集合这边,假如有一堆字符串水果在篮子里,你想挑出带 “a” 字母的水果名字,Lambda 表达式也能轻松搞定!
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class LambdaFilterStringExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elder");
List<String> filteredWords = words.stream()
.filter(s -> s.contains("a"))
这里的 filter 就像个火眼金睛的水果挑选大师,Lambda 表达式 s -> s.contains("a") 就是它的秘密武器,专门把带 “a” 的水果名字挑出来,放进新的水果篮里。
接下来是映射(map)操作,这就像是给集合里的元素们来一场华丽大变身。比如有个整数集合,想把每个数字都变成它的两倍,Lambda 表达式又来施展魔法咯!
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class LambdaMapExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> doubledNumbers = numbers.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println(doubledNumbers);
}
}
map 方法就像个神奇的魔法师,Lambda 表达式 n -> n * 2 则是魔法咒语,念一下,每个整数元素就像被施了魔法一样,瞬间变成了原来的两倍,组成了全新的列表。
要是字符串集合呢,想把所有字符串都变成大写,Lambda 表达式同样不在话下!
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class LambdaMapStringExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", "world", "java");
List<String> upperCaseWords = words.stream()
.map(s -> s.toUpperCase())
.collect(Collectors.toList());
System.out.println(upperCaseWords);
}
}
这里 map 带着 Lambda 表达式 s -> s.toUpperCase() 这个魔法棒,轻轻一挥,所有字符串就都穿上了大写的 “华丽外衣”,是不是超酷?
再聊聊排序(sorted)操作,这就像是给集合元素们排排队,让它们整整齐齐的。对于整数集合,按从小到大的顺序排好:
import java.util.Arrays;
import java.util.List;
public class LambdaSortedExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(5, 3, 8, 1, 2);
List<Integer> sortedNumbers = numbers.stream()
.sorted((a, b) -> a - b)
.collect(Collectors.toList());
System.out.println(sortedNumbers);
}
}
sorted 方法就像个严厉的教官,Lambda 表达式 (a, b) -> a - b 是它的排队规则,根据差值判断大小,让整数元素们乖乖地从小到大站好队。
要是字符串集合,按照字符串长度从短到长来排序呢:
import java.util.Arrays;
import java.util.List;
public class LambdaSortedStringExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "pear", "date");
List<String> sortedWords = words.stream()
.sorted((s1, s2) -> s1.length() - s2.length())
.collect(Collectors.toList());
System.out.println(sortedWords);
}
}
sorted 拿着 Lambda 表达式 (s1, s2) -> s1.length() - s2.length() 这个指挥棒,指挥着字符串元素们按照长度依次排列,就像一群小士兵按照身高排队一样有趣。
二、事件处理中的灵动舞步
在图形界面编程里,Lambda 表达式也跳起了灵动的舞步。比如在 JavaFX 中处理按钮点击事件:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class JavaFXLambdaExample extends Application {
@Override
public void start(Stage primaryStage) {
Button button = new Button("Click me");
button.setOnAction(event -> {
System.out.println("Button clicked in JavaFX");
// 可以在这里添加更多点击按钮后的具体操作逻辑,比如让界面来个大变身之类的
});
VBox vbox = new VBox(button);
Scene scene = new Scene(vbox, 300, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
这里按钮的 setOnAction 方法就像个舞台,Lambda 表达式在上面尽情表演,当按钮被点击时,就会触发这个表演,先简单打印个消息,要是你想玩得更嗨,可以在后面添加各种让界面酷炫变化的代码,就像给舞台加特效一样。
在 Swing 里也不例外哦!处理按钮点击事件也有 Lambda 表达式的精彩表演:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class SwingLambdaExample {
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Lambda Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Click me");
// Lambda表达式处理按钮点击事件,就像个搞怪小丑,点击按钮就弹出个消息对话框逗你乐
button.addActionListener((ActionEvent e) -> {
JOptionPane.showMessageDialog(frame, "Button clicked in Swing");
});
// 还可以变身成造型师,点击按钮就改变按钮的文本,让它换个新模样
button.addActionListener((ActionEvent e) -> {
button.setText("Clicked!");
});
frame.getContentPane().add(button);
frame.pack();
frame.setVisible(true);
}
}
你看,在 Swing 里的按钮点击事件处理中,Lambda 表达式一会儿扮演搞怪小丑弹出对话框,一会儿又变身造型师改变按钮文本,是不是很有趣?
三、函数式接口与 Lambda 表达式的奇妙组合
(一)Predicate 接口:条件判断的犀利侦探
Predicate 接口就像个犀利的侦探,用 Lambda 表达式来定义各种判断条件。比如判断一个整数是不是在某个神秘区间内:
import java.util.function.Predicate;
public class PredicateRangeExample {
public static void main(String[] args) {
Predicate<Integer> inRange = num -> num >= 10 && num <= 20;
System.out.println(inRange.test(15));
System.out.println(inRange.test(5));
}
}
这里的 Predicate<Integer> 类型的 Lambda 表达式 num -> num >= 10 && num <= 20 就是侦探的推理依据,通过 test 方法来验证每个整数是不是在 10 到 20 这个神秘区间里,15 符合条件就被侦探认可,5 不符合就被排除在外。
再比如判断字符串是不是以特定前缀开头,这就像侦探在找特定开头的线索:
import java.util.function.Predicate;
public class PredicateStringPrefixExample {
public static void main(String[] args) {
Predicate<String> startsWith = s -> s.startsWith("java");
System.out.println(startsWith.test("javaee"));
System.out.println(startsWith.test("python"));
}
}
Predicate<String> 接口的 Lambda 表达式 s -> s.startsWith("java") 就是侦探的线索筛选器,“javaee” 有这个线索就被选中,“python” 没有就被淘汰。
(二)Consumer 接口:元素处理的万能工匠
Consumer 接口就像个万能工匠,用 Lambda 表达式来定义对元素的各种操作。比如遍历列表然后打印每个元素,工匠就像个勤劳的打印机:
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class ConsumerPrintExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", "world", "java");
Consumer<String> printConsumer = s -> System.out.println(s);
words.forEach(printConsumer);
}
}
Consumer<String> 类型的 Lambda 表达式 s -> System.out.println(s) 就是工匠的打印工具,通过 forEach 方法把列表里的每个字符串元素都打印出来,就像工匠把每个零件都检查一遍并做个标记。
要是有个对象列表,比如一群人的信息,想修改对象的属性呢?工匠也能搞定!
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class ConsumerModifyExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(new Person("Alice", 25), new Person("Bob", 30));
Consumer<Person> ageIncrement = p -> p.age++;
people.forEach(ageIncrement);
for (Person person : people) {
System.out.println(person.name + " is " + person.age + " years old.");
}
}
}
这里的 Consumer<Person> 接口的 Lambda 表达式 p -> p.age++ 就是工匠的修改工具,把列表里每个人的年龄都加一岁,然后再把更新后的人员信息打印出来,就像工匠把每个零件都升级改造了一下。
(三)Function 接口:类型转换的神奇变身器
Function 接口就像个神奇变身器,用 Lambda 表达式来定义各种类型转换规则。比如把字符串变成它的长度对应的整数,变身器就开始施展魔法啦!
import java.util.function.Function;
public class FunctionStringLengthExample {
public static void main(String[] args) {
Function<String, Integer> stringToLength = s -> s.length();
System.out.println(stringToLength.apply("hello"));
System.out.println(stringToLength.apply("world"));
}
}
Function<String, Integer> 类型的 Lambda 表达式 s -> s.length() 就是变身器的魔法咒语,通过 apply 方法把输入的字符串变成它的长度值,“hello” 就变成 5,“world” 就变成 5,就像把一种东西瞬间变成另一种东西,超神奇!
要是有个自定义对象,比如还是 Person 类,想把它变成它的姓名属性对应的字符串,变身器也不在话下!
import java.util.function.Function;
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class FunctionExtractExample {
public static void main(String[] args) {
Function<Person, String> personToName = p -> p.name;
Person person = new Person("Charlie", 35);
System.out.println(personToName.apply(person));
}
}
此例中 Function<Person, String> 接口的 Lambda 表达式 p -> p.name 就是变身器的另一种魔法,把 Person 对象变成它的姓名字符串,就像把一个复杂的东西提炼出最关键的部分,是不是很厉害?
总之,Java Lambda 表达式就像一个无所不能的魔法棒,在集合操作、事件处理、函数式接口等各个领域都能施展出令人惊叹的魔法,让我们的 Java 编程之旅变得更加有趣和高效!