Java条件组合问题,Java-合并给定条件的列表对象

I uttlerly convinced that my question its quite simple but im unable to do it with streams (if there is a way to do it without stream will be helpfull too)

Suppose that we have this list of users

public class Users {

String firstName;

String lastName;

double accountBalance;

String type;

String extraField;

}

and suppose that we have the following data in my List < Users >

"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"

}]

the expected result here its given that firstName, lastName and type appears twice on the list just merge the results that are common without missing any field

Expected output

"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

}]

解决方案

You can create a key class containing the three fields, like

@Data

class UserKey {

String firstName;

String lastName;

String type;

static UserKey from(User user) { /* TODO (trivial) */ }

}

groupingBy

Those can be used to group your users

Map> grouped =

users.stream().collect(Collectors.groupingBy(UserKey::from));

Each of these lists can then be merged by

Optional summed = userList.stream()

.collect(Collectors.reducing((u1, u2) -> {

u1.setAccountBalance(u1.accountBalance() + u2.accountBalance());

});

This can also be given directly as a downstream collector to the groupingBy:

Map> mergedMap =

users.stream().collect(Collectors.groupingBy(UserKey::from,

Collectors.reducing((u1, u2) -> {

u1.setAccountBalance(u1.accountBalance() + u2.accountBalance());

return u1;

}));

Since those Optionals are guaranteed to be filled, you can just call get() on them; also, you don't need the keys anymore, so

List result = mergedMap.values().stream()

.map(Optional::get)

.collect(toList());

toMap

As Naman suggested in the comments, you can also shortcut this by toMap.

Map mergedMap = users.stream()

.collect(toMap(UserKey::from, Function.identity(),

(u1, u2) -> {

u1.setAccountBalance(u1.accountBalance() + u2.accountBalance());

return u1;

}));

List result = new ArrayList<>(mergedMap.values());

Note that the reducing function has the side effect of manipulating one of the original user objects in the list, so make sure you don't need them again.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值