sik*_*iki 478 java java-8 java-stream
我刚刚开始使用Java 8 lambdas,我正在尝试实现我在函数式语言中习惯的一些东西.
例如,大多数函数式语言都有某种类型的查找函数,这些函数对序列进行操作,或者列表返回谓词所在的第一个元素true
.我在Java 8中实现这一目标的唯一方法是:
lst.stream()
.filter(x -> x > 5)
.findFirst()
Run Code Online (Sandbox Code Playgroud)
然而这对我来说似乎效率低下,因为过滤器会扫描整个列表,至少根据我的理解(这可能是错误的).有没有更好的办法?
Ale*_* C. 677
不,过滤器不会扫描整个流.这是一个中间操作,它返回一个惰性流(实际上所有中间操作都返回一个惰性流).为了说服你,你可以简单地做以下测试:
List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
int a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.get();
System.out.println(a);
Run Code Online (Sandbox Code Playgroud)
哪个输出:
will filter 1
will filter 10
10
Run Code Online (Sandbox Code Playgroud)
您会看到实际只处理了流的两个第一个元素.
所以你可以采用你的方法,这是非常好的.
小智 102
然而,这似乎对我来说效率低,因为过滤器将扫描整个列表
不,它不会 - 一旦找到满足谓词的第一个元素,它就会"中断".你可以在流包javadoc中阅读更多关于懒惰的内容,特别是(强调我的):
许多流操作(例如过滤,映射或重复删除)可以懒惰地实现,从而暴露出优化的机会.例如,"查找具有三个连续元音的第一个字符串"不需要检查所有输入字符串.流操作分为中间(流生成)操作和终端(生成价值或副作用)操作.中间操作总是很懒惰.
Cod*_*dow 30
return dataSource.getParkingLots().stream().filter(parkingLot -> Objects.equals(parkingLot.getId(), id)).findFirst().orElse(null);
Run Code Online (Sandbox Code Playgroud)
我不得不从对象列表中过滤出一个对象.所以我用这个,希望它有所帮助.
GKi*_*lin 16
@AjaxLeung 已经回答了,但在评论中很难找到。
仅供检查
lst.stream()
.filter(x -> x > 5)
.findFirst()
.isPresent()
Run Code Online (Sandbox Code Playgroud)
被简化为
lst.stream()
.anyMatch(x -> x > 5)
Run Code Online (Sandbox Code Playgroud)
Ife*_*yan 13
除了Alexis C的回答之外,如果您正在使用数组列表,您不确定您要搜索的元素是否存在,请使用此列表.
Integer a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.orElse(null);
Run Code Online (Sandbox Code Playgroud)
然后,你可以简单地检查是否一个是null
.
归档时间: |
|
查看次数: |
356895 次 |
最近记录: |