Reputation: 800
I want to combine and sum (specific properties) of two ArrayList of identical Domain Objects. Based on the condition of multiple properties matching, then combine them in one.
Here is my model class
public class SalesTransactionTax {
private String code;
private BigDecimal rate;
private Boolean isFixed;
private BigDecimal taxAmount;
public SalesTransactionTax(String code, BigDecimal rate, Boolean isFixed, BigDecimal taxAmount) { // NO_UCD
// (unused
// code)
this.code = code;
this.rate = rate;
this.isFixed = isFixed;
this.taxAmount = taxAmount;
}
public SalesTransactionTax() {
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public BigDecimal getRate() {
return rate;
}
public void setRate(BigDecimal rate) {
this.rate = rate;
}
public Boolean getIsFixed() {
return isFixed;
}
public void setFixed(Boolean fixed) {
isFixed = fixed;
}
public BigDecimal getTaxAmount() {
return taxAmount;
}
public void setTaxAmount(BigDecimal taxAmount) {
this.taxAmount = taxAmount;
}
@Override
public String toString() {
return "SalesTransactionTax [code=" + code + ", rate=" + rate + ", isFixed=" + isFixed
+ ", taxAmount=" + taxAmount + "]";
}
}
Using the following as an example:
List<SalesTransactionTax> taxes = new ArrayList<>();
taxes.add(new SalesTransactionTax("VAT_1", 5.000, true, 1.100));
taxes.add(new SalesTransactionTax("VAT_1", 5.000, true, 1.100));
taxes.add(new SalesTransactionTax("VAT_2", 9.000, true, 2.200));
taxes.add(new SalesTransactionTax("VAT_2", 9.000, true, 2.200));
taxes.add(new SalesTransactionTax("VAT_2", 9.000, true, 2.200));
taxes.add(new SalesTransactionTax("VAT_2", 9.000, false, 9.500));
taxes.add(new SalesTransactionTax("VAT_3", 7.000, true, 1.000));
Values in a new ArrayList would be:
Using Java 8, maybe a Lambda expression would be the way to go? Thanks for any suggestions.
Upvotes: 1
Views: 1069
Reputation: 3974
The add (...)
method should has the logic to sum the taxes amount, for to do that, it is necessary to check if the new transaction complies with established validations.
The validations should has the same: getCode(), getRate(), getIsFixed()
Snippet code to add:
public void add(SalesTransactionTax inputValue) {
SalesTransactionTax salesTransactionTax = checkInList(inputValue);
if (salesTransactionTax != null) {
// To sum operations the method used is add() from BigDecimal
salesTransactionTax.setTaxAmount(salesTransactionTax.getTaxAmount().add(inputValue.getTaxAmount()));
} else {
this.salesTransactionTaxList.add(inputValue);
}
}
To check if exist the new SalesTransactionTax
in the list you can validate using filter()
method from Java 8
Snippet code to check the validations:
private SalesTransactionTax checkInList(SalesTransactionTax stt) {
return salesTransactionTaxList.stream()
// To compare String is used equals()
.filter(stt2 -> stt2.getCode().equals(stt.getCode()))
// To compare BigDecimal is used compareTo()
.filter(stt2 -> stt2.getRate().compareTo(stt.getRate()) == 0)
// To compare boolean is used ==
.filter(stt2 -> stt2.getIsFixed() == stt.getIsFixed())
// If doesn't exist return null
.findAny().orElse(null);
}
Full example:
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public class SalesTransactionTax {
private String code;
private BigDecimal rate;
private Boolean isFixed;
private BigDecimal taxAmount;
private List<SalesTransactionTax> salesTransactionTaxList = null;
public SalesTransactionTax(String code, BigDecimal rate, Boolean isFixed, BigDecimal taxAmount) { // NO_UCD
this.code = code;
this.rate = rate;
this.isFixed = isFixed;
this.taxAmount = taxAmount;
}
public SalesTransactionTax() {
this.salesTransactionTaxList = new ArrayList<>();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public BigDecimal getRate() {
return rate;
}
public void setRate(BigDecimal rate) {
this.rate = rate;
}
public Boolean getIsFixed() {
return isFixed;
}
public void setFixed(Boolean fixed) {
isFixed = fixed;
}
public BigDecimal getTaxAmount() {
return taxAmount;
}
public void setTaxAmount(BigDecimal taxAmount) {
this.taxAmount = taxAmount;
}
public void add(SalesTransactionTax inputValue) {
SalesTransactionTax salesTransactionTax = checkInList(inputValue);
if (salesTransactionTax != null) {
// To sum operations the method used is add() from BigDecimal
salesTransactionTax.setTaxAmount(salesTransactionTax.getTaxAmount().add(inputValue.getTaxAmount()));
} else {
this.salesTransactionTaxList.add(inputValue);
}
}
private SalesTransactionTax checkInList(SalesTransactionTax stt) {
return salesTransactionTaxList.stream()
// To compare String is used equals()
.filter(stt2 -> stt2.getCode().equals(stt.getCode()))
// To compare BigDecimal is used compareTo()
.filter(stt2 -> stt2.getRate().compareTo(stt.getRate()) == 0)
// To compare boolean is used ==
.filter(stt2 -> stt2.getIsFixed() == stt.getIsFixed())
// If doesn't exist return null
.findAny().orElse(null);
}
public void print() {
salesTransactionTaxList.forEach(System.out::println);
}
@Override
public String toString() {
//Output formatted
DecimalFormat df = new DecimalFormat("#,###.000");
return code + ", " + df.format(new BigDecimal(String.valueOf(rate))) + ", " + isFixed + ", " + df.format(new BigDecimal(String.valueOf(taxAmount)));
}
public static void main(String[] args) {
SalesTransactionTax mergeTaxes = new SalesTransactionTax();
mergeTaxes.add(new SalesTransactionTax("VAT_1", BigDecimal.valueOf(5.000), true, BigDecimal.valueOf(1.100)));
mergeTaxes.add(new SalesTransactionTax("VAT_1", BigDecimal.valueOf(5.000), true, BigDecimal.valueOf(1.100)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), true, BigDecimal.valueOf(2.200)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), true, BigDecimal.valueOf(2.200)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), true, BigDecimal.valueOf(2.200)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), false, BigDecimal.valueOf(9.500)));
mergeTaxes.add(new SalesTransactionTax("VAT_3", BigDecimal.valueOf(7.000), true, BigDecimal.valueOf(1.000)));
mergeTaxes.print();
}
}
Output:
VAT_1, 5.000, true, 2.200
VAT_2, 9.000, true, 6.600
VAT_2, 9.000, false, 9.500
VAT_3, 7.000, true, 1.000
Upvotes: 4
Reputation: 208
You said
Based on the condition if two properties match, then combine them in one.
But based on the example results, you need to check three properties match.
public class SalesTransactionMerge {
private List<SalesTransactionTax> taxes = null;
public List<SalesTransactionTax> getTaxes(){
return this.taxes;
}
public SalesTransactionMerge(){
this.taxes = new ArrayList<SalesTransactionTax>();
}
public void add(SalesTransactionTax stt){
SalesTransactionTax sttExists = exists(stt);
if(sttExists == null){
this.taxes.add(stt);
}
else{
sttExists.setTaxAmount(sttExists.getTaxAmount().add(stt.getTaxAmount()));
}
}
private SalesTransactionTax exists(SalesTransactionTax stt){
SalesTransactionTax sttExists = null;
for(SalesTransactionTax stt2 : taxes){
int matches = 0;
if(stt2.getCode().equals(stt.getCode())) matches++;
if(stt2.getRate().compareTo(stt.getRate()) == 0) matches++;
if(stt2.getIsFixed() == stt.getIsFixed()) matches++;
if(matches == 3){
sttExists = stt2;
break;
}
}
return sttExists;
}
public void print(){
for(SalesTransactionTax stt : taxes){
System.out.println(stt.toString());
}
}
}
Using your examples
public static void main(String[] args) {
SalesTransactionMerge mergeTaxes = new SalesTransactionMerge();
mergeTaxes.add(new SalesTransactionTax("VAT_1", BigDecimal.valueOf(5.000), true, BigDecimal.valueOf(1.100)));
mergeTaxes.add(new SalesTransactionTax("VAT_1", BigDecimal.valueOf(5.000), true, BigDecimal.valueOf(1.100)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), true, BigDecimal.valueOf(2.200)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), true, BigDecimal.valueOf(2.200)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), true, BigDecimal.valueOf(2.200)));
mergeTaxes.add(new SalesTransactionTax("VAT_2", BigDecimal.valueOf(9.000), false, BigDecimal.valueOf(9.500)));
mergeTaxes.add(new SalesTransactionTax("VAT_3", BigDecimal.valueOf(7.000), true, BigDecimal.valueOf(1.000)));
mergeTaxes.print();
}
Upvotes: 0