lambda表达式在SE1.8中引入,与接口中的唯一的抽象方法相匹配,语法:(参数列表)->返回值,返回值也可以通过{}和return实现.
?
import java.util.*; public class LambdaDemo1 { public static void main(String[] args) { List<String> name = Arrays.asList("James", "Kobe", "Yao"); Collections.sort(name, new Comparator<String>() { public int compare(String s1, String s2) { return s1.compareTo(s2); } }); } }
?静态方法Collections.sort接收一个list和一个Comparator接口作为输入参数,实现对输入的list中的元素进行比较并排序.通常可以用创建匿名Comparator对象,重写compare方法,并作为参数传递给sort方法.
如果使用lambda表达式,可以使代码更加简短易读:
Collections.sort(name, (String s1, String s2) -> { return s1.compareTo(s2); });
?而且,它还可以更简短:
Collections.sort(name, (String s1, String s2) -> s1.compareTo(s2));
此段代码已经省略了{}和return,但是它还可以更短:
Collections.sort(name, (s1, s2) -> s1.compareTo(s2));
?编译器能够自动识别参数类型,类型也可以省略不写.
?
?
一个函数式接口必须有且仅有一个抽象方法声明,可以通过@FunctionalInterface标识,每个与之对应的lambda表达式必须与此相匹配.任何一个只包含一个抽象方法的接口,都可以做成lambda表达式.例:
@FunctionalInterface interface MapDemo<K, V> { V get(K k); } public class LambdaDemo2 { public static void main(String[] args) { MapDemo<String, Integer> map = (k) -> Integer.valueOf(k); System.out.println(map.get("10")); } }
?
考虑极端一点的话,我们可以将函数式接口中的方法定义为无参无返回值的,lambda同样可以相匹配:
@FunctionalInterface interface MapDemo<K, V> { void get(); } public class LambdaDemo2 { public static void main(String[] args) { MapDemo<String, Integer> map = () -> {}; } }
?
这里只是举个例子,在实际编程中并不实用.
?
?
public class LambdaDemo3 { public static void main(String[] args) { MapDemo<String, Integer> map = Integer::valueOf; System.out.println(map.get("10")); } }
?
注意,此段代码中等号右边的Integer是指Integer.valueOf()方法返回值的类型,与上一节代码中的意义不同.
?
class A { String name; public A() { } public A(String name) { this.name = name; } } interface AFactory<T extends A> { T create(String name); } public class LambdaDemo3 { public static void main(String[] args) { AFactory<A> afactory = A::new; A a = afactory.create("name"); System.out.println(a.name); } }
?
通过A::new创建一个A类构造函数的引用.编译器会自动选择合适的构造函数来匹配A.create方法,并调用正确的构造函数.
?
?
public class LambdaDemo4 { public static void main(String[] args) { String s = "20"; MapDemo<String, Integer> map = (k) -> Integer.valueOf(k + s); System.out.println(map.get("10")); } }
?
虽然s不是final的,但此段代码是合法的,运行结果:1020.但下面的代码不合法:
String s = "20"; MapDemo<String, Integer> map = (k) -> Integer.valueOf(k + s); System.out.println(map.get("10")); s="30";
?可见,s在编译的时候被隐式的当做final变量来处理,在lambda内部改变s也是不可以的.
?
public class LambdaDemo4 { String s1; static String s2; public void test() { MapDemo<String, Integer> map1 = (k) -> { s1 = "100"; return Integer.valueOf(s1); }; MapDemo<String, Integer> map2 = (k) -> { s2 = "200"; return Integer.valueOf(s2); }; } }
?
interface MapDemo<K, V> { V get(K k); static void getStatic() { } default void getDefault() { } } public class LambdaDemo4 { public void test() { MapDemo<String, Integer> map1 = (k) -> { MapDemo.getStatic(); return Integer.valueOf(k); }; MapDemo<String, Integer> map2 = (k) -> { // MapDemo.getDefault(); return Integer.valueOf(k); }; } }
?
编译发现,静态方法在lambda表达式可以被访问,而默认方法是不可以的.
?
小结:java SE在1.8引入的lambda表达式实现了与函数式接口中方法的匹配,同时提供很多新的函数式接口,如Comparator等,使程序变得更加简短易读.
原文:http://xiao1zhao2.iteye.com/blog/2189835