栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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::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

null这个概念,本身就有争议,它使得方法的返回值变得更复杂。需要做非空判断,而Optional就是把非空判断这个逻辑给封装了。
当遇到一个变量可能null时,就可以用Optional把它封装起来,然后就可以调用Optional的api来进行操作,比如非空判断,比如为空时如何,不为空时如何。

Optional.ofNullable(student).map(u -> u.getGender()).orElseGet(() -> "Unkown");
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/531488.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号