减去 java 8 中每个组的值
Subtract the values for each group in java 8
我有 class Data10,它有 5 个字段并有值列表,然后我想从 valuePeriod 的每个唯一 ID 组中减去值,如下例所示,最后在结果中生成具有相同 ID 的新 Data10 对象, 同年, 新名称, 相同的 valuePeriod 和减值结果.
注意:在下面的例子中,我只有 2 个名字,我想从 A-B 中减去它们,然后名字在预期结果中变成“C”。
重要说明:我想做 A-B 而不是 B-A。
class Data10 {
int id;
int year;
String name;
int valuePeriod;
BigDecimal value;
}
List<Data10> list = new ArrayList();
list.add(new Data10(1, 2020, "A", 1, new BigDecimal(5.5)));
list.add(new Data10(1, 2020, "B", 1, new BigDecimal(2.5)));
list.add(new Data10(1, 2020, "A", 2, new BigDecimal(8.5)));
list.add(new Data10(1, 2020, "B", 2, new BigDecimal(1.5)));
list.add(new Data10(1, 2020, "A", 3, new BigDecimal(6.5)));
list.add(new Data10(1, 2020, "B", 3, new BigDecimal(2.5)));
list.add(new Data10(2, 2020, "A", 1, new BigDecimal(6.5)));
list.add(new Data10(2, 2020, "B", 1, new BigDecimal(1.5)));
list.add(new Data10(2, 2020, "A", 2, new BigDecimal(9.5)));
list.add(new Data10(2, 2020, "B", 2, new BigDecimal(3.5)));
list.add(new Data10(2, 2020, "A", 3, new BigDecimal(7.5)));
list.add(new Data10(2, 2020, "B", 3, new BigDecimal(5.5)));
我尝试对数据进行分组,但如何减去相同 valuePeriod 的值然后生成新对象?请任何帮助。提前致谢!
list.stream().collect(Collectors.groupingBy(Data10::getId, Collectors.groupingBy(Data10::getValuePeriod)));
预期结果:
Data10(1, 2020, "C", 1, 3.0); (Subtract the value for same valuePeriod A-B)
Data10(1, 2020, "C", 2, 7.0);
Data10(1, 2020, "C", 3, 4.0);
Data10(2, 2020, "C", 1, 5.0);
Data10(2, 2020, "C", 2, 6.0);
Data10(2, 2020, "C", 3, 2.0);
如果我能想到更好的方法,我会post。但目前这是一个两个阶段的过程。
- 首先使用名称、id、valuePeriod 和年份作为键创建一个地图。这假定每个
A
都有一个匹配的 B
(否则它会变得更复杂)。
Map<String, Data10> map =
list.stream()
.collect(Collectors.toMap(
d -> d.getName() + d.getId()
+ d.getValuePeriod()+d.getYear(),
d -> d));
map.entrySet().forEach(System.out::println);
打印
A112020=[1, 2020, A, 1, 5.5]
A222020=[2, 2020, A, 2, 9.5]
A232020=[2, 2020, A, 3, 7.5]
A122020=[1, 2020, A, 2, 8.5]
A132020=[1, 2020, A, 3, 6.5]
B212020=[2, 2020, B, 1, 1.5]
B222020=[2, 2020, B, 2, 3.5]
B112020=[1, 2020, B, 1, 2.5]
B232020=[2, 2020, B, 3, 5.5]
A212020=[2, 2020, A, 1, 6.5]
B132020=[1, 2020, B, 3, 2.5]
B122020=[1, 2020, B, 2, 1.5]
- 现在流式传输原始列表并使用映射引用适当的键,过滤掉“B”值。
- 创建一个新的
Data10
实例,填充现有值以及 A-B
的差异
List<Data10> result = list.stream().filter(d->d.getName().equals("A"))
.map(d->new Data10(d.getId(),
d.getYear(), "C", d.getValuePeriod(),
map.get("A" + d.getId() + d.getValuePeriod()+d.getYear()).getValue()
.subtract(map.get("B" + d.getId()
+ d.getValuePeriod()+d.getYear()).getValue())))
.toList();
result.forEach(System.out::println);
打印
[1, 2020, C, 1, 3.0]
[1, 2020, C, 2, 7.0]
[1, 2020, C, 3, 4.0]
[2, 2020, C, 1, 5.0]
[2, 2020, C, 2, 6.0]
[2, 2020, C, 3, 2.0]
我假设可能有不同的年份可能具有相同的 valuePeriod
,因此有必要将其包含在密钥中以定位适当的值。您当然可以修改以满足您的具体要求。
我有 class Data10,它有 5 个字段并有值列表,然后我想从 valuePeriod 的每个唯一 ID 组中减去值,如下例所示,最后在结果中生成具有相同 ID 的新 Data10 对象, 同年, 新名称, 相同的 valuePeriod 和减值结果.
注意:在下面的例子中,我只有 2 个名字,我想从 A-B 中减去它们,然后名字在预期结果中变成“C”。
重要说明:我想做 A-B 而不是 B-A。
class Data10 {
int id;
int year;
String name;
int valuePeriod;
BigDecimal value;
}
List<Data10> list = new ArrayList();
list.add(new Data10(1, 2020, "A", 1, new BigDecimal(5.5)));
list.add(new Data10(1, 2020, "B", 1, new BigDecimal(2.5)));
list.add(new Data10(1, 2020, "A", 2, new BigDecimal(8.5)));
list.add(new Data10(1, 2020, "B", 2, new BigDecimal(1.5)));
list.add(new Data10(1, 2020, "A", 3, new BigDecimal(6.5)));
list.add(new Data10(1, 2020, "B", 3, new BigDecimal(2.5)));
list.add(new Data10(2, 2020, "A", 1, new BigDecimal(6.5)));
list.add(new Data10(2, 2020, "B", 1, new BigDecimal(1.5)));
list.add(new Data10(2, 2020, "A", 2, new BigDecimal(9.5)));
list.add(new Data10(2, 2020, "B", 2, new BigDecimal(3.5)));
list.add(new Data10(2, 2020, "A", 3, new BigDecimal(7.5)));
list.add(new Data10(2, 2020, "B", 3, new BigDecimal(5.5)));
我尝试对数据进行分组,但如何减去相同 valuePeriod 的值然后生成新对象?请任何帮助。提前致谢!
list.stream().collect(Collectors.groupingBy(Data10::getId, Collectors.groupingBy(Data10::getValuePeriod)));
预期结果:
Data10(1, 2020, "C", 1, 3.0); (Subtract the value for same valuePeriod A-B)
Data10(1, 2020, "C", 2, 7.0);
Data10(1, 2020, "C", 3, 4.0);
Data10(2, 2020, "C", 1, 5.0);
Data10(2, 2020, "C", 2, 6.0);
Data10(2, 2020, "C", 3, 2.0);
如果我能想到更好的方法,我会post。但目前这是一个两个阶段的过程。
- 首先使用名称、id、valuePeriod 和年份作为键创建一个地图。这假定每个
A
都有一个匹配的B
(否则它会变得更复杂)。
Map<String, Data10> map =
list.stream()
.collect(Collectors.toMap(
d -> d.getName() + d.getId()
+ d.getValuePeriod()+d.getYear(),
d -> d));
map.entrySet().forEach(System.out::println);
打印
A112020=[1, 2020, A, 1, 5.5]
A222020=[2, 2020, A, 2, 9.5]
A232020=[2, 2020, A, 3, 7.5]
A122020=[1, 2020, A, 2, 8.5]
A132020=[1, 2020, A, 3, 6.5]
B212020=[2, 2020, B, 1, 1.5]
B222020=[2, 2020, B, 2, 3.5]
B112020=[1, 2020, B, 1, 2.5]
B232020=[2, 2020, B, 3, 5.5]
A212020=[2, 2020, A, 1, 6.5]
B132020=[1, 2020, B, 3, 2.5]
B122020=[1, 2020, B, 2, 1.5]
- 现在流式传输原始列表并使用映射引用适当的键,过滤掉“B”值。
- 创建一个新的
Data10
实例,填充现有值以及A-B
的差异
List<Data10> result = list.stream().filter(d->d.getName().equals("A"))
.map(d->new Data10(d.getId(),
d.getYear(), "C", d.getValuePeriod(),
map.get("A" + d.getId() + d.getValuePeriod()+d.getYear()).getValue()
.subtract(map.get("B" + d.getId()
+ d.getValuePeriod()+d.getYear()).getValue())))
.toList();
result.forEach(System.out::println);
打印
[1, 2020, C, 1, 3.0]
[1, 2020, C, 2, 7.0]
[1, 2020, C, 3, 4.0]
[2, 2020, C, 1, 5.0]
[2, 2020, C, 2, 6.0]
[2, 2020, C, 3, 2.0]
我假设可能有不同的年份可能具有相同的 valuePeriod
,因此有必要将其包含在密钥中以定位适当的值。您当然可以修改以满足您的具体要求。