我想知道是否有一种在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)接缝的多个调用是“脏”的,我想知道是否有办法通过传递单个调用的结果来避免它?
编辑:
请考虑这是一个java-stream问题。解决这个问题的方法有很多,例如,@Transient字段可以存储Department @Entity中的值,而简单的getter可以对其进行return处理。
但是我感兴趣的是是否可以用java-stream来完成
发布于 2017-12-06 17:40:07
正如我在评论中提到的,有一个流行的建议是这样的问题:将流元素映射到包含元素本身以及所需的中间值的对。首先,让我们找一个更简单的例子(也为我编译):
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.of(s, s.length()))向项目添加一个实际的Pair.of(s, s.length())类。无论您选择哪种方式,它都比收集到带有收集器(stream.collect(toMap()).entrySet().stream().filter(e).forEach(e))的映射要好,因为没有将整个映射具体化到内存中。
我提到的另一种可能性是将支票放入forEach。鉴于您的示例(可能简化),我想说这是最容易阅读的方式,但当然不是“流-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。
发布于 2017-12-06 16:18:56
如果您想过滤部门,我认为您应该先过滤它,然后再从数据库中检索它,并让问题管理器接受一个列表。
List<Department> departments = departmentRepository.someMethod(date);
holidaysPlaningProblemManager.addProblems(date, departments);除非您仍然与集合中的元素有关。
https://stackoverflow.com/questions/47678765
复制相似问题