使用Stream

时间:2018-08-17 02:22:45

标签: java design-patterns

这是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);

carWithEngineCar。请注意,有时即使将汽车(带有仪表板)传递给installSunroof,也不会进行任何操作,因为车顶没有孔。我应该总是在安装/映射过程结束时买车

需要安装顺序(这就是我想到进行流式传输的原因),下一次安装有时可能需要通过汽车实例的参数来执行其操作。

  1. 这是Java 8 Stream的一个很好的用例吗?

  2. 不好意思,我最后的收藏不对。我应该如何在此安装/装配线的结尾处获得汽车? findFirst().get()可以正常工作,但是我认为这很糟糕,因为即使安装对carWitEngine没有任何作用,并且我不会流式传输多个元素,我也应该始终得到一辆汽车。

我不确定汽车的组装方式,但是为了进行类比,您需要在添加内饰之前先把引擎放在第一位。

2 个答案:

答案 0 :(得分:4)

由于您要在单个对象上执行操作。 Java 8 Optional是合适的。

构建器模式(Phil C的评论)绝对值得一游,如果这些映射操作中的每一个都只是对Car对象进行水化。

  1. 为单个对象打开流不是流的好用例。
  2. 如果Car通过.map()操作掉入流中,则您正在冒险进入危险区域(副作用)。在处理Streams时,强烈建议按照预期的方式使用这些操作。如果您打算从流.filter()
  3. 中删除元素

编辑为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方法将返回Optionalcollect方法将提供一种终端操作,可让您汇总/减少/分组这些结果。

这些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)

回答您的问题:

  
      
  1. 这是Java 8 Stream的好用例吗?
  2.   

否,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);