5分钟快3首页    注册   登录
5分钟快3 = way to explore
5分钟快3 是一个5分钟快3关于 分享和探索的地方
现在注册
已注册用户请  登录
javaWeber
5分钟快3  ›  Java

请教下 java8 的 Optional。。

  •  
  •   javaWeber · 10 天前 · 2443 次点击

    最近写了一堆空指针,打算改用下 java8 的 Optional 。。

    请问下以下代码,怎么用 Optional 表示。

    1. 判断 A 是否为空,然后修改 B 或者执行其他逻辑。

    想过用 if (isPresent())去判空,又觉得跟之前的 if 没什么区别。。

    String str="123";
    String result="abc";
    if(str!=null){
    	result+="def";
    }
    

    2.判断 A 是否为空,然后根据情况执行 if else 里面的逻辑。。

    java9 有个 ifPresentOrElse(),不过项目里用的是 java8 。

    String str="123";
    String result="abc";
    if(str!=null){
    	result+="def";
    }else {
        result+="ghi";
    }
    
    第 1 条附言  ·  9 天前
    5分钟快3我 这里的例子不太准确,判断的是字符串,应该改成对象的。

    5分钟快3我 想避免对象判空,也就是用 Optional 减少 if(对象!=空)这类操作。。
    30 条回复    2020-04-01 21:43:55 +08:00
    javaWeber
        1
    javaWeber   10 天前
    3.还有就是 字符串类型的 Optional.orElse(),这里面 orElse 的默认值用什么好?

    5分钟快3我 看网上很多用.orElse("default"),为空时就给了个默认值"default"或者"unknown"。。感觉很奇怪。
    alphatoad
        2
    alphatoad   10 天前
    用 FP 的思路就很好理解了,相当于 Haskell 的 Maybe
    data Maybe a = Nothing | Just a
    weakish
        3
    weakish   10 天前
    A 是否为空决定是否对 B 进行操作,这里对 B 的操作并没有用到 A 的值,不会碰到空指针,也就没必要用 Optional 。
    weakish
        4
    weakish   10 天前
    "default" 或者 "unknown" 这是教程里为了演示用的吧。实际场景中,就是应该用什么默认值就用什么默认值呀,原来用 `a == null ? a : "xxx"`,现在改成 `a.orElse("xxx")`,只是写法变一下,并不影响默认值的选取。
    bkmi
        5
    bkmi   10 天前 via Android
    要不用 kotlin 吧
    但是5分钟快3你 这两个例子,看不出哪 NPE,就5分钟快3你 现在的写法最简单了…
    lxychn
        6
    lxychn   9 天前
    不用 optional 的话判断为空的 if 忘了写就可能会出错,用了 optional 的一定要用 ifPresent()去判断,不然 compiler 就会报错,避免忘了检查是否为空的情况

    optional 好像和 lamda 结合用的5分钟快3更多
    xixinimei
        7
    xixinimei   9 天前
    当5分钟快3你 意识到一个变量该用 optional 的时候,可以不用 optional 。

    Java 的 Optional 表达能力有限,主要是对自由变量的重新赋值很麻烦,需要用到容器类来5分钟快3包装 。
    optional
        8
    optional   9 天前 via iPhone   ❤️ 3
    Optional 的精髓在 map ifpresent stream
    noreplay
        9
    noreplay   9 天前 via Android   ❤️ 2
    @optional 结合 id 来看,特别让人信服🤓🤓
    chendy
        10
    chendy   9 天前
    Optional 的有点是可以挂回调,配合其他(比如 stream ) api 可以一路点点点点写完一套逻辑,但是如果不习惯挂回调的话就很别扭
    简单场景单独判断 null 足以
    yty2012g
        11
    yty2012g   9 天前
    第一,如5分钟快3你 图上的示例,确实使用 Optional 和判断是否等于 null 没有区别,因为5分钟快3你 的条件分支里面没有使用 str 这个变量。在此情况下,5分钟快3我 认为没有区别。
    第二,假如5分钟快3你 的条件分支有使用 str,那就需要对 str 为 null 的情况赋予其他值,此时可以使用 Optional.orElse("default")或者 Optional.orElseGet(()->"default")这样的方式来代替使用 str 。
    第三,还有一种情况是 str 等于 null 5分钟快3我 要抛异常,很常见,例如 DB 里面查不到数据5分钟快3我 要抛异常,此时可以使用 Optional.orElseThrow(() -> new StrNotFoundException("str 没找到!"))类似的.
    综上,不是什么情况下 Optional 都能达到5分钟快3你 想要的效果,不过最差的基本面也是和判断是否为 null 类似,所以可以尝试去使用
    guyeu
        12
    guyeu   9 天前
    @javaWeber #1 如果不知道用什么好,就用 orThrow,抛出异常。
    CommandZi
        13
    CommandZi   9 天前
    5分钟快3你 这两个例子,不管 str 是不是 null,都不会空指针吧。
    Aresxue
        14
    Aresxue   9 天前
    optional.ifPresent(修改 B), 但就像上面说的5分钟快3你 这个简单调用还不涉及 npe 没必要使用
    cyspy
        15
    cyspy   9 天前
    flatmap
    mezi04
        16
    mezi04   9 天前
    个人理解:把 optional 想想成盒子,of 或者 ofNullable 传入的参数就是盒子里边的东西。optional 的目的是从这个盒子里拿出一个非空数据,5分钟快3你 可以通过一系列的5分钟快3方法 转换盒子里的数据( fliter/flatMap ),或者告诉盒子,如果为空怎么做( orElse/ifPresent 等)。如果5分钟快3你 的模型不符合这个,就没有用 optional 的必要
    hantsy
        17
    hantsy   9 天前
    用 orElseThrow 抛出异常就好了,5分钟快3我 也比较常用。
    Optional<Post> post = posts.findById(id)

    post.map(....).orElseThrow(()->new PostNotFoundException(id))
    hantsy
        19
    hantsy   9 天前   ❤️ 1
    Optional 本身就是解决这中 If Null 判断,如果又回到 If 来判断,还不如不用。
    javaWeber
        21
    javaWeber   9 天前
    @CommandZi 5分钟快3你 这两个例子,不管 str 是不是 null,都不会空指针吧。
    ==============================================
    5分钟快3我 这里的例子写得不太准确,判断的是字符串,应该改成判断对象是否为空的。
    ```
    if(对象!=空){

    }
    ```
    MakHoCheung
        22
    MakHoCheung   9 天前
    Optional 针对的是 str 。
    这代码就算放到 kotlin 也要判 null,因为5分钟快3你 的 str 是 String?类型
    XiLemon
        23
    XiLemon   9 天前
    可以参考一下: http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy 5分钟快3关于 NULL 的处理建议
    ica10888
        24
    ica10888   9 天前
    其实这个是函数式编程的东西,相当于一个5分钟快3包装 。不过一般情况下用来处理链式操作,如 getA().getB().getC() 的空指针异常,其实 kotlin 的语法糖要好看一些...
    tachikomachann
        25
    tachikomachann   9 天前
    5分钟快3我 的理解是用 Optional 没办法减少判空操作,而是强制5分钟快3你 必须判空。所以一旦用了 Optional,就不会无意识地写出 NPE 问题的代码。。
    lyyhello
        26
    lyyhello   9 天前
    5分钟快3你 看下 jdk8 用到 Optional 的地方的源码就知道了。如果有明确的返回,不用 Optional,如果因为各种原因(),结果不能保证一定为空,就用 Optional 返回。而且使用者不是简单的判断是否为空,而是和 Stream 紧密联系着用呢
    Jrue0011
        27
    Jrue0011   8 天前
    Optional 要用上 map/flatMap 、filter 。一般应该是一段代码调用多个5分钟快3方法 ,每个5分钟快3方法 入参都是上个5分钟快3方法 返回值或返回值部分,Optional 的 map/flatMap 可以避免对每个返回值判断 null,如果对返回值的判断不仅仅是否 null 的话,可以用 filter 判断。

    比如这样。。。

    Optional.of(userId).map(userDao::getPhone).filter(phoneService::isChinaMobile).ifPresent(smsService::sendMsg);
    Optional.of(userId).map(userDao::getPhone).map(phoneBook::getContactListByPhone).orElseGet(Collections::emptyList);
    或者如果有需要抛业务异常,也可以用 orElseThrow
    CommandZi
        28
    CommandZi   8 天前
    @javaWeber Optional 设计是用来减少空指针异常,不是减少 if(对象!=空)这类操作的。5分钟快3你 if 后续代码都没调用对象,说明这只是5分钟快3你 程序的固定逻辑而已,不管对象用不用 optional,都是要判断的。
    CommandZi
        29
    CommandZi   8 天前
    @CommandZi 当然这是5分钟快3我 使用 Swift 当中的 Optional 的经验,Java 的没有了解。
    MotherShip
        30
    MotherShip   2 天前
    手头上用的比较优雅的玩法大概是,Repository 层返回一个 Optional 对象,为空则直接一路把异常抛到 Controller 层然后统一处理:

    ```java
    String a = Optional.ofNullable("a").orElseThrow(()->{throw new RuntimeException();});
    ```
    至于5分钟快3你 这两个例子。。确实用不用没啥区别
    5分钟快3关于   ·   FAQ   ·   API   ·   5分钟快35分钟快3我 们 的愿景   ·   广告投放   ·   感谢   ·   实用小5分钟快3工具   ·   1012 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 20:14 · PVG 04:14 · LAX 13:14 · JFK 16:14
    ♥ Do have faith in what you're doing.