Lambda表达式是Java 8中引入的一个重要特性,它允许开发者以更加简洁的方式编写函数式代码。在本文中,我们将深入探讨Lambda表达式的概念、语法和用法,并为每个实例提供代码演示,同时对比与传统方法的区别和优势。
1. Lambda表达式概述
Lambda表达式是一种匿名函数,它主要用于表示简单的行为或代码块,并可以在需要时传递到其他函数中。Lambda表达式可以看作是一个函数式接口的实例,它由三个部分组成:参数列表、箭头符号和表达式体。以下是一个简单的Lambda表达式示例:
() -> System.out.println("Hello, World!");
在这个示例中,Lambda表达式包含一个空参数列表,箭头符号"->"和一个输出"Hello, World!"的表达式体。它可以通过调用Lambda表达式的函数式接口来执行。
2. Lambda表达式语法
Lambda表达式的语法非常简单,它由三个部分组成:参数列表、箭头符号和表达式体。以下是Lambda表达式的语法:
(parameters) -> expression
或者
(parameters) -> { statements; }
其中,参数列表可以是空的、包含一个参数或包含多个参数。如果有多个参数,则需要使用逗号分隔参数。表达式体可以是一个简单的表达式,也可以是一个代码块。
当使用Java语言时,Lambda表达式也由三个关键部分组成:
参数列表:指定Lambda函数接受的参数。参数可以有零到多个,用逗号隔开,放在小括号中。
箭头符号:箭头符号“->”用于分隔参数列表和表达式体。它表示将给定的参数映射到表达式体中进行计算。
表达式体:指定Lambda函数执行的代码块,可以是任何有效的表达式或语句块。
下面是一个简单的示例,展示了一个使用Lambda表达式来对字符串数组进行排序的例子:
// 对字符串数组进行排序 String[] myArray = {"hello", "world", "lambda", "expression"}; // 使用Lambda表达式定义排序规则 Arrays.sort(myArray, (String str1, String str2) -> str1.compareTo(str2)); // 输出排序后的结果 System.out.println(Arrays.toString(myArray));
在这个例子中,Lambda表达式被用作Comparator的实现传递给Arrays.sort方法。Lambda表达式(String str1, String str2) -> str1.compareTo(str2)指定了排序规则,它接受两个参数str1和str2,并返回它们比较的结果。这意味着该字符串数组将按字母序进行排序。
需要注意的是,Lambda
表达式需要使用函数式接口来实现。函数式接口是一个只有一个抽象方法的接口,它可以被Lambda
表达式实现。Java 8提供了许多内置的函数式接口,例如Comparator
、Runnable
和Function
等。
3. Lambda表达式用法
Lambda表达式的主要用途是作为函数式接口的
提供了一些demo;
1.遍历列表并输出每个元素
List<String> list = Arrays.asList("apple", "banana", "orange"); // 使用Lambda遍历列表 list.forEach(item -> System.out.println(item)); // 常规写法 for (String item : list) { System.out.println(item); }
2.筛选列表中的偶数并返回一个新列表
List list = Arrays.asList(1, 2, 3, 4, 5, 6);
// 使用Lambda筛选偶数
List<Integer> evenList = list.stream().filter(num -> num % 2 == 0).collect(Collectors.toList()); System.out.println(evenList); // 常规写法 List<Integer> evenList2 = new ArrayList<>(); for (Integer num : list) { if (num % 2 == 0) { evenList2.add(num); } } System.out.println(evenList2);
3.将字符串转换为大写并返回一个新列表
List<String> list = Arrays.asList("apple", "banana", "orange"); // 使用Lambda将字符串转换为大写 List<String> upperList = list.stream().map(str -> str.toUpperCase()).collect(Collectors.toList()); System.out.println(upperList); // 常规写法 List<String> upperList2 = new ArrayList<>(); for (String str : list) { upperList2.add(str.toUpperCase()); } System.out.println(upperList2);
4.计算列表中所有元素的总和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 使用Lambda计算列表元素总和 int sum = list.stream().reduce(0, (a, b) -> a + b); System.out.println(sum); // 常规写法 int sum2 = 0; for (Integer num : list) { sum2 += num; } System.out.println(sum2);
5.将列表中的元素转换为键值对并放入Map中
List<String> list = Arrays.asList("apple", "banana", "orange"); // 使用Lambda将列表中的元素转换为键值对并放入Map中 Map<String, Integer> map = list.stream().collect(Collectors.toMap(Function.identity(), String::length)); System.out.println(map); // 常规写法 Map<String, Integer> map2 = new HashMap<>(); for (String str : list) { map2.put(str, str.length()); } System.out.println(map2);
6. 筛选集合中的元素
// 使用Lambda表达式筛选出小于10的数字 List<Integer> numbers = Arrays.asList(1, 5, 10, 15); List<Integer> filteredNumbers = numbers.stream() .filter(n -> n < 10) .collect(Collectors.toList()); // 传统写法 List<Integer> filteredNumbers = new ArrayList<>(); for (Integer n : numbers) { if (n < 10) { filteredNumbers.add(n); } }
7. 在集合中进行映射
// 使用Lambda表达式将字符串转换为它们的长度 List<String> words = Arrays.asList("apple", "banana", "orange"); List<Integer> wordLengths = words.stream() .map(s -> s.length()) .collect(Collectors.toList()); // 传统写法 List<Integer> wordLengths = new ArrayList<>(); for (String s : words) { wordLengths.add(s.length()); }
8.对集合中的元素进行排序
// 使用Lambda表达式将集合中的元素按字母顺序排序 List<String> words = Arrays.asList("apple", "banana", "orange"); Collections.sort(words, (s1, s2) -> s1.compareTo(s2)); // 传统写法 List<String> words = Arrays.asList("apple", "banana", "orange"); Collections.sort(words, new Comparator<String>() { public int compare(String s1, String s2) { return s1.compareTo(s2); } });
9.执行多个操作
// 使用Lambda表达式执行多个操作 List<String> words = Arrays.asList("apple", "banana", "orange"); words.stream() .filter(s -> s.startsWith("a")) .map(s -> s.toUpperCase()) .forEach(System.out::println); // 传统写法 List<String> words = Arrays.asList("apple", "banana", "orange"); for (String s : words) { if (s.startsWith("a")) { System.out.println(s.toUpperCase()); } }
10.对整数数组进行排序
//传统写法: int[] arr = {3, 1, 4, 1, 5, 9, 2, 6, 5}; Arrays.sort(arr, new Comparator<Integer>() { public int compare(Integer a, Integer b) { return a - b; } });
//Lambda写法: int[] arr = {3, 1, 4, 1, 5, 9, 2, 6, 5}; Arrays.sort(arr, (a, b) -> a - b);
说明:这个示例展示了如何使用Lambda表达式对一个整数数组进行排序。在传统写法中,我们需要定义一个实现Comparator接口的类,并在排序时将其传递给Arrays.sort()方法。而在Lambda写法中,我们只需要编写一行简单的代码即可完成相同的操作。
11使用Stream API过滤集合元素
//传统写法: List<String> list = Arrays.asList("apple", "banana", "cherry", "date"); List<String> filteredList = new ArrayList<>(); for (String s : list) { if (s.startsWith("a")) { filteredList.add(s); } }
//Lambda写法: List<String> list = Arrays.asList("apple", "banana", "cherry", "date"); List<String> filteredList = list.stream() .filter(s -> s.startsWith("a")) .collect(Collectors.toList());
说明:这个示例展示了如何使用Lambda表达式和Stream API对一个字符串列表进行过滤。在传统写法中,我们需要手动遍历整个集合并筛选出符合条件的元素,而在Lambda写法中,我们可以使用stream()方法将集合转换为流,并使用filter()方法对流进行过滤操作。
12. 使用Lambda表达式作为方法参数
//传统写法: public static void operate(int a, int b, Operation operation) { System.out.println(operation.operate(a, b)); } interface Operation { int operate(int a, int b); } operate(2, 3, new Operation() { public int operate(int a, int b) { return a + b; } });
//Lambda写法: public static void operate(int a, int b, IntBinaryOperator operator) { System.out.println(operator.applyAsInt(a, b)); } operate(2, 3, (a, b) -> a + b);
说明:这个示例展示了如何使用Lambda表达式作为方法参数。在传统写法中,我们需要定义一个实现某个接口的类,并在调用方法时将其传递给方法。而在Lambda写法中,我们可以直接在调用方法时编写Lambda表达式作为参数,从而省略了额外的类定义。
13.使用Lambda表达式作为变量
//传统写法: public static void printMessage(String message) { System.out.println(message); } printMessage("Hello, world!");
//Lambda写法: Consumer<String> printer = (message) -> System.out.println(message); printer.accept("Hello, world!");
说明:这个示例展示了如何使用Lambda表达式定义一个函数式接口的实现,并将其作为变量使用。在传统写法中,我们需要定义一个方法并在调用时传递参数。而在Lambda写法中,我们可以先定义一个函数式接口,然后使用Lambda表达式创建其实现,并将其赋值给一个变量。
4.Lambda表达式优缺点
Lambda表达式具有以下优点:
简洁:使用Lambda表达式可以少写很多样板代码。
灵活:Lambda表达式可以在运行时定义,在需要时才创建。
易读:Lambda表达式的语法简单明了,易于理解。
Lambda表达式也具有以下缺点:
可读性:过度使用Lambda表达式可能会降低代码的可读性。
性能:Lambda表达式的性能可能比普通方法略差。但在大部分场景下,这个差距是微不足道的。