java8新特性,方法引用、Optional、函数式

java8新特性,包括方法引用、Optional

一、方法引用

1.理解

lambda表达式是对函数式接口的一种匿名实现,也就是入参、出参都符合的情况下,加了函数体。
如果函数体只是调用了已有的方法,此时入参、出参、函数体3者都确定了,只需要把要调用的方法描述清楚即可,提供调用者(4种)、方法名即可,此时就可以用方法引用了,是lambda表达式的进一步简化。
于是,根据方法调用者的4种情况,有4种写法。

  • 静态方法引用       :    ClassName :: staticMethodName
    没啥好说的,提供类名+方法名,参数自动补上

  • 构造器引用        :  ClassName :: new
    没啥好说的,提供类名+方法名,参数自动补上

  • 类的任意对象的实例方法引用:    ClassName :: instanceMethodName

    • 类的任意对象指的是由入参中传入的对象(第一个,后面的无论几个都是参数)来调用,也就是说,入参要比调用的方法的参数多一个。这种情况下,调用者是不确定的,调用的时候才确定
        Arrays.sort(strs,(s1,s2)->s1.compareToIgnoreCase(s2));
        //sort的参数比compareToIgnoreCase要多一个,多出来的就是调用者
        Arrays.sort(strs, String::compareToIgnoreCase);
      
    • 看到ClassName :: instanceMethodName,就表示,args0是调用者,后面的args是instanceMethodName的参数,相当于(args0,args...) -> args0.instanceMethodName(args...),args0是ClassName 类型的
    • 入参的数量由接口决定,跟数据无法,比如前一个里面元素是map,那后面的方法引用也只能有一个入参。也就是说,一个运算符里面的函数类型是规定好的,方法引用写啥方法是有限制的,方法引用只是lambda的简化,功能远没有lambda强大。
      比如下图,第二行就报错,因为方法引用无法传入自定义的入参;只能像第三行那样,调用一个无参的方法,除非接口支持,比如Arrays.sort,就支持2个参数
      在这里插入图片描述
  • 特定对象的实例方法引用  :    object :: instanceMethodName
    特定对象指的是在lambda外面创建的对象

    public class Test
    {
        public static void main(String[] args)
        {
            Test test = new Test();
            // lambda表达式使用:
            Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(s -> test.println(s));
            // 特定对象的实例方法引用:
            Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(test::println);
        }
        
        public void println(String s)
        {
            System.out.println(s);
        }
    }
    

2.注意

  • 无法显式传参

3.example

3.1 任意对象

类的任意对象指的是由入参中传入的对象(第一个,后面的无论几个都是参数)来调用,也就是说,入参要比调用的方法的参数多一个。这种情况下,调用者是不确定的,调用的时候才确定

public class Student{
    
    private String name;
    
    private Integer score;
    
    public void setNameAndScore(String name, Integer score)
    {
        this.name = name;
        this.score = score;
        System.out.println("Student "+  name +"'s score is " + score);
    }
     
    public static void main(String[] args)
    {
        /*lambda表达式的用法:
        TestInterface testInterface = (student, name, score) -> student.setNameAndScore(name, score);*/
        //用变量接收lambda表达式,相当于给匿名函数起了个名
        TestInterface testInterface = Student::setNameAndScore;
        testInterface.set(new Student(), "DoubleBin", 100);
    }
    
    @FunctionalInterface
    interface TestInterface
    {
        // 注意:入参比Student类的setNameAndScore方法多1个Student对象,除第一个外其它入参类型一致
        public void set(Student d, String name, Integer score);
    }
}

3.2 特定对象

test对象是lambda外创建的

public class Test
{
    public static void main(String[] args)
    {
        Test test = new Test();
        // lambda表达式使用:
        Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(s -> test.println(s));
        // 特定对象的实例方法引用:
        Arrays.asList(new String[] {"a", "c", "b"}).stream().forEach(test::println);
    }
    
    public void println(String s)
    {
        System.out.println(s);
    }
}

stream API

https://blog.csdn.net/mu_wind/article/details/109516995?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.nonecase

二、Optional

1.com

null这个概念,本身就有争议,它使得方法的返回值变得更复杂。需要做非空判断,而Optional就是把非空判断以及后续操作给封装了(相当于在任意操作前加个为null的判断)
那都有哪些操作呢?
1、为null时返回默认值,不为null时返回自身–orElse
2、为null时返回默认值,不为null时调用方法–map()
3、为null时抛出异常,不为null时返回自身–orElseThrow()
4、为null时返回false,不为null时返回true–isPresent()
5、为null时不执行,不为null时执行代码–ifPresent()
6、为null时返回empty,否则传入predicate进行过滤
。。。。。。
众多场景都有对应的api提供支持

2.创建(包装)

// 1、创建一个包装对象值为空的Optional对象
Optional<String> optStr = Optional.empty();
// 2、创建包装对象值非空的Optional对象
Optional<String> optStr1 = Optional.of("optional");
Optional.of(null);//直接会报错,用来处理不允许为null的场景,用try-catch处理
// 3、创建包装对象值允许为空的Optional对象
Optional<String> optStr2 = Optional.ofNullable(null);

3.map

这个map()的源码,注意入参是一个函数,出参还是Optional,这就意味着后续可以继续调用api,比如orElse(),注意orElse()的入参跟泛型有关。

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent()) //判断value是否为null,也就是Optional包装的值
        return empty(); //返回EMPTY,这意味着后续会触发orElse()的缺省值
    else {
        return Optional.ofNullable(mapper.apply(value)); //mapper是个实现类,apply()方法就是传入的逻辑
    }
}

函数式

将一段逻辑作为一等公民,参数、返回值。
根据场景,将这些逻辑分为:
生产:无参,只有返回值
消费:有参,无返回值
判断:有一个入参,返回boolean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值