1
hello2090 2023-08-26 17:25:16 +08:00 via iPhone
你随便 Google 一下就有了哇,你这里更好是用 pData.ifPresent()
|
2
bringyou 2023-08-26 17:31:24 +08:00 3
String username = Optional.ofNullable(people).ifPresent(People::getName).orElse(null);
|
3
javapythongo 2023-08-26 17:31:49 +08:00
需要从一个对象连续获取值的时候
``` String username = Optional.ofNullable(people).map(People::getName).orElse(null); ``` |
4
bitmin 2023-08-26 17:34:58 +08:00
String username = Optional.ofNullable(people).map(People::getName).orElse(null);
2# ifPresent void |
5
Leviathann 2023-08-26 17:37:08 +08:00
chaining
|
6
baolinliu442k OP @bringyou 太优雅了
|
7
BBCCBB 2023-08-26 17:46:11 +08:00
链式的时候可以用, 简单判断一个字段是否有值的时候, 真不如 if (xxx != null )
|
8
baolinliu442k OP @javapythongo 确实好一点,那大哥,假如 People 对象里面还有一个 Job 对象, 我想获取里面的 jobName, 这种写法可以吗
|
9
baolinliu442k OP @BBCCBB 因为我们项目有时候返回几十个字段,以前都是 String name = people == null ? "" : people.getName() 这样
|
10
fkdog 2023-08-26 17:48:46 +08:00 3
1. 可以在返回值里使用 optional ,提醒调用方这里返回的值可能为空,包装成 optional 对象就是强制要求调用者对空值情况进行判断处理。
2. 连续取值。比如你接到一个层级很复杂的 json 对象,将其转换成 map 结构,一层一层的 get 需要判断 null ,用 Optional 的话,就算是内嵌深度是 10 层,也能用一行 optional 解决,避免出现嵌套 10 层 if-else 判断 |
11
baolinliu442k OP @Leviathann 链式调用吗
|
12
baolinliu442k OP @bitmin 如果 api 这么设计好像也挺清晰的
|
13
baolinliu442k OP @fkdog 这两点都还挺有用的,学到了
|
14
baolinliu442k OP @hello2090 好哒
|
15
baolinliu442k OP @baolinliu442k String jobName = Optional.ofNullable(people).map(People::getJob).map(Job::getJobName).orElse(null);
这样写也可以,嵌套对象取值还挺方便的 |
16
baolinliu442k OP 总结一下就是#10 楼大哥说的优势, 感谢大家的回复
|
17
arloor 2023-08-26 18:18:16 +08:00 via Android
可以减少代码行数,又不损失可读性的时候
|
18
Edward4074 2023-08-26 18:30:45 +08:00 via iPhone
在其他语法丰富的语言里就是
people?.job?.jobName??”” 在 Java 里就只能是这样了 |
19
hello2090 2023-08-26 18:32:29 +08:00
@Edward4074 Groovy!
|
20
cnt2ex 2023-08-26 19:36:51 +08:00
因为 null 指针的引入本身就是个历史错误。用 Optional 类型改正了这个历史错误。
虽然在一些情况下,和写检查 null 一样。但是引入了 Optional 类型相当于强制你做检查了。 |
21
yechentide 2023-08-26 19:51:24 +08:00 via iPhone
@Edward4074 Swift !
|
22
baolinliu442k OP @yechentide dart 里好像也有这个
|
23
Building 2023-08-26 20:01:16 +08:00 via iPhone
惊到我了,以前看到 Java 新增 Optional Value 的时候我还想越来越现代化了,没想到这个老太太的裹脚布果然没让我失望
|
25
cyningxu 2023-08-26 22:31:12 +08:00
kotlin:就这?
|
26
caiqichang 2023-08-26 23:48:59 +08:00
kotlin 更优雅
val jobName = people?.job?.jobName ?: null |
27
humpy 2023-08-27 00:36:17 +08:00
基本不用,这就是个 nullability 的残废实现,慢慢等 https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-May/002276.html 吧
|
28
netabare 2023-08-27 01:05:45 +08:00 via Android 1
一般是用 orElse 、flatMap 来串接不同的处理过程的吧。
if isPresent 这个写法太命令式了。直接 get 的话说实话不如不要用 Optional 。 当然 Optional 确实很难用就是了。 |
29
cheng6563 2023-08-27 01:10:18 +08:00 1
烂设计,没有必要用。
|
30
lisongeee 2023-08-27 01:37:13 +08:00 2
kotlin: val jobName = people?.job?.jobName ?: null
js/ts: const jobName = people?.job?.jobName?.[0] ?? null c#: var jobName = people?.job?.jobName?[0] ?? null Swift: let value = obj?.nestedObj?.property dart: var jobName = people?.job?.jobName ?: null 但是肯定有人觉得 Optional 比上面更好用,毕竟祖宗之法不可变 |
31
ikas 2023-08-27 09:56:56 +08:00
复制一点实际业务代码
var fileName = file.getName(); var fileInfo = new FileInfo(); SessionContext.userName().ifPresent(fileInfo::setUserName); MediaTypeFactory.getMediaType(fileName).map(MediaType::toString).ifPresent(fileInfo::setContentType); |
32
Bingchunmoli 2023-08-27 11:28:59 +08:00 via Android
@lisongeee 有时候??多了有点增加阅读难度,当然也是因为用的不多不够熟悉 kt 。.let 复杂点 ide 提示的自己都看不懂
|
33
tamer 2023-08-27 11:45:51 +08:00
不是拿来单独取代 if 判断的
是拿来写 lambda 的 |
34
PTLin 2023-08-27 14:32:19 +08:00 1
我还记得以前有人笑过 Optional ,大概是说 Java 的 Maybe 居然有三种状态:Just ,Noting 和 NULL 。
|
35
FrankHB 2023-08-27 15:19:43 +08:00 1
@lisongeee null 就是个阉割版的 Optional ,而且明显更祖宗。
Optional 本身本来也不是太大的问题(起码回避起来比起无处不在的 null 来说容易多了),问题是 null 这祖宗干不掉,又另外加上 Optional ,本该是同一种目的凭空多出来不同的不兼容的表达方式乃至于扭曲目的本身(不顾历史,强行为现状洗地而寻找不同的用例场合),混起来效果就很感人了。 |
36
FrankHB 2023-08-27 15:34:54 +08:00 1
@PTLin 多几种其实不是直接问题。上古的 cons pair 限制个别元素就能造出 list monad ,用比较现代一点的说法,决定限制的 unit predicate 是 null?;中古一点的 string 同样也是个 monad ,unit pred 是 string-null? 。其实吧,传统数学上 list 和 string 可以就是一回事。那为什么不嫌弃 string 和 list 共存冗余呢?因为 string 好歹有复杂度 hint 表明适合不同场景(激进一点的还有 encoding 甚至 SSO 之类的假设,但把本属于 text 的东西混同 string 有过度设计的问题,这又是另一回事了)。这个意义上 string 是具有更多实现假设的 list 又确实不都能替代 string ,这种不同层次上的冗余适应新的需求,其实不难接受。
问题是引入的目的和过程。新增的抽象如果没有提供更详细的假设提升到接口的含义,而仅仅是为了给不完善的旧有抽象擦屁股,但被擦屁股的东西又因为兼容性之类的原因没法被彻底替代而只能共存,这样缝合的下场自然不会让用户舒服了。 为什么说 null 是多余的呢?因为 nullable type 历史上本来就是实现偷懒( null pointer )的结果上反向臆造的抽象。要从需求侧讲,没什么和 Maybe 区分的必要,反倒是传统实现习惯(比如死板的错误处理)导致使用者体验很尴尬。相比之下,C++一样也有 optional<T&>不能随便和 T*等价的历史包袱,这里思想包袱就体现得更明显,因为 nullptr 并没有 Java 一样被迫弄得到处都是的存在感,兼容性问题本该不是借口。 |
37
lisongeee 2023-08-27 15:36:31 +08:00
@FrankHB
null 我觉得还好,不好的点是没有把 null 做到编译期,实际上可 null 就是一个简单的联合类型 如果把 null 像 kotlin/ts/c#/Swift/dart 直接做到编译期,我觉得就没啥问题了 Optional 太长太难用了,还是编译期 null 校验+可选链更好用 |
38
Kaiv2 2023-08-27 16:09:12 +08:00
补充一个小点: 在 JDK8 时,使用 Optional 总感觉少了个功能, 在一堆链式调用后,
只有 ifPresent 方法, 不为空的情况下才能执行, 还是需要 if 语句来判断是否为空。 后面发现 JDK9 添加了一个 ifPresentOrElse 方法来解决这个问题。 |
39
Kaiv2 2023-08-27 16:18:00 +08:00
@Kaiv2 补充代码
People p = null; // TODO: Optional<People> people = Optional.ofNullable(p); Map<String, String> result = new HashMap<>(); people.map(People::getUsername) .ifPresentOrElse(e -> { result.put("status", "1"); result.put("name", e); }, () -> { result.put("status", "?"); }); System.out.println(result); |