这是Java 8 Stream的一个很好的用例:
final Car carWithInterior = Stream.of(carWithEngine)
.map(car -> installSeats.execute(car))
.map(car -> installDashBoard.execute(car))
.map(car -> installSunRoof.execute(car))
.collect(car);
carWithEngine
是Car
。请注意,有时即使将汽车(带有仪表板)传递给installSunroof,也不会进行任何操作,因为车顶没有孔。我应该总是在安装/映射过程结束时买车。
需要安装顺序(这就是我想到进行流式传输的原因),下一次安装有时可能需要通过汽车实例的参数来执行其操作。
这是Java 8 Stream的一个很好的用例吗?
不好意思,我最后的收藏不对。我应该如何在此安装/装配线的结尾处获得汽车? findFirst().get()
可以正常工作,但是我认为这很糟糕,因为即使安装对carWitEngine
没有任何作用,并且我不会流式传输多个元素,我也应该始终得到一辆汽车。1 p>
我不确定汽车的组装方式,但是为了进行类比,您需要在添加内饰之前先把引擎放在第一位。
答案 0 :(得分:4)
由于您要在单个对象上执行操作。 Java 8 Optional是合适的。
构建器模式(Phil C的评论)绝对值得一游,如果这些映射操作中的每一个都只是对Car
对象进行水化。
Car
通过.map()
操作掉入流中,则您正在冒险进入危险区域(副作用)。在处理Streams
时,强烈建议按照预期的方式使用这些操作。如果您打算从流.filter()
编辑为OP的编辑内容
围绕“序列”及其翻译方式存在一些基本的困惑
可选
car => map(execute) => map(execute) => transformedcar
流
[car1, car2, car3]
=> map(execute) => map(execute) => updatedcar1 | => findFirst (Optional<Car>)
=> map(execute) => map(execute) => updatedcar2 |
=> map(execute) => map(execute) => updatedcar3 |
collect
[updatedcar1, updatedcar2, updatedcar3]
findFirst
方法将返回Optional
。
collect
方法将提供一种终端操作,可让您汇总/减少/分组这些结果。
这些map
操作对传递的元素进行“顺序”转换。但是Stream
是合适的情况,在这种情况下,您必须处理许多或“一系列”汽车。
重新访问#2
您可以选择使用orElse(car)
的Optional提供替代项。
但这是您必须对正在执行的副作用产生争议的地方。
如果execute方法正在操作并返回传递给它的同一对象,则将产生意想不到的后果。例如,我将使用Optionals,但同样适用于Streams。
private final Car car Optional.of(carWithEngine)
.map(installSunroof.execute) // <-- updatedCarWithSunroof
.map(installDashboard.execute) // <-- updatedCarWithSunroofAndDashboard
.orElse(carWithEngine) // <-- updatedCarWithSunroofAndDashboard
答案 1 :(得分:3)
回答您的问题:
- 这是Java 8 Stream的好用例吗?
否,Java Stream Api应该用于集合。在here中,流的定义为:
来源中支持聚合的一系列元素 操作
您只有一个不是一系列元素的对象,因此使用Stream会使您的代码更难以理解。要回答问题2,您可以
findFirst().orElse(carWithEngine)
您的示例的另一种选择是简单地嵌套函数调用,如下所示:
installSunRoof.execute(installDashBoard.execute(installSeats.execute(car)))
另一种替代方法是在汽车上定义一个方法安装,该方法将接收BaseIinstaller并返回修改后的汽车,如下所示:
final Car carWithInterior = car.install(installSeats)
.install(installDashBoard)
.install(installSunRoof);