Java——lambda表达式
Java lambda表达式是Java 8中引入的一种新特性,它可以用来简化代码并提高程序员的生产力。Lambda表达式本质上就是一个匿名函数,它没有名称、修饰符和返回类型。
在使用lambda时需要注意以下几点:
- Lambda表达式由箭头(->)分隔成两部分:左侧为参数列表,右侧为所需执行的功能。
- 如果只有一个参数,则不必使用括号;如果没有参数则必须加上空括号()。
- 如果要指定数据类型,则需要将其放在圆括号内,并且也可以省略掉大括号{}以及return关键字。
下面给出了三个例子说明如何使用lambda:
- 使用无参方法
Runnable r = () -> System.out.println("Hello World");
这里我们定义了一个Runnable
对象r,在其中实现了run方法打印"Hello World"字符串。因此当调用该对象的run方法时会输出相应内容。
- 使用单个输入变量
Consumer<String> c = (s) -> System.out.println(s);
c.accept("This is a test.");
这里我们定义了一个消费者接口Consumer<T>
型别T被设置为String, 并创建对应于该接口实例c 。然后通过accept 方法传递“ This is a test.” 字符串作为唯一输入值进行测试.
- 省略形参声明与花括号
Comparator<Integer> c = (a, b) -> a.compareTo(b);
这里我们定义了一个比较器接口Comparator<T>
型别T被设置为Integer,并创建对应于该接口实例c。然后通过compareTo方法进行两个整数的大小比较。
总之,Java lambda表达式是一种简洁、灵活和强大的编程方式,在处理集合数据时尤其有用。它可以帮助程序员更快地开发出高效且易维护的代码。
除了上述介绍的基本用法,Java lambda表达式还有一些高级特性:
- 方法引用
方法引用是lambda表达式的简化形式。它可以直接使用已经存在的方法来代替lambda中需要实现的功能。
例如,在对一个字符串列表进行排序时,我们可以这样写:
List<String> list = Arrays.asList("apple", "banana", "orange");
list.sort(String::compareToIgnoreCase);
其中String::compareToIgnoreCase
就是通过“双冒号”操作符将该类中定义好并且可重载(即参数类型和个数不同)与当前调用处相匹配函数名字传递给sort() 函数作为比较器对象.
- Lambda范围
Lambda表达式内部访问外部变量时会创建一个新局部变量,并拷贝其值到Lambda体内。因此在修改该局部变量后原始值仍然保持不变。
例如,
int num = 10;
Runnable r = () -> {
int num2=20; // 局域常规声明
System.out.println(num); // 访问num 变量, 输出结果: 10
};
r.run();
- Stream API
Stream API 是 Java8 中新增加处理集合数据流程方式API 。 它提供了很多便捷、灵活而强大地聚合操作以及过滤等能力 ,使得开发者们更容易编写出优雅而有效率代码 .
下面展示一个简单的例子:
List<String> list = Arrays.asList("apple", "banana", "orange");
long count = list.stream().filter(s -> s.startsWith("a")).count();
System.out.println(count); // 输出结果: 1
这里我们使用了stream()
方法将列表转换为流,然后通过filter()
方法过滤出以"a"开头的字符串,并最终统计数量。
总之,Java lambda表达式是一种非常强大和灵活的编程方式。它可以帮助程序员更快地实现代码并提高生产力,在处理集合数据时尤其有用。同时也需要注意Lambda范围、Stream API等相关特性来避免潜在问题或错误发生。
4. 函数式接口
函数式接口是指只有一个抽象方法的接口。Java lambda表达式可以被赋值给这种类型的变量,从而实现对该单一方法进行重写。
例如,在使用Comparator
时我们就需要传递一个比较器对象作为参数,它必须满足“只包含一个抽象方法”的条件:
public interface Comparator<T> {
int compare(T o1, T o2);
}
因此在创建比较器对象时我们可以直接使用lambda表达式来代替原本需要定义匿名内部类的方式:
List<String> list = Arrays.asList("apple", "banana", "orange");
list.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
- 并行流处理
并行流(Parallel Streams)是Stream API中提供了多线程执行集合数据操作功能 。 它能够将大型数据分割成小块,并且利用所有可用CPU核心同时处理每个子任务以加速整体计算过程 。
下面展示如何通过并行流求出列表元素平方和:
List<Integer> numbers = Arrays.asList(3, 4, 7 ,8);
int sumOfSquares = numbers.parallelStream().mapToInt(x -> x * x).sum();
System.out.println(sumOfSquares); // 输出结果: 114
- Lambda与Optional结合应用
Lambda 表达 式 和 Optional 类 型 是 Java 中两个非常强 大 的 特性 。 它们的结合使用可以帮助我们更好地处理空值问题,避免出现 NullPointerException 异常。
例如,在对一个字符串进行转换时可能会产生 null 值:
String str = "123";
Integer num1 = Integer.parseInt(str); // 正确情况下返回整数
str = "";
Integer num2= Integer.parseInt(str); // 抛出异常: NumberFormatException
这里如果输入为空串,则parseInt()
方法将抛出NumberFormatException。为了解决该问题,我们可以通过Optional类型来包装结果并在需要时检查是否存在:
String str="";
Optional<Integer> optionalNum3 =
Optional.ofNullable(
(str.isEmpty()) ? null : Integer.valueOf(str));
if(optionalNum3.isPresent()){
System.out.println("Value is present.");
} else {
System.out.println("Value not available.");
}
总之, Java lambda表达式是一种非常强大和灵活的编程方式,并且与其他Java特性如函数接口、Stream API等相互配合能够实现更加高效而优雅代码设计及开发过程.
7. Lambda与注解
Java 8中的Lambda表达式可以和注解一起使用,这使得我们能够更加灵活地定义自己的函数接口。
例如,在下面代码片段中,@FunctionalInterface
注释用于标记该接口是一个功能性 接 口 ,并且只包含了单个抽象方法:
@FunctionalInterface
interface MyFunction {
int apply(int x, int y);
}
然后在调用时就可以直接传递lambda表达式作为参数:
MyFunction add = (x,y) -> x + y;
int result = add.apply(3,4); // 结果:7
通过上述方式实现对两数求和操作。同时也需要注意到 apply()
方法被重写以满足当前需求.
总之,Lambda 表 达 式 和 Java 中其他特 性 如 函数型 接 口、Stream API 等相互配合应用可帮助程序员编写出高效而优雅 的代 码 。 同时它们还支持多种语言级别(如类型推断)及运行环境层次 (如JVM JIT 编译器等),从而进一步提升开发者生产力 .
本文来自博客园,作者:两拳ko小yu,转载请注明原文链接:https://www.cnblogs.com/SwapEnd/p/17373006.html