object 的 Sum 属性与 Stream API
Sum attribute of object with Stream API
我目前有以下情况:
我有一个 Report
object 可以包含多个 Query
object。 Query
object 具有以下属性:Optional<Filter> comparisonFilter
、Optional<String> filterChoice
和 int queryOutput
。
并非每个查询都有比较过滤器,所以我首先检查一下。然后,我确保获得针对特定过滤器的查询(这不是这里的问题,因此我不会详细讨论)。每个过滤器都有一些选择,其中选择的数量是可变的。
这里是输入的例子(这些Query
object都有相同的comparisonFilter):
Query 1 -- Choice: 'First' -- Output: 10
Query 1 -- Choice: 'First' -- Output: 5
Query 1 -- Choice: 'Second' -- Output: 25
Query 1 -- Choice: 'Third' -- Output: 10
现在,我想对每个唯一选择的查询输出求和。我目前有这个代码:
report
.getQueries()
.stream()
.filter(q -> q.getComparisonFilter().isPresent())
.filter(q -> q.getComparisonFilter().get().equals(view.getFilter().get()))
.forEach(query -> {
//Sum the query outputs per choice
});
我可以通过创建一个 Map<String, Integer>
来做到这一点,其中键是选择,值是查询输入。但是然后我需要再次遍历 Map
以使用某些东西的值(这在这里并不重要)。
输出应该是这样的:
Choice: 'First' -- Summed Output: 15
Choice: 'Second' -- Summed Output: 25
Choice: 'Third' -- Summed Output: 10
但我想直接在直播中的 forEach
中使用这个 'Summed Output',但如果这不再可行或不实用,我可以接受。
我想以 'Java 8' 的方式执行此操作,但我似乎无法找到方法。
所以我的问题是:是否可以使用新的 Stream API 缩短此时间?
注意:如果有人对我如何使这个问题更笼统(可能是更好的标题和一些概括)有一些想法,请告诉我!
如果我理解得很好,你确实在寻找一个 groupingBy
然后你必须通过对它们的 int 属性.
求和来对这些值进行分组
groupingBy
会给你一个 Map<String, List<Query>>
但随后下游收集器(在这种情况下为 Collectors.summingInt
)将对 [=17 的所有 int
值求和=] 列表中的实例,导致 Map<String, Integer>
.
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;
...
Map<String, Integer> map =
report.getQueries()
.stream()
.filter(q -> q.getComparisonFilter().isPresent())
.filter(q -> q.getComparisonFilter().get().equals(view.getFilter().get()))
.collect(groupingBy(q -> q.filterChoice.get(), summingInt(q -> q.queryOutput)));
请注意,您应该检查 filterChoice
可选是否不为空(也许添加另一个 filter
子句?)。你可以看到这个小gist一个基本和简化的演示来说明原理。
此外,Optional
class 提供了 equals
的合理实现,因此过滤器子句可能如下所示:
.filter(q -> q.getComparisonFilter().equals(view.getFilter()))
我目前有以下情况:
我有一个 Report
object 可以包含多个 Query
object。 Query
object 具有以下属性:Optional<Filter> comparisonFilter
、Optional<String> filterChoice
和 int queryOutput
。
并非每个查询都有比较过滤器,所以我首先检查一下。然后,我确保获得针对特定过滤器的查询(这不是这里的问题,因此我不会详细讨论)。每个过滤器都有一些选择,其中选择的数量是可变的。
这里是输入的例子(这些Query
object都有相同的comparisonFilter):
Query 1 -- Choice: 'First' -- Output: 10
Query 1 -- Choice: 'First' -- Output: 5
Query 1 -- Choice: 'Second' -- Output: 25
Query 1 -- Choice: 'Third' -- Output: 10
现在,我想对每个唯一选择的查询输出求和。我目前有这个代码:
report
.getQueries()
.stream()
.filter(q -> q.getComparisonFilter().isPresent())
.filter(q -> q.getComparisonFilter().get().equals(view.getFilter().get()))
.forEach(query -> {
//Sum the query outputs per choice
});
我可以通过创建一个 Map<String, Integer>
来做到这一点,其中键是选择,值是查询输入。但是然后我需要再次遍历 Map
以使用某些东西的值(这在这里并不重要)。
输出应该是这样的:
Choice: 'First' -- Summed Output: 15
Choice: 'Second' -- Summed Output: 25
Choice: 'Third' -- Summed Output: 10
但我想直接在直播中的 forEach
中使用这个 'Summed Output',但如果这不再可行或不实用,我可以接受。
我想以 'Java 8' 的方式执行此操作,但我似乎无法找到方法。
所以我的问题是:是否可以使用新的 Stream API 缩短此时间?
注意:如果有人对我如何使这个问题更笼统(可能是更好的标题和一些概括)有一些想法,请告诉我!
如果我理解得很好,你确实在寻找一个 groupingBy
然后你必须通过对它们的 int 属性.
groupingBy
会给你一个 Map<String, List<Query>>
但随后下游收集器(在这种情况下为 Collectors.summingInt
)将对 [=17 的所有 int
值求和=] 列表中的实例,导致 Map<String, Integer>
.
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;
...
Map<String, Integer> map =
report.getQueries()
.stream()
.filter(q -> q.getComparisonFilter().isPresent())
.filter(q -> q.getComparisonFilter().get().equals(view.getFilter().get()))
.collect(groupingBy(q -> q.filterChoice.get(), summingInt(q -> q.queryOutput)));
请注意,您应该检查 filterChoice
可选是否不为空(也许添加另一个 filter
子句?)。你可以看到这个小gist一个基本和简化的演示来说明原理。
此外,Optional
class 提供了 equals
的合理实现,因此过滤器子句可能如下所示:
.filter(q -> q.getComparisonFilter().equals(view.getFilter()))