Reputation: 3881
How to merge two user list, if user is common merge its attribute.
I have two user lists, getting first list from DB and second from web service, if their firstname and lastname are same then user merge attribute and return combined list.
import java.util.List;
import java.util.Objects;
class User {
String firstName;
String lastName;
Integer count;
Integer marks;
String status;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return Objects.equals(firstName, user.firstName) &&
Objects.equals(lastName, user.lastName);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}
//constructor getter setter....
}
public class MainTest {
public static void main(String[] args) {
List<User> source1 = List.of(new User("A", "A", 1, 0, null),
new User("B", "B", 2, 0, null),
new User("C", "C", 3, 0, null));
List<User> source2 = List.of(new User("A", "A", 0, 10, "FAIL"),
new User("B", "B", 0, 20, "FAIL"),
new User("D", "D", 0, 30, "PASS"));
List<User> combinedExpectedList = List.of(new User("A", "A", 1, 10, "FAIL"),
new User("B", "B", 2, 20, "FAIL"),
new User("C", "C", 3, 0, null),
new User("D", "D", 0, 30, "PASS"));
//List<User> userList3= Stream.concat(source1.stream(), source2.stream()).distinct().collect(Collectors.toList());//Adding 4 records but marks and status not copied
//BeanUtils.copyProperties(model2, model1); - can't user don't have library
for (User t : source2) {
for (User s : source1) {
if (t.getFirstName().equals(s.getFirstName()) && t.getLastName().equals(s.getLastName())) {
t.setCount(s.getCount());
}
}
}// Not adding record with firstName=C and LastName=C
System.out.println(combinedExpectedList.equals(source2));
}
}
Upvotes: 1
Views: 243
Reputation: 4120
Similar to this answer but here 'User' within source list remains unchanged:
List<User> values = new ArrayList<>(Stream.concat(source1.stream(), source2.stream())
.collect(Collectors.toMap(e -> e.firstName + e.lastName, Function.identity(),
(User u1, User u2) ->
new User(u1.firstName, u1.lastName, u1.count,
(u1.marks == 0) ? u2.marks : u1.marks,
(u1.status == null) ? u2.status : u1.status
)
)).values());
Upvotes: 0
Reputation: 7165
Assuming that you want to retain non zero marks and non null status elements, you can not directly use distinct. You can use Collectors.toMap
as below,
List<User> userList3 = Stream.concat(source1.stream(), source2.stream())
.collect(Collectors.toMap(e -> e.firstName + e.lastName, e -> e,
(User u1, User u2) -> {
if (u1.marks == 0)
u1.marks = u2.marks;
if (u1.status == null)
u1.status = u2.status;
return u1;
})).values().stream().collect(Collectors.toList());
Note that you may need to reorder elements.
Upvotes: 3