java1.8新特性之函数式接口_学习心得

声明:本文为个人学习心得,不代表实际情况,有错误请指出
注意!java1.8的特性中以函数式接口Lambda 表达式为主的方法引用Stream APIOptional 类是同一种风格的编程方式,这几种配套使用才能发挥出它们的最大优势。本人观点是能不使用就不使用,只有在必须需要它来优化代码和逻辑时再使用。切莫为了装* 而装*.

这几种特性写出来的代码对于不了解它的码农来说就是噩梦,难以理解,可读性极差。并且学习之路也陡峭,没有一个月的业余学习时间是根本无法正常使用的。但是对于熟悉这种编程方式的人来说就是如鱼得水,编程效率和代码可读性可以得到很大的提升,少写许多冗余的代码

函数式接口主要包括以下几个接口和衍生出来的其他接口:

1.Consumer<T> 代表了接受一个输入参数T并且无返回的操作
2.Function<T,R>接收一个参数T,返回R
3.Predicate<T>接收一个参数T返回一个boolean类型的值

本文主要讲解前三种
学习函数式最好掌握以下知识点,不会也没关系,只是学习比较吃力:

1.java1.8中 default 修饰的默认方法
2.java1.8中 lambda表达式
3.java1.8中 方法引用

1.Consumer< T>

java源码:Iterable接口中的默认方法foreach参数就是Consumer类型
代码001

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

调用方式如下几种方式:
代码002

        List<User> userList=new ArrayList<>();//数据省略不写
        //1.普通for循环
        for(int i=0;i<userList.size();i++){
            System.out.println(userList.get(i).getName());
        }
        //2.foreach
        for(User user:userList){
            System.out.println(userList.get(i).getName());
        }
        //3.重点:最复杂,新手最易懂的方式
        userList.forEach(user->{
            System.out.println(user.getName());
        });
        //4.函数式参数只有一句代码时可以简化去掉大括号,去掉分号
        userList.forEach(user -> System.out.println(user.getName()));

以上所有方式的代码打印结果一致
根据代码上边001的源码分析可知for循环中action.accept(t); 的参数就是代码002中的user
user的名字随便起,相当于002代码里函数式代码的引用,System.out.println(user.getName()) 就是函数式的参数,在函数式参数的代码块中可以引用其他地方的变量,(注意!引用时,在代码块外所有变量相当于被final修饰),如下:
在这里插入图片描述
直接赋值会编译报错!
测试使用代码如下:

    public static void main(String[] args) {

        User user=new User(1,"Jack");
        test1(user,u->{
            System.out.println("我的朋友是:"+u.getName());
        });
        test1(user,u->{
            System.out.println("我的哥哥是:"+u.getName());
        });
    }
    public static void test1(User user,Consumer<? super User> consumer){
        System.out.println("----这里是大量逻辑代码1");

        consumer.accept(user);
        System.out.println("----这里是大量逻辑代码2");
    }

运行结果:
在这里插入图片描述

2.Function<T,R>

Function相较于Consumer多了个返回值
测试代码如下:

    public static void main(String[] args) {
        callTest2();
    }
    public static void callTest2(){
        List<User> userList=new ArrayList(){{
            add(new User(11,"Jack"));
            add(new User(12,"zhangsan"));
            add(new User(23,"lisi"));
            add(new User(34,"wangwu"));
        }};
        test2(userList,user -> {
            if(user.getAge()<18){
                return "未成年";
            }
            return "已经成年";
        });
    }
    public static void test2(List<User> list, Function<? super User,? extends String> function){
        System.out.println("----这里是大量逻辑代码1");
        list.forEach(user->{
            System.out.println(user.getName()+":"+function.apply(user));
        });
        System.out.println("----这里是大量逻辑代码2");
    }

运行结果:
在这里插入图片描述

3.Predicate< T>

Predicate为参数时,代码块内要返回一个boolean值
我参考list.stream().filter()写出如下测试代码

public static void callTest3(){
        List<User> userList=new ArrayList(){{
            add(new User(11,"Jack"));
            add(new User(12,"zhangsan"));
            add(new User(23,"lisi"));
            add(new User(34,"wangwu"));
        }};
        //得到年龄大于18岁的人
        List<User> =test3(userList,user -> {
            return user.getAge()>18
        });
        //上边的代码可以这样简化
        System.out.println("大于18岁的");
        List<User> list3=test3(userList,user ->user.getAge()>18);
        list3.forEach(user -> System.out.println(user.getAge()));

        System.out.println("名字中含有'z'的");
        List<User> list4=test3(userList,user ->user.getName().contains("z"));
        list4.forEach(user -> System.out.println(user.getName()));
        list3.stream().filter()
}
public static List<User> test3(List<User> list, Predicate<? super User> predicate){
        Objects.requireNonNull(list);//提前判空
        List<User> userList=new ArrayList<>();
        list.forEach(user->{
            if(predicate.test(user)){
                userList.add(user);
            }
        });
        return userList;
}

运行结果:
在这里插入图片描述
版权声明:本文为博主原创文章,未经博主允许不得转载。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值