java的lambda表达式
java的lambda表达式
来源:
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
- 语法
(parameters) -> expression
或
(parameters) ->{ statements; }
以下是lambda表达式的重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
注意:
- Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在下面例子中,使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
- Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。
简单例子:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
使用
1.定义一个接口,接口只能有一个方法
interface MathOperation {
int operation(int a, int b);
}
2.声明接口,并设置lambda表达式(声明多个接口来定义不同的表达式)
// 类型声明
MathOperation addition = (int a, int b) -> a + b;
MathOperation subtraction = (a, b) -> a - b;
3.创建方法,调用lambda,设置参数
//需要传入的参数,lambda表达式
private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);
}
4.调用方法
addition.operation(111,222);
- lambda表达式不会对参数造成改变
MathOperation addition = (int a, int b) -> ++a;
int aa=100;
addition.operation(aa,222);
//运行之后,addition方法的值是101,aa仍是100,没变
- lambda调用外部参数,则此参数是final的;
int aa=100,bb=200;
MathOperation addition = (int a, int b) -> a+bb ;
addition.operation(aa,222);
//调用了外部定义的bb参数,虽然bb没有设置final,但是bb默认设置为final了,若是修改bb,会出现异常
- lambda表达式参数名与所在类的参数名不能重复;
int a=100,b=200;
// 类型声明
MathOperation addition = (int a, int b) -> a+b ;//这样会异常,因为 int声明的变量名和MathOperation中的变量名相同,会冲突
- 遍历
// 以前的循环方式
for (String player : players) {
System.out.print(player + "; ");
}
// 使用 lambda 表达式以及函数操作(functional operation)
players.forEach((player) -> System.out.print(player + "; "));
// 在 Java 8 中使用双冒号操作符(double colon operator)
players.forEach(System.out::println);
- 匿名内部类
// 1.1使用匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
}).start();
// 1.2使用 lambda expression
new Thread(() -> System.out.println("Hello world !")).start();
// 2.1使用匿名内部类
Runnable race1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
};
// 2.2使用 lambda expression
Runnable race2 = () -> System.out.println("Hello world !");
// 直接调用 run 方法(没开新线程哦!)
race1.run();
race2.run();
- 类排序
//原排序
String[] players = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka", "David Ferrer",
"Roger Federer", "Andy Murray",
"Tomas Berdych", "Juan Martin Del Potro",
"Richard Gasquet", "John Isner"};
// 1.1 使用匿名内部类根据 name 排序 players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.compareTo(s2));
}
});
// 1.2 使用 lambda expression 排序 players
Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
Arrays.sort(players, sortByName);
// 1.3 也可以采用如下形式:
Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
其他排序规则
//根据 surname(第二个字符串进行排序,比如Rafael Nadal中的Nadel)
Comparator<String> sortBySurname = (String s1, String s2) ->
( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) );
Arrays.sort(players, sortBySurname);
//或者
Arrays.sort(players, (String s1, String s2) ->
( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) )
);