This is a sample test code I wrote to ensure what I know is right
class Form {
List<Sample> samples;
List<Sample> sampleList;
public List<Sample> getSamples() {
return samples;
}
public void setSamples(List<Sample> samples) {
this.samples = samples;
}
public List<Sample> getSampleList() {
return sampleList;
}
public void setSampleList(List<Sample> sampleList) {
this.sampleList = sampleList;
}
void setInitialData() {
this.samples = new ArrayList<Sample>();
this.sampleList = new ArrayList<Sample>();
}
}
class Sample {
}
public class ListAddingAmbiguity {
public static void main(String[] args) {
Form form = new Form();
form.setInitialData();
Sample sample = new Sample();
form.getSamples().add(sample);
form.getSampleList().add(sample);
System.out.println(form.getSamples().size());
System.out.println(form.getSampleList().size());
}
}
The output coming is
1
1
And it is correct, samples
and sampleList
are two different references pointing to two different memory locations, so adding to samples
won't change the size of sampleList
.
But in my project code it is different, this is my Form
class
public class InvoiceForm extends BaseActionForm {
private List<ProductTO> products;
private List<ProductTO> productList;
// getters and setters
}
This is the code in my Action
class
private void setProductsToInvoice(InvoiceForm invoiceForm) throws Exception {
if(invoiceForm.getProducts() != null && !invoiceForm.getProducts().isEmpty()){
ProductTO productTO = new ProductTO();//ProductEntryHandler.getInstance().prepareProductsForInvoice();
invoiceForm.getProducts().add(productTO);
invoiceForm.getProductList().add(productTO);
}else {
List<ProductTO> productTOs = new ArrayList<ProductTO>();
productTOs.add(ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(productTOs);
invoiceForm.setProductList(productTOs);
}
}
Both the products and productList are having a size of 1
initially, so in the above code if block
will execute. The commented portion is the earlier code. Even if it is the new code ProductTO productTO = new ProductTO();
or the old code ProductTO productTO = ProductEntryHandler.getInstance().prepareProductsForInvoice();
the problem is the same.
Like I said when execution comes to the method both the lists are having a size of 1
. When the line invoiceForm.getProducts().add(productTO);
is executed the size of products
and productList
size becomes 2
, which is in conflict with my test code. Now when the nest line invoiceForm.getProductList().add(productTO);
is executed both the list size is becoming 3
. I don't know why its happening, can anybody help?
The following code else
case in setProductsToInvoice
set both products
and productList
to the same list:
List<ProductTO> productTOs = new ArrayList<ProductTO>();
productTOs.add(ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(productTOs);
invoiceForm.setProductList(productTOs);
The correct way, or at least the less incorrect way, is something like this:
ProductTO newProd =
ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(new ArrayList<ProductTO>());
invoiceForm.getProducts().add(newProd);
invoiceForm.setProductList(new ArrayList<ProductTO>());
invoiceForm.getProductList().add(newProd);
I'd suggest an investigation to determine why there are two lists apparently being maintained in parallel in the first place. At first glance, it has a bit of a smell to it...