将多个字段连接成一个字符串,然后使用 collection 对其进行分组以查找每组的总和
Concat multiple fields into one string, then group by it using collection to find sum of each group
假设我有以下字段:
> String name1
> String name2
> String name3
> BigDecimal amount
我想用一个 String
将它们分组,这是 name1、name2 和 name3 的串联。
例如:
name1 = hi
name2 = am
name3 = sarah
String newString = hiamsarah
然后,在我设法通过链式 String
对 objects 进行分组后,我想获得每个组的 amount
字段的总和。
这可能吗?
我已经尝试了所有可能的方法,但就是无法通过。另外,我是 collections.
的新手
假设您的实例包含在 List
中并且在您的 class 中有一种方法可以 return 链接的名称,您可以使用集合流和分组依据您使用终端操作的实例 collect(Collectors.toMap())
.
链接的值可以用作键,BigDecimal
值作为键对应的值,最后可以通过对BigDecimal
值求和来处理冲突情况。
由于您没有提供您所指的 class 的代码,我声明了一个名为 MyClass
的 class 包含 3 个 String
字段和BigDecimal
。这是代码片段:
public class Main {
public static void main(String[] args) {
List<MyClass> list = new ArrayList<>(List.of(
new MyClass("I", "am", "Sarah", BigDecimal.valueOf(5.33)),
new MyClass("I", "am", "Frank", BigDecimal.valueOf(2.75)),
new MyClass("I", "am", "Sarah", BigDecimal.valueOf(3.56)),
new MyClass("I", "am", "Frank", BigDecimal.valueOf(7.12)),
new MyClass("I", "am", "John", BigDecimal.valueOf(1.11))
));
Map<String, BigDecimal> mapRes = list.stream()
.collect(Collectors.toMap(mc -> mc.chainNames(), mc -> mc.getAmount(), (decimal1, decimal2) -> decimal1.add(decimal2)));
System.out.println(mapRes);
}
}
测试class实施(MyClass
):
class MyClass {
private String name1;
private String name2;
private String name3;
private BigDecimal amount;
public MyClass(String name1, String name2, String name3, BigDecimal amount) {
this.name1 = name1;
this.name2 = name2;
this.name3 = name3;
this.amount = amount;
}
/* ... your implementation ...*/
public BigDecimal getAmount() {
return amount;
}
public String chainNames() {
StringBuilder strBld = new StringBuilder(name1);
strBld.append(name2);
strBld.append(name3);
return strBld.toString();
}
}
这里还有一个link测试代码:
- 连接多个字符串,有方法
String::join
,第一个参数是分隔符,可以是空字符串String.join("", name1, name2, name3)
- 要按列表中的某些值分组并汇总某个值,Stream API 应与
Collectors.groupingBy
+ Collectors.reducing
一起使用
假设给定的 class 实现为自 Java 14 以来提供的 record,则提供以下实现:
public static void main(String[] args) {
record MyObj(String name1, String name2, String name3, BigDecimal amount) {
public String fullName() {
return String.join("", name1, name2, name3);
}
};
List<MyObj> list = List.of(
new MyObj("I", "am", "Sarah", BigDecimal.valueOf(5.33)),
new MyObj("I", "am", "Frank", BigDecimal.valueOf(2.75)),
new MyObj("I", "am", "Sarah", BigDecimal.valueOf(3.56)),
new MyObj("I", "am", "Frank", BigDecimal.valueOf(7.12)),
new MyObj("I", "am", "John", BigDecimal.valueOf(1.11))
);
Map<String, BigDecimal> mapRes = list.stream()
.collect(Collectors.groupingBy(
MyObj::fullName,
Collectors.reducing(BigDecimal.ZERO, MyObj::amount, BigDecimal::add)
));
System.out.println(mapRes);
}
输出:
{IamJohn=1.11, IamSarah=8.89, IamFrank=9.87}
假设我有以下字段:
> String name1
> String name2
> String name3
> BigDecimal amount
我想用一个 String
将它们分组,这是 name1、name2 和 name3 的串联。
例如:
name1 = hi
name2 = am
name3 = sarah
String newString = hiamsarah
然后,在我设法通过链式 String
对 objects 进行分组后,我想获得每个组的 amount
字段的总和。
这可能吗?
我已经尝试了所有可能的方法,但就是无法通过。另外,我是 collections.
的新手假设您的实例包含在 List
中并且在您的 class 中有一种方法可以 return 链接的名称,您可以使用集合流和分组依据您使用终端操作的实例 collect(Collectors.toMap())
.
链接的值可以用作键,BigDecimal
值作为键对应的值,最后可以通过对BigDecimal
值求和来处理冲突情况。
由于您没有提供您所指的 class 的代码,我声明了一个名为 MyClass
的 class 包含 3 个 String
字段和BigDecimal
。这是代码片段:
public class Main {
public static void main(String[] args) {
List<MyClass> list = new ArrayList<>(List.of(
new MyClass("I", "am", "Sarah", BigDecimal.valueOf(5.33)),
new MyClass("I", "am", "Frank", BigDecimal.valueOf(2.75)),
new MyClass("I", "am", "Sarah", BigDecimal.valueOf(3.56)),
new MyClass("I", "am", "Frank", BigDecimal.valueOf(7.12)),
new MyClass("I", "am", "John", BigDecimal.valueOf(1.11))
));
Map<String, BigDecimal> mapRes = list.stream()
.collect(Collectors.toMap(mc -> mc.chainNames(), mc -> mc.getAmount(), (decimal1, decimal2) -> decimal1.add(decimal2)));
System.out.println(mapRes);
}
}
测试class实施(MyClass
):
class MyClass {
private String name1;
private String name2;
private String name3;
private BigDecimal amount;
public MyClass(String name1, String name2, String name3, BigDecimal amount) {
this.name1 = name1;
this.name2 = name2;
this.name3 = name3;
this.amount = amount;
}
/* ... your implementation ...*/
public BigDecimal getAmount() {
return amount;
}
public String chainNames() {
StringBuilder strBld = new StringBuilder(name1);
strBld.append(name2);
strBld.append(name3);
return strBld.toString();
}
}
这里还有一个link测试代码:
- 连接多个字符串,有方法
String::join
,第一个参数是分隔符,可以是空字符串String.join("", name1, name2, name3)
- 要按列表中的某些值分组并汇总某个值,Stream API 应与
Collectors.groupingBy
+Collectors.reducing
一起使用
假设给定的 class 实现为自 Java 14 以来提供的 record,则提供以下实现:
public static void main(String[] args) {
record MyObj(String name1, String name2, String name3, BigDecimal amount) {
public String fullName() {
return String.join("", name1, name2, name3);
}
};
List<MyObj> list = List.of(
new MyObj("I", "am", "Sarah", BigDecimal.valueOf(5.33)),
new MyObj("I", "am", "Frank", BigDecimal.valueOf(2.75)),
new MyObj("I", "am", "Sarah", BigDecimal.valueOf(3.56)),
new MyObj("I", "am", "Frank", BigDecimal.valueOf(7.12)),
new MyObj("I", "am", "John", BigDecimal.valueOf(1.11))
);
Map<String, BigDecimal> mapRes = list.stream()
.collect(Collectors.groupingBy(
MyObj::fullName,
Collectors.reducing(BigDecimal.ZERO, MyObj::amount, BigDecimal::add)
));
System.out.println(mapRes);
}
输出:
{IamJohn=1.11, IamSarah=8.89, IamFrank=9.87}