使用`java-stream`

时间:2017-12-06 16:12:17

标签: java java-stream

我想知道是否有一种临时存储/携带java-stream内的值的方式?

List<Department> departments = (ArrayList<Department>) departmentRepository.findAll();

departments.parallelStream()
        .filter(e -> e.getUnderstuffCount(date) > 0)
        .forEach(e -> {
            holidaysPlaningProblemManager.addProblem(e, date, e.getUnderstuffCount(date));
        });

多次调用e.getUnderstuffCount(date)接缝&#34;脏&#34;我想知道是否有办法通过一次通话的结果来避免它?



修改

请将此视为java-stream问题。有很多方法可以解决这个问题,例如@Transient Department中的@Entity字段可以存储值,而简单的getter可以return

但我很感兴趣,如果可以使用java-stream

完成此操作

2 个答案:

答案 0 :(得分:3)

正如我在评论中提到的,对于这样的问题,有一个流行的建议是将流元素映射到包含元素本身的对和您需要的中间值。首先,让我们找一个更简单的例子(也为我编译):

Stream.of("Hello", "World", "!")
      .filter(s -> s.length() > 1)
      .forEach(s -> System.out.println(s + ": " + s.length()));
// Hello: 5
// World: 5

如果我们现在采用简单数组或AbstractMap.SimpleEntry作为配对对象,我们可以添加一个映射步骤:

Stream.of("Hello", "World", "!")
      .map(s -> new Object[] {s, s.length()})
      .filter(a -> ((int) a[1]) > 1)
      .forEach(a -> System.out.println(a[0] + ": " + a[1]));

Stream.of("Hello", "World", "!")
      .map(s -> new AbstractMap.SimpleEntry<>(s, s.length()))
      .filter(e -> e.getValue() > 1)
      .forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));

数组变体的写入时间要短一些,但不是类型安全的。我会使用第二个可能性。或者您可以使用简短的方法名称和一个漂亮的工厂方法(Pair<L, R>)向项目添加实际的Pair.of(s, s.length())类。无论您选择哪种方式,它都比收集到收藏家(stream.collect(toMap()).entrySet().stream().filter(e).forEach(e))的地图更好,因为您没有将整个地图具体化为内存。

我提到的另一种可能性是将支票拉入forEach。鉴于你的(可能是简化的)例子,我会说这是最容易阅读的方式,但当然不是“stream-y”或“lambda-y”。

Stream.of("Hello", "World", "!").forEach(s -> {
    int length = s.length();
    if (length > 1)
    {
        System.out.println(s + ": " + length);
    }
});

在这个简单的例子中,您甚至不需要拥有流。只需致电Collection.forEach()

最后你必须看看在这里使用流是否值得。你使用并行流,但它确实加快了速度(例如你的holidaysPlaningProblemManager线程安全还是只是再次同步所有线程,使并行流无意义?如果没有,您可以重构为正常的for循环或Collection.forEach

答案 1 :(得分:1)

如果您想过滤部门,我认为您应该先从数据库中检索部门,然后让问题管理员接受列表。

List<Department> departments = departmentRepository.someMethod(date);
holidaysPlaningProblemManager.addProblems(date, departments);

除非您仍然与集合中的元素有关。