我完全相信我的问题很简单,但我无法使用流进行处理(如果有一种方法也可以不使用流进行处理,那么它也会有所帮助)假设我们有此用户列表
public class Users {
String firstName;
String lastName;
double accountBalance;
String type;
String extraField;
}
并假设我们的List
"Users": [{
"firstName": "Scott",
"lastName": "Salisbury",
"accountBalance": "100",
"type" : "A"
}, {
"firstName": "John",
"lastName": "Richards",
"accountBalance": "200",
"type" :"C"
}, {
"firstName": "John",
"lastName": "Richards",
"accountBalance": "200",
"type " : "C",
"ExtraField": "Apply"
}]
在此预期的结果它因为名字,姓氏和类型列表中出现了两次只是合并是常见的结果,而不会错过任何领域的
预期成果
"Users": [{
"firstName": "Scott",
"lastName": "Salisbury",
"accountBalance": "100",
"type" : "A"
}, {
"firstName": "John",
"lastName": "Richards",
"accountBalance": "400",//merged values
"type " : "C",
"ExtraField": "Apply" //value that remains in one object of the list
}]
您可以创建一个包含三个字段的键类,例如
@Data
class UserKey {
String firstName;
String lastName;
String type;
static UserKey from(User user) { /* TODO (trivial) */ }
}
分组
这些可以用来对您的用户进行分组
Map<UserKey,List<User>> grouped =
users.stream().collect(Collectors.groupingBy(UserKey::from));
这些列表中的每一个都可以通过合并
Optional<User> summed = userList.stream()
.collect(Collectors.reducing((u1, u2) -> {
u1.setAccountBalance(u1.accountBalance() + u2.accountBalance());
});
也可以直接将其作为下游收集器提供给groupingBy
:
Map<UserKey,Optional<User>> mergedMap =
users.stream().collect(Collectors.groupingBy(UserKey::from,
Collectors.reducing((u1, u2) -> {
u1.setAccountBalance(u1.accountBalance() + u2.accountBalance());
return u1;
}));
由于Optional
可以确保已填充了这些,因此您可以调用get()
它们;而且,您不再需要按键,因此
List<User> result = mergedMap.values().stream()
.map(Optional::get)
.collect(toList());
地图
就像Naman在评论中建议的那样,您也可以通过快捷方式toMap
。
Map<UserKey,User> mergedMap = users.stream()
.collect(toMap(UserKey::from, Function.identity(),
(u1, u2) -> {
u1.setAccountBalance(u1.accountBalance() + u2.accountBalance());
return u1;
}));
List<User> result = new ArrayList<>(mergedMap.values());
请注意,reduce函数具有操作列表中原始用户对象之一的副作用,因此请确保不再需要它们。
问题内容: 我有一个带有20个属性的Java类及其相应的getter和setters。我也有两个对象列表:和。 现在,我想合并两个列表,并避免基于和的重复对象。 使用Java 8: 但是我必须在哪里指定属性?我应该重写和方法吗? 问题答案: 如果要实现and ,则 在 类 内部 进行操作。在该类中添加类似的方法 如果您这样做了,在上调用将自动执行正确的操作。 如果您不想(或无法)更改类,则没有平等
我需要从给定的超级列表中提取子列表,如下所述。 假设我有一个“Person”对象的超级列表如下: 让Person类定义如下: 通过使用Java Streams API,我如何获取包含如下条目的子列表(注意,必须获取具有相同名称的对象的重复实例): 有人能帮我用Java 8流API实现这一点吗? 附注:我不会预先知道这些对象的名称是什么值。
我有两个可观测值,一个返回1个元素,另一个返回多个元素。我的目标是在不阻塞的情况下将它们合并在一起,以构建如下对象: 我试过压缩、合并和合并,但似乎都不是解决方案。
我认为这个问题可以用动态规划来解决,但我不能提出递归关系。
我们在Java中有任何聚合器函数来执行下面的聚合吗?