本次玩一下jdk8新增的lambda。
首先我们写一个接口,叫做Filter(拦截器)。如下
@FunctionalInterface
public interface Filter<T> {
T filter();
}
这里你应该能看懂泛型了吧, 我们在接口中定义了一个抽象方法叫filter返回泛型。
于是再写个测试类吧,叫啥名无所谓,整个main方法便于测试。
在测试类中写了个static方法,需要传入filter的一个实例(new出来的对象),打印,然后返回,main方法调用这个静态方法。
因为filter是一个接口,不能new出实例,所以需要用匿名内部类,对吧?这么做你应该能看懂。
为了方便我使用String对象。
public class LambdaTest {
private static Object test (Filter filter) {
System.out.println(filter.filter());
return filter.filter();
}
public static void main(String[] args) {
test(new Filter() {
@Override
public Object filter() {
return "hello";
}
});
}
}
这种内部类的写法相信你在将Runnable实例传给Thread的时候用过了吧 ,通过lambda我把它变一下(只动了main方法哈)。为了对比,我把两个main方法放在一起
//lambda改变的搁这
public static void main(String[] args) {
test( () -> {
return "hello";
} );
}
public static void main(String[] args) {
test(new Filter() {
@Override
public Object filter() {
return "hello";
}
});
}
你肯定开始头皮发麻了吧,你瞧,test方法里的这个内部类变成了一个()-> {} ,这个()里填需要给filter()这个方法传入的参数,这里的filter()方法没有参数,所以里面什么也不填。
这个 -> 是一个操作符,你大可不必管它,后面有个{}, 在他里面写你原本卸载filter()方法里的代码。
你肯定疑惑,这么写test方法如何知道你传的是一个filter对象呢? 那是因为我们只定义了一个需要传入filter实例的test()方法,它自动推到出。
你需要注意的是,这样的lambda简化的写法,必须保证接口中只有一个方法,如果多个方法,这么写,它就不知道你在实现哪个方法了,所以啊,这样的简化只适合只有一个抽象方法的接口。
现在你可以把Runnable匿名内部类如下写了:
new Thread(() -> {
System.out.println("hello");
}).start();
是不是简介了很多呢? 你以为这样完了吗,不行,得再简化下。
当实现的方法只有一条语句的时候,我们可以省略{},如下:
new Thread(() ->
System.out.println("hello")
).start();
你可得注意哈,这句语句不要 分号(;)。
lambda 对有返回值的也有特别的简洁优化。(为了对比,我把之前的放一起对比) 如下:
//再次简化。
test(() -> "hello");
test(() -> {
return "hello";
});
假设现在不返回一个字符串了,而是返回一个对象Object,如下:
test(() -> {
return new Object();
});
返回一个new的对象的话,我们可以写成:
// 简化后
test(Object::new);
//简化前
test(() -> {
return new Object();
});
当然可以new各种对象,不是只能Object,但你需要注意哦,()和{}全被省略了。
假设要调用某个静态方法呢? 是不是也同理>>>
public class LambdaTest {
private static User test() {
return new User();
}
// 这里两个static方法使用了重载哦
private static Object test (Filter filter) {
System.out.println(filter.filter());
return filter.filter();
}
public static void main(String[] args) {
// 如果override的方法中只调用了一个static方法,可以这样做 类名::方法名(不需要括号)
test(LambdaTest::test);
}
}
当然,static方法可以,普通方法可不可以捏??
当然可以了,只不过static方法用类名调用,普通方法需要对象调用,我们要先创建对象的
public class LambdaTest {
private static User test() {
return new User();
}
private User test2() {
return new User();
}
private static Object test (Filter filter) {
System.out.println(filter.filter());
return filter.filter();
}
public static void main(String[] args) {
// static方法的调用
test(LambdaTest::test);
//普通方法 的调用,需要先创建对象的
LambdaTest lambdaTest = new LambdaTest();
test(lambdaTest::test2);
}
}
很久以前我见过如下的写法遍历list很是疑惑,现在应该能接受了,你能接受吗!(手动滑稽)
@Test
public void test3() {
List<String> list = new ArrayList<>(Arrays.asList("hello", "java"));
list.forEach(System.out::println);
}
网友评论