Lambda的基础使用
Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。
没有使用lambda的方式(匿名内部类)
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent actionEvent){
System.out.println("Action detected");
}
});
使用lambda
// () -> {执行体}
// 无参数的情况下()括号不能省略
button.addActionListener( () -> {
System.out.println("Action detected");
});
// 参数名 -> {执行体}
// 有且只有一个参数的情况下()括号可以省略
button.addActionListener( actionEvent -> {
System.out.println("Action detected");
});
// (参数名) -> 执行体
// 当方法的执行体只有一句时,可以省略大括号和分号
button.addActionListener(actionEvent -> System.out.println("Action detected") );
一些特殊情况下的写法
-
当方法有返回值时,如果带返回值的方法有好多行代码,正常大括号;
如果带返回值的方法只有一行代码时,省略大括号、分号和return。
-
接口
public interface A { String test(String str); }
-
没有使用lambda(匿名内部类)
A a = new A() { @Override public String test(String str) { return str + "test"; } };
-
使用lambda
//此处的参数只有一个,括号可以省略 //省略后的写法:A a = str -> str + "test"; A a = (str) -> str + "test";
-
-
当子类方法实现中引用了别人写好的方法
方法的引用前提:自己子类的方法和引用的方法参数返回值一样
-
接口
public interface B { //将String转换为int int parse(String s); }
-
没有使用lambda(匿名内部类)
B b = new B( @Override public int parse(String s){ return Integer.parseInt(s); } );
-
使用lambda
// 方式一:代码只有一行,省略大括号、分号和return B b = (s) -> Integer.parseInt(s); // 方式二:方法引用,因为子类的方法parse和引用的方法parseInt参数返回值一样,因此可以省略参数 // 因为方法体只有一行代码,所以可以省略大括号、分号和return。 // 类名 :: 方法名 B b2 = Integer::parseInt;
-
-
当子类方法实现中引用了一个构造方法
-
接口
public interface C { //该方法返回一个Person对象 Person get(String name, int age); }
-
Person类
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } }
-
没有使用lambda(匿名内部类)
C c = new C ( @Override public Person get(String name, int age){ return new Person(name, age); } );
-
使用lambda
// 方式一:代码只有一行,省略大括号、分号和return C c2 = (name,age) -> new Person(name,age); // 方式二:方法引用,方法体中引用了Person类的构造方法 // 类名 :: new C c3 = Person::new;
-
扩展
-
利用lambda遍历集合
List<String> list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("e"); //匿名内部类遍历 list.forEach(new Consumer<String>() { @Override public void accept(String value) { System.out.println(value); } }); //lambda写法 list.forEach( (value) -> System.out.print(value) ); //方法引用 引用了out对象的print方法而已 list.forEach(System.out::print);
-
@FunctionalInterface注解
接口的上面添加一个注解@FunctionalInterface
接口中只允许出现一个抽象方法 但是如果接口中有static方法或default修饰的方法 是可以多个的如果一个接口中包含不止一个抽象方法,那么不能使用@FunctionalInterface,编译会报错。
@FunctionalInterface public interface Test { // 抽象方法 Person get(String name,int age); //JDK1.8之后出现的 //接口中可以使用default关键字修饰普通方法 //不是抽象方法 default void test1(){ System.out.println("test1"); } //不是抽象方法 default void test2(){ System.out.println("test2"); } //不是抽象方法 static静态方法 static void test3(){ System.out.println("test3"); } }