'How to combine 2 or more objects in a list based on certain fields of those objects
I'm sorry if the title sounds vague.
I have an object -
public class AccountInfo {
private String accountId;
private Double vat;
private Double totalFee;
private Date invoiceDate;
}
and there is a list of these objects-
List<AccountInfo> AccountInfoLst;
I want to manipulate this list by combining objects with the same accountId by adding up the vat and totalFee fields, provided they have the same invoiceDate as well.
If two objects have the same accountId but different invoiceDate, they shouldn't be combined.
Solution 1:[1]
Iterate over the list which are duplicate combine them to one AccountInfo and remove all the duplicates.
Since Date is deprecated we have used java.time.LocalDate.
Code:
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class AccountInfo {
private String accountId;
private Double vat;
private Double totalFee;
private LocalDate invoiceDate;
public Double getVat() {
return vat;
}
public void setVat(Double vat) {
this.vat = vat;
}
public Double getTotalFee() {
return totalFee;
}
public void setTotalFee(Double totalFee) {
this.totalFee = totalFee;
}
public LocalDate getInvoiceDate() {
return invoiceDate;
}
public void setInvoiceDate(LocalDate invoiceDate) {
this.invoiceDate = invoiceDate;
}
public AccountInfo(String accountId, Double vat, Double totalFee, LocalDate invoiceDate) {
this.accountId = accountId;
this.vat = vat;
this.totalFee = totalFee;
this.invoiceDate = invoiceDate;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String toString() {
return accountId + " " + vat + " " + totalFee + " " + invoiceDate;
}
public boolean areEquals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AccountInfo that = (AccountInfo) o;
var thatInvoiceDate = that.getInvoiceDate();
var thisInvoiceDate = getInvoiceDate();
return that.getAccountId().equals(getAccountId()) && thatInvoiceDate.isEqual(thisInvoiceDate);
}
@Override
public int hashCode() {
return Objects.hash(accountId, vat, totalFee, invoiceDate);
}
}
public class MainClass {
public static void main(String... $) {
var out = System.out;
List<AccountInfo> accounts = Stream.of(new AccountInfo("A", 20.2, 200.4, LocalDate.of(2022, 11, 3))
, new AccountInfo("A", 20.2, 200.4, LocalDate.of(2022, 11, 3)),
new AccountInfo("B", 20.2, 200.4, LocalDate.of(2023, 11, 2)),
new AccountInfo("B", 20.2, 200.4, LocalDate.of(2023, 11, 2))).collect(Collectors.toList());
//Iterating over all the accounts
for (int i = 0; i < accounts.size(); i++) {
var account = accounts.get(i);
ArrayList<AccountInfo> duplicates = new ArrayList<>();
for (int j = i + 1; j < accounts.size(); j++) {
var acc = accounts.get(j);
if (acc.areEquals(account))
duplicates.add(acc);
}
// out.println(i + " " + indices);
//Merging all duplicates to account
for (AccountInfo acc : duplicates) {
account.setTotalFee(acc.getTotalFee() + account.getTotalFee());
account.setVat(acc.getVat() + account.getVat());
}
//Removing all duplicates
accounts.removeAll(duplicates);
}
//printing accounts after removal of duplicates
out.println(accounts);
}
}
Output:
[A 40.4 400.8 2022-11-03, B 40.4 400.8 2023-11-02]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Udesh Ranjan |
