美文网首页
jdk8的lambda,有点好玩

jdk8的lambda,有点好玩

作者: 一只小安仔 | 来源:发表于2019-08-07 17:45 被阅读0次

本次玩一下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);
    }

相关文章

网友评论

      本文标题:jdk8的lambda,有点好玩

      本文链接:https://www.haomeiwen.com/subject/qewwdctx.html