lambda 表达式大家在工作中用的多么,小白看了好多遍也理解不住

2019-11-29 15:58:30 +08:00
 wuwudeqi
12240 次点击
所在节点    Java
91 条回复
winterbells
2019-11-29 21:04:03 +08:00
经常用,很简单啊
alt + enter [:doge]
hantsy
2019-11-29 21:06:57 +08:00
val filter = {age: Int -> age >30}
AlisaDestiny
2019-11-29 21:10:44 +08:00
用,可以简化代码,并且使代码更直观。
hantsy
2019-11-29 21:15:58 +08:00
作为 Java 8 特性,lambda 已经出来 5,6 年了吧。你还能以**太新了**为理由拒绝吗?

第一次用的时候,一个项目要上 Java 8 (刚出来不久),要用 Spring Integration 和 Java 8 特性,那时 Spring Integration 4 有一个专门 Java 8 module(现在集成到 core 了), Spring 官方 Blog 有一个介绍 Spring Integration Java 8 DSL。

https://spring.io/blog/2014/11/25/spring-integration-java-dsl-line-by-line-tutorial

能够理解这个 Orders Bean 就差不多了。

@Bean
public IntegrationFlow orders() { // 12
return f -> f // 13
.split(Order.class, Order::getItems) // 14
.channel(c -> c.executor(Executors.newCachedThreadPool()))// 15
.<OrderItem, Boolean>route(OrderItem::isIced, mapping -> mapping // 16
.subFlowMapping("true", sf -> sf // 17
.channel(c -> c.queue(10)) // 18
.publishSubscribeChannel(c -> c // 19
.subscribe(s -> // 20
s.handle(m -> sleepUninterruptibly(1, TimeUnit.SECONDS)))// 21
.subscribe(sub -> sub // 22
.<OrderItem, String>transform(item ->
Thread.currentThread().getName()
+ " prepared cold drink #"
+ this.coldDrinkCounter.incrementAndGet()
+ " for order #" + item.getOrderNumber()
+ ": " + item) // 23
.handle(m -> System.out.println(m.getPayload())))))// 24
.subFlowMapping("false", sf -> sf // 25
.channel(c -> c.queue(10))
.publishSubscribeChannel(c -> c
.subscribe(s ->
s.handle(m -> sleepUninterruptibly(5, TimeUnit.SECONDS)))// 26
.subscribe(sub -> sub
.<OrderItem, String>transform(item ->
Thread.currentThread().getName()
+ " prepared hot drink #"
+ this.hotDrinkCounter.incrementAndGet()
+ " for order #" + item.getOrderNumber()
+ ": " + item)
.handle(m -> System.out.println(m.getPayload()))))))
.<OrderItem, Drink>transform(orderItem ->
new Drink(orderItem.getOrderNumber(),
orderItem.getDrinkType(),
orderItem.isIced(),
orderItem.getShots())) // 27
.aggregate(aggregator -> aggregator // 28
.outputProcessor(group -> // 29
new Delivery(group.getMessages()
.stream()
.map(message -> (Drink) message.getPayload())
.collect(Collectors.toList()))) // 30
.correlationStrategy(m ->
((Drink) m.getPayload()).getOrderNumber()), null) // 31
.handle(CharacterStreamWritingMessageHandler.stdout()); // 32
}

}
hannhuan
2019-11-29 21:20:38 +08:00
@l93814690
// 原来的代码
for (Sample s : samples){
if (sample.getValue() == aValue){
System.out.println(sample);
}
}

// 然后...
samples.stream()
.filter(sample -> sample.getValue() == aValue)
.forEach(System.out::println);

// 或者...
List<Sample> sortSampleByIndex = samples.stream()
.sorted((s1, s2) -> s1.getIndex()- s2.getIndex())
.collect(Collectors.toList());


简化下之前写的大概是这样吧_(:з」∠)_ 不过我超菜,这个也不一定是正确的用法
laminux29
2019-11-29 21:32:56 +08:00
在 C#中,给学生数组,按照总分、语文分数、其他分数等字段进行多字段排序,自己写的话会有一堆 for 循环以及后处理,而 lambda 只需要一行:

学生数组.OrderBy(x => x.总分).ThenBy(x => x.语文分数).ThenBy....

这玩意本质是函数语言,和 SQL 的思路很像。如果你熟悉 SQL,你就会发现这玩意在处理数据时,非常好用。
KentY
2019-11-29 21:34:26 +08:00
@hannhuan 想一下, 如果你在 for 里的调用, 比如那个 out.print(), 如果是另一个会 throw checked exception method, 要怎么处理?
hantsy
2019-11-29 21:39:56 +08:00
@hannhuan
.sorted((s1, s2) -> s1.getIndex()- s2.getIndex()) 可以用 Comparator.comparing, 如

.sorted(comparing(Sample::getIndex)

抽取,可以在 Sample 定义

static Comparator<Sample> COMPARAED_BY_INDEX=comparing(Sample::getIndex );

应用
.sorted(COMPARAED_BY_INDEX)
aliveyang
2019-11-29 21:41:30 +08:00
用 idea 自动补全, 然后就习惯写了
sagaxu
2019-11-29 21:43:00 +08:00
最近一年基本没写过 for 循环,你说用的多不多
hantsy
2019-11-29 21:43:13 +08:00
@KentY 所有的流式( Stream,Future,ReactiveStreams )处理都有异常路径的,让你处理异常。
rimutuyuan
2019-11-29 21:43:21 +08:00
完全不用!因为 go 根本没有
KentY
2019-11-29 21:50:11 +08:00
@hantsy "异常路径" 是什么? google 没找到对应英语.
缺省的是无法将 exception forward 到外面的. 需要自己 wrap 或者扩展 Consumer, Function 等.
希望我们俩说的是一件事. :D
hantsy
2019-11-29 21:56:19 +08:00
hannhuan
2019-11-29 21:56:43 +08:00
@hantsy 学到了,感谢~下次试试。
hantsy
2019-11-29 22:00:55 +08:00
@KentY 留了一个 Exception 路径的入口,怎么优雅处理倒是一个问题,Stackoverflow 很多这种问题。
ztcaoll222
2019-11-29 22:01:23 +08:00
记住: 2014 年出的 java 1.8
KentY
2019-11-29 22:05:13 +08:00
@hantsy 你的例子是 CompletionStage interface 定义的方法而已. 跟我说的不是一个事. 或许我没表述清, ok:
class Whatever{...
public void foo throw WhateverException(){...}
}

in some method:
...someMethod(Collection<Whatever> collection) throw WhateverException{....
collection.stream().foreach(Whatever::foo); --> here it won't work, the checked exception won't be forwarded to the caller method.
}

我是这个意思
KentY
2019-11-29 22:06:33 +08:00
请忽视 syntax mistakes. like throws, (), etc.
KentY
2019-11-29 22:12:23 +08:00
@hantsy
"留了一个 Exception 路径的入口" 我不理解这句话. 什么是"路径"? 什么又是"入口"?

另, 我在 SO 也相对活跃. 我不是不知道怎么解决来这求解决方案的. 只是, 看到人们说到 lambda 都是这些 foreach 啊, filter 啊, stream 啊, 没人提到在传统的 for -> stream()这个变换中, 不是所有都可以简单的改写的, 有些情况需要做特殊处理. 仅此而已.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/624350

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX