这就是Test
的样子:
@Test
public void testFunctional()
{
final Member member = new Member("email", "memberExternalId", "clientId", "clientSecret");
final Category foodCategory = new Category("Groceries", "Food");
final Category utilityCategory = new Category("Internet", "utility");
final List<Transaction> transactions = new ArrayList<>();
{
transactions.add(new Transaction("food1", new BigDecimal("10.00"), true, LocalDateTime.now(), member, foodCategory));
transactions.add(new Transaction("food2", new BigDecimal("20.00"), true, LocalDateTime.now(), member, foodCategory));
}
{
transactions.add(new Transaction("utility1", new BigDecimal("100.00"), true, LocalDateTime.now(), member, utilityCategory));
transactions.add(new Transaction("utility2", new BigDecimal("200.00"), true, LocalDateTime.now(), member, utilityCategory));
}
final Map<String, List<BigDecimal>> groupByCategory = transactions.stream().collect(Collectors.groupingBy(Category::getGroupName));
}
Category
看起来像这样:
public class Category
{
@Id
private String id;
@Column(nullable = false)
private String name;
@Column(name = "group_name", nullable = false)
private String groupName;
@Column(name = "created_at")
private LocalDateTime createdAt;
...
}
当我这样做时:
final Map<String, List<BigDecimal>> groupByCategory = transactions.stream().collect(Collectors.groupingBy(Category::getGroupName));
IntelliJ抱怨Cyclic Inference
我是第一次尝试这个Java 8
功能而不确定是什么导致了这一点。
答案 0 :(得分:5)
您的输入是List<Transaction>
,您可以从中创建Stream<Transaction>
。
当您将此Stream
收集到Map
时,您应该提供一个收集器,将每个Transaction
映射到应在其下分组的密钥。
您希望Transaction
对GroupName
Category
的{{1}}进行分组。由于Transaction
不是Category::getGroupName
的方法,因此您无法在此处使用方法参考。相反,您可以使用lambda表达式:
Transaction
另请注意,此分组会生成final Map<String, List<Transaction>> groupByCategory =
transactions.stream()
.collect(Collectors.groupingBy(t -> t.getCategory().getGroupName()));
,而非Map<String, List<Transaction>>
。
答案 1 :(得分:3)
如果您想获得按类别分组的金额,那么您可以将groupingBy
收藏家与mapping
收藏家合并:
Map<String, List<BigDecimal>> amountsByCategory = transactions.stream()
.collect(Collectors.groupingBy(t -> t.getCategory().getGroupName(),
Collectors.mapping(Transaction::getAmount,
Collectors.toList())));
还可以使用Collectors.reducing
获得每组的总金额:
Map<String, BigDecimal> totalAmountByCategory = transactions.stream()
.collect(Collectors.groupingBy(t -> t.getCategory().getGroupName(),
Collectors.mapping(Transaction::getAmount,
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));