前言
Java Lambda表达式是匿名内部类的语法糖,它可以简化和取代匿名内部类,JVM内部是通过invokedynamic指令来实现Lambda表达式。
取代某些匿名内部类
无参数函数的写法,在Java7中,如果要创建一个线程,通常如下:
new Thread(new Runnable(){// 接口名
@Override
public void run(){// 方法名
//dosomething...
}
}).start();
如果使用Lambda表达式,可以简写成下面形式:省去了接口名和方法名
new Thread(()->{
//dosomething...
})
带参数函数的写法,在Java7中,如下:
List<String> list = Arrays.asList("This", "is", "my", "world");
Collections.sort(list, new Comparator<String>(){// 接口名
@Override
public int compare(String s1, String s2){// 方法名
if(s1 == null)
return -1;
if(s2 == null)
return 1;
return s1.length()-s2.length();
}
});
使用Lambda表达式,如下:
List<String> list = Arrays.asList("This", "is", "my", "world");
Collections.sort(list, (s1,s2)->{
if(s1 == null)
return -1;
if(s2 == null)
return 1;
return s1.length()-s2.length();
})
上面两个例子可以看出,要使用Lambda表达式代替匿名内部类,必须有函数接口,也就是説不在随便在任何地方使用Lambda表达式。
实际上Java8中新引入了函数接口的概念,函数接口是指内部只有一个函数的接口。
另外Lambda表达式另一个依据是类型推断机制,在上下文信息足够的情况下,编译器可以推断出参数表的类型,而不需要显式指名。像上面的例子2,不需要指定s1和s2的类型,Lambda表达式根据上下文会推断出来 。
自定义函数接口
自定义函数接口很容易,只需要编写一个只有一个抽象方法的接口即可。如下:
// 自定义函数接口
@FunctionalInterface
public interface ConsumerInterface<T>{
void accept(T t);
}
//使用自定义函数接口
class MyDemo<T>{
private List<T> list;
public void each(ConsumerInterface<T> consumer){// 1
for(T t : list){
consumer.accept(t);
}
}
}
MyDemo<String> stream = new MyDemo<String>();
stream.each(str -> System.out.println(str)); // 使用自定义函数接口书写Lambda表达式
参考:
http://www.cnblogs.com/CarpenterLee/p/5978721.html
http://www.runoob.com/java/java8-lambda-expressions.html
网友评论