
1 vate32 2022-03-30 18:15:38 +08:00 为什么不用,用来处理集合效率多高。“考虑 code viewe”,不会有人看不懂吧 |
2 golangLover 2022-03-30 18:17:30 +08:00 via Android 用 foor loop 的可读性太差了 |
3 LeonL1 2022-03-30 18:17:32 +08:00 虽然可读性确实不太好,但是写起来确实爽啊 |
4 chendy 2022-03-30 18:21:31 +08:00 具体情况具体分析,没有固定标准 有的地方直接循环更清晰,有些地方 stream 更简洁 |
5 fengpan567 2022-03-30 18:23:51 +08:00 stream 就是简洁明了啊 |
6 xianzhe 2022-03-30 18:25:16 +08:00 via Android 离了 stream 不会写了 |
7 lostpg 2022-03-30 18:27:13 +08:00 via Android 我觉得使用 stream 是更明晰的 |
8 SurfaceView 2022-03-30 18:27:42 +08:00 never use. |
9 xuanbg 2022-03-30 18:28:57 +08:00 我觉得更清晰 |
10 keshawnvan 2022-03-30 18:30:15 +08:00 可读性提高了,code review 不应该更简单吗? |
11 eb0c6551 2022-03-30 18:31:08 +08:00 请看《 Effective Java 》 Item 45 : Use streams judiciously |
12 kingfalse 2022-03-30 18:31:12 +08:00 via Android review 的人不是得起码能看得懂 stream..... |
13 kingfalse 2022-03-30 18:31:51 +08:00 via Android 或许该考虑换人 review 了? |
14 pengtdyd 2022-03-30 18:33:39 +08:00 人写出来的代码是给人看的,不是给某些蠢货看的 |
15 Samuelcc 2022-03-30 18:48:45 +08:00 合理地使用 Stream 只会让可读性更好。 只会不合理使用的人换别的写法可读性也不会高到哪里去。。 |
16 w741069229 OP @pengtdyd 但是公司的大佬不让用 stream 和 optional 这些用法 |
17 luckyrayyy 2022-03-30 18:51:19 +08:00 stream 也不是所有情况下都可读性更好的....不是非常复杂的 stream ,我觉得都可以用 |
18 MakHoCheung 2022-03-30 18:52:40 +08:00 @w741069229 听大佬的,如果你想用就用一遍然后删了改回 foreach |
19 TWorldIsNButThis 2022-03-30 18:55:46 +08:00 via iPhone idea 可以一键把 stream 转成 for |
20 gabon 2022-03-30 18:57:24 +08:00 @MakHoCheung intellij idea 可以自动把简单的 stream 转换为 for loop 。 |
21 TWorldIsNButThis 2022-03-30 18:57:48 +08:00 via iPhone @w741069229 那建议他们转 go 永远不升 1.18 的那种 |
22 adoal 2022-03-30 19:50:32 +08:00 via iPhone @w741069229 换个新大佬 |
23 interim 2022-03-30 20:17:17 +08:00 离了 stream 不会写了 +1 |
24 gam2046 2022-03-30 20:18:23 +08:00 @w741069229 #16 有没有一种可能,大佬对项目不够熟悉,目测,看不出类型推导的具体结果,就导致大佬不知道你在干啥。 |
25 w741069229 OP @gam2046 我是新接的,我之前都是梭哈 stream 流,通篇的那种,但是新公司入职后,就不让用了 |
26 w741069229 OP @chnyuwen +1 |
27 pofycn 2022-03-30 22:21:28 +08:00 能用 steam 梭的统统用 stream 梭 管他呢 [狗头] |
28 zmal 2022-03-30 22:41:33 +08:00 你司大佬排斥 stream 的原因无非这么几条: 1. 可读性差。理论上 lambda 范式的代码可读性会更好。如果可读性变差了,说明姿势不太对,业务逻辑和控制逻辑没有分离。 2. 性能损耗。据说相比 for loop 大约 15%的性能损失。但对业务代码来说是可接受的。 3. 不便调试。这个要看具体案例,个人认为不是问题。 4. 老派守旧。无解,建议换公司。 |
29 searene 2022-03-30 23:02:31 +08:00 Stream 出来都多少年了,这都看不懂就不要 review 代码了吧 |
30 Vegetable 2022-03-30 23:05:08 +08:00 笑死,这么多人不明白什么叫可读性是吧。 Stream 确实不错,但是最好少用 lambda ,把代码写短不是本事,写清楚才是。 |
31 Vegetable 2022-03-30 23:06:23 +08:00 Reviewer 欠你的,在网页上一行一行给你走读代码? |
32 tohuer00 2022-03-30 23:06:54 +08:00 得考虑团队整体水平,防止水平差的同事瞎用,干脆一刀切禁掉省事。比如楼上很多一把梭的我看就很危险。 |
33 EscYezi 2022-03-30 23:09:55 +08:00 via iPhone steam filter map 等 api 语义不比 for 来 for 去清晰多了 顺便推荐 vavr 库,更简洁更清晰 |
34 v2eb 2022-03-30 23:13:26 +08:00 via Android 想看下可读性差的 stream 流形式代码是怎么写的。 |
35 gtx990 2022-03-30 23:22:24 +08:00 via Android Java 的完全没问题,Scala 的吐了 |
36 lux182 2022-03-30 23:33:36 +08:00 想知道不用等理由 |
37 Rocketer 2022-03-30 23:35:16 +08:00 via iPhone 这是要照顾纯 Java 6 程序员么?哪怕是写过 JS 的也能看懂 stream 吧? |
38 yazinnnn 2022-03-30 23:47:11 +08:00 你们前端也禁用 lambda 吗? |
39 RobberPhex 2022-03-31 00:02:16 +08:00 用 stream (甚至用函数式编程)都会遇到一个问题,就是堆栈不可回溯了。你只能看到这个 stream 的栈,再往上就看不到上一个 stream/lambda 了,只能看到 stream 库的栈了。 所以我个人觉得,单个语句中,stream 可以用一次,不能再多。 当然,回到问题,公司项目,怎么约定就怎么来,协作重要。 |
40 Jooooooooo 2022-03-31 00:35:55 +08:00 里面抛个空指针不好查. |
42 WebKit 2022-03-31 01:03:10 +08:00 via Android stream 不止简洁,的性能更好 |
43 Hider5 2022-03-31 01:17:33 +08:00 via iPhone Stream 可读性好,但空指针问题不好排查 |
44 w741069229 OP @EscYezi 哈哈哈哈哈。我一直在用 |
45 wxyrrcj 2022-03-31 07:32:16 +08:00 via Android 多好用 为啥不用 |
46 dreamramon 2022-03-31 07:49:47 +08:00 出了空指针,堆栈不好查。 |
47 aptupdate 2022-03-31 08:03:55 +08:00 via iPhone 前段时间有个奇葩需求要对集合各种过滤、排序、分组,当时就感叹要是没有 stream 我得累个半死。 所以这种省时省力的方法为什么不用呢? NPE 问题确实麻烦,不过新版 idea 里有个流调试器,直接可视化处理过程。 |
48 micean 2022-03-31 08:33:05 +08:00 stream 的 lambda 里面要精炼、简洁到不可能出现 NPE 问题 |
49 cweijan 2022-03-31 08:47:25 +08:00 stream 还是要用的, 但是有的程序员水平低, 用 stream 写的代码可读性极差. |
50 neptuno 2022-03-31 09:13:46 +08:00 看不懂 stream ,这个水平 review 了有啥用吗 |
51 ychost 2022-03-31 09:28:52 +08:00 stream 结合 Optional 用起来美滋滋,C# 的 Linq 更加的纯粹舒服 |
52 arthas2234 2022-03-31 09:53:54 +08:00 stream 挺好用的,用来处理集合再适合不过啦。说看不懂的,可读性差的,是没用过的吧 |
53 Stream 及 Lambda 表达式的第一优点就是代码简洁,这跟 code review 是正相关,不是互斥的。 不过 Lambda 表达式能无缝转接,Stream 不能。Stream 使用的是数据流逻辑,跟传统的“判断、循环……”逻辑有区别,转换过去需要学习。但是这个学习成本不大,而且如果是数据结构 /算法已经很溜的,早就回了压根不用学。大佬刚开始不让用,可能还是要考虑团队管理,大佬要是一直不让用,那他 100%是假大佬。 |
54 Huelse 2022-03-31 10:02:48 +08:00 哪来那么多可读性问题?是你自己“懒”吧? |
55 yor1g 2022-03-31 10:09:38 +08:00 java 8 都多少年了 还抱着 java6 么 |
56 superchijinpeng 2022-03-31 10:11:32 +08:00 Why not ? |
57 Loku 2022-03-31 10:15:12 +08:00 stream 都 jdk1.8 的东西了。 现在 jdk1.18 了。 |
58 loryyang 2022-03-31 10:16:17 +08:00 可以,但,注意别过于复杂 我对代码的认知就是,这代码写完,过段时间,你自己能不能很快地看懂,看不懂就说明写得不好。要不改逻辑,要不写注释 最后,stream 也有上面提到的堆栈问题,一般不建议做非常复杂的操作 |
59 xwayway 2022-03-31 10:18:31 +08:00 可以,但是不要过长,一句话完成一个目的,需要写得太长了,那样就成裹脚布了。 |
61 bertonzh 2022-03-31 10:26:58 +08:00 22 年了大概只有 Java 圈才会出现这种问题... |
62 byte10 2022-03-31 10:27:37 +08:00 @RobberPhex 这个是核心问题,一直觉得 stream 有哪里不对,原来在你这里。 |
63 intmax2147483647 2022-03-31 10:29:28 +08:00 说抛空指针不好查的的你不知道在流中对空的处理吗 |
64 dayudayupao 2022-03-31 10:35:06 +08:00 Stream 需要什么可读性,跟业务逻辑代码比起来,这几个集合操作的复杂度有啥,还是把重心放在业务逻辑代码的清晰上来吧,这种语法糖怎么可能承载太多逻辑 |
65 Magentaize 2022-03-31 10:48:16 +08:00 via iPhone 在 stream 里说 NPE ,栈的怕是不会正确使用 stream ? |
66 anzu 2022-03-31 10:57:13 +08:00 看情况,禁止在调用链中写一堆代码,类似 .filter(d -> { /*这里有 10 行代码*/ }) |
67 clf 2022-03-31 10:57:17 +08:00 stream 除了一些小坑( localthread 相关)外,都挺好的。对于可读性的提升也是很大的,相对来说,可以很清晰的知道这份 stream 输出的数据经过了哪些流程。 |
68 nulIptr 2022-03-31 11:23:17 +08:00 2022 年是 linq 发布的第 14 年,stream api 发布的第 8 年。居然还有人讨论这个问题。 |
69 fewok 2022-03-31 11:47:07 +08:00 2022 年了,其实可提出,该不该用 java 了,毕竟其他编程语言也是不错的 |
70 WispZhan 2022-03-31 12:25:40 +08:00 via Android 你们是不是都不屑写 ut ,单元测试? |
71 selca 2022-03-31 12:52:38 +08:00 读个 lambda 都读不明白,啥 reviewer ,水准这么低 |
72 uSy62nMkdH 2022-03-31 13:06:37 +08:00 建议上一段你们产生争议的代码看看。 |
74 mauve PRO 程序员就该写程序员该写的东西! |
75 zw1one 2022-03-31 13:52:51 +08:00 没必要一刀切,写 for 也有写得恶心的,不是 stream 的问题,是写的人有没有维护代码可读性意识的问题。 |
76 siweipancc 2022-03-31 14:01:11 +08:00 via iPhone 不应该用范型,注解也不该用,毕竟大佬可以不学,你不可以不听他的话 |
79 NoKey 2022-03-31 14:20:17 +08:00 太多一刀切的说法,还有说因为不让用 stream 直接换公司的。。。 学 java 的同时,学习一下其他语言 各种语言提供的语法糖不同 如楼上有人说的,如果没有 stream ,各种分组,过滤,排序就不会写了 这实际上是有问题的 当然,要觉得自己这辈子在程序员这路上,只用 java ,且都在 1.8 版本以上,那也没啥问题 |
80 TWorldIsNButThis 2022-03-31 14:33:10 +08:00 via iPhone @EscYezi 还有 eclipse collections Java 官方视频拿 java17 的 stream 跟它对比,说难道更好的抽象(指 eclipse collections )一定会有更差的性能吗?结论为不是,因为 eclipse collections 在他们给出的几个用例下抽象更好且速度也更快 XD |
81 Leviathann 2022-03-31 14:49:33 +08:00 @NoKey 如果用上了比 java8 表达力还烂的语言且收入不是明显高出其他的话,那真的要反省一下自己了 |
82 HanMeiM 2022-03-31 15:13:59 +08:00 @w741069229 为啥不让用 optional ?我不是很明白,更喜欢不确定的空指针返回值吗? optional 在某些情况下更能表达返还值的稳定性。 |
83 uleh 2022-03-31 16:11:33 +08:00 对于工程化比较成熟的团队,只要你的局部小组里能维护好,用什么黑魔法其实都无所谓 但是如果是工程化比较弱的团队,请记住:安全第一! |
84 wupher 2022-03-31 17:26:59 +08:00 stream 绝对应该用。 ReactiveX 倒是可以考虑场景,值得商榷。 |
85 FrankHB 2022-03-31 18:49:04 +08:00 @RobberPhex @dreamramon @loryyang @byte10 提到的一些通病比这里说的原始问题更有毛病得多。 栈作为活动记录的一种实现,本来就用于隐藏过程运行时状态的实现细节。只有直接能在程序中显式访问活动记录的语言(比如至少得有 first-class one-shot continuation ),这种东西才配被要求是和程序员交互的标配。 说白了,在抽象能力弱鸡的语言里没事依赖栈帧是一种习惯性纵容实现泄露抽象的病。 特别是要知道 Java 不光不支持 continuation capture ,甚至连 proper tail call 都没有……设计 JVM 的丈育还用 stack inspection 当挡箭牌,结果差不多被正面打脸: https://stackoverflow.com/a/5097402 退一步讲,真是想要照顾调试体验,又不是 C 这种滥依赖 ABI 兼容的历史包袱,这么多年了连个 shadow stack 都不会实现的弟弟怎么好意思变成工业主流的? 算了,还是先停止把 stack 叫做什么劳什子“堆栈”开始吧。 (反思为什么 NPE PTSD 以及 optional 实质套娃的问题就不提了,本质算不上 Java 特色,虽然这年头也快成了 Java 特供问题了。) |
86 hervey0424 2022-03-31 20:58:11 +08:00 C# 十年前都没有这种问题 |
87 lmshl 2022-03-31 21:13:44 +08:00 你们还在争论该不该用的时候,我的 5 个 Akka Stream 已经上线生产了。 ZStream / fs2 混着用表示看 Stream API 毫无压力 |
88 leeg810312 2022-04-01 08:34:11 +08:00 via Android 用循环写代码逻辑不清晰的人,用 stream 写一样不清晰,连 stream 都看不明白的没资格做代码审核 |
89 codeant 2022-04-01 08:38:01 +08:00 via iPhone @w741069229 提这种要求的人也配叫大佬 |
90 a href="/member/Breadykid" class="dark">Breadykid 2022-04-01 10:25:59 +08:00 @eb0c6551 你看的哪一版? |
91 w741069229 OP @anzu 非常同意,但是这样做的结果就是,要么要写一个 predicate,把所有的判断逻辑放进去,这种会增加一定的理解度,但是我认为会有一定的效率提升;要么就要不停的.flilter ,这种得对原生的 api 有一定的了解,我认为好处就是代码比较清晰明了吧。那么这就引申了一个问题,哪种写法更好? |
92 w741069229 OP @HanMeiM 理解难度吧,别人拿到代码不能直观的看出来,就比如 optionalofNullbale 这个算子 |
93 TWorldIsNButThis 2022-04-06 23:20:43 +08:00 @w741069229 stream 的 map 跟 filter 都是无状态操作,所以串 n 个 filter 它也是遍历一遍 |
94 w741069229 OP 感谢各位大佬的回复,我们就基于这个问题,站在`code review`的角度,和`debug`的角度,看下下面这段, 1. @TWorldIsNButThis 大佬说,`stream`的`filter`算子都是无状态的,这一点我同意,本质如下面这段代码,其实只有`map`和`flatmap`会引入时间的复杂度 2. 站在`review`的角度,如果我们要兼容向下的同学,那么这段代码是否存在复杂性的难度? 3. 站在`debug`的角度,我们是否引入了新的**断点**(就是`stream`是无状态的,导致断点其实有时候不太好懂)问题呢?譬如,`idea`可以使用`debug`中的计算器模式进行 4. 站在代码整个的观感角度,下面这段代码是否可以理解不具备代码简洁特性以及代码的整体都美感上 5. 站在代码的复用性上,我认为`steam`的代码其实是对业务有更高的要求,因为我觉得`stream`的复用性其实蛮低的,如果要改的话,就会牵一发而动全身. 6. 站在异常的处理上,我认为`stream`其实是在更严谨的要求一个编程人员对一段结果中产生异常的一个预判,我认为更能锻炼编码人员的功底吧 ```java Optional.ofNullable(search) .map(SearchResponse::getHits) .ifPresent(hits -> StreamSupport .stream(hits.spliterator(), false) .filter(Objects::nonNull) .filter(SearchHit::hasSource) .filter(this::filter) .......会是 filter .map(SearchHit::getSourceAsMap) .filter(Objects::nonNull) .map(Map::entrySet) .flatMap(Collection::stream) .filter(Objects::nonNull) .map(this::map) .forEach(.....) ); ``` 以上是小弟对`stream`一点见解,希望大家能对我的看法进行批判和讨论吧 |
95 yoloMiss 2022-04-09 21:53:55 +08:00 这种情况建议抓紧润啊。 |