Java8特性之Lambdas(二)functional interface
- lambda表达式,语法
(参数) -> 表达式
或者
(参数) -> {语句;}
- () -> {}
- (int i) -> i>10
- () -> “hello”
- (int i) -> return 0;
上面的表达式中,4是不对的,应该为(int i) -> {return 0;}
- lambda表达式,使用
前提需要有一个函数接口(functional interface),例如上一节讲到的FilterIntf,就是functional interface,因为它只有一个接口方法:
public interface FilterIntf {
boolean filter(Student student);
}
//这种定义就不是functional interface,因为没有要实现的方法
public interface FilterIntf {
}
在JDK中也有很多funcional interface,比如常用的:Runnable、Comparator、Callable,他们都有且只有一个接口方法,例如我们要创建一个线程可以这样:
@Test
public void testThreadByLambda(){
new Thread(() -> System.out.println("hello thread")).start();
}
也可以
Runnable r = () -> System.out.println("hello thread2");
new Thread(r).start();
- 实际中的例子,得到程序的执行时间
@Test
public void testExecTime() throws InterruptedException {
long st = System.currentTimeMillis();
for(int i=0; i<10; ++i){
i += 1;
Thread.sleep(500);
}
System.out.println(System.currentTimeMillis() - st);
}
缺点:不够灵活,每个方法中都需要得到startTime和endTime,不好维护
使用Lambda来封装这个例子:
- 使用Suplier,它是java.util.function提供的Functional Interface,是一个() -> T
public static <T> T traceTime(Supplier<T> methord){
long start = System.currentTimeMillis();
try{
T result = methord.get();
return result;
}finally{
System.out.println(System.currentTimeMillis() - start);
}
}
这样我们就可以传入一个方法,然后就可以得到方法的执行时间,但是还可以再完善,试想一下如果不适用println,使用Log4j呢?那么很明显时间内容处理也需要抽象出来。
- 增加一个TimeTracer接口,可以任意的实现时间内容的处理方式
public interface TimeTracer {
void onTrace(long cast);
}
- 最后得到
//Utils.java中的方法
public static <T> T traceTime(Supplier<T> methord, TimeTracer tracer){
long start = System.currentTimeMillis();
try{
T result = methord.get();
return result;
}finally{
tracer.onTrace(System.currentTimeMillis() - start);
}
}
testExecTime
就可以修改为:
@Test
public void testExecTime(){
Utils.traceTime(() -> {
for (int i=0; i<10; ++i){
i = i + 1;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return 0;
}, (cast -> System.out.println("exec time: " + cast/1000.00 + "s")));
}