E. Ancuta E. Ancuta -3 years ago 103
Java Question

Clearing the list also clears previous records of the list in Java

I have a list of data values that I am inserting into a HashMap to be read by the request, and I am inputting that data into a table in my JSP. The issue I'm having here is that I would successfully add the data into the relevant lists, and then add it into the hashmap, but once I clear the lists to retrieve new data for a new year, it also clears the recorded values in the hashmap. How do I stop this from dynamically adjusting my hashmap? Thank you for your time.

Here is my code, although I don't think it's the issue as much as my lack of knowledge.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}

List<MyDataType> dataList = null;
try {
dataList = ***;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

HashMap<String, List<BigDecimal>> recordYearlyData = new HashMap<>();
String nwC = "New Customers ";
String alC = "All Customers ";
String lsC = "Lost Customers ";
String rtC = "Rate ";

List<BigDecimal> startCus = new ArrayList<>();

List<BigDecimal> newCus = new ArrayList<>();

List<BigDecimal> endCus = new ArrayList<>();

List<BigDecimal> thisYearCus = new ArrayList<>();

List<BigDecimal> lostCus = new ArrayList<>();

List<BigDecimal> rateL = new ArrayList<>();

for (MyDataType dataType : dataList) {

String createDate = dataType.getOrderDate().toString();
String createDateN = createDate.substring(5, 7);
Integer getDateKey = Integer.parseInt(createDateN) - 1;
Integer getYear = Integer.parseInt(createDate.substring(0,4));
BigDecimal tenant_id = dataType.getTenantID();

createDateLabel = monthNames[getDateKey];

if (getYear != yearChecker) {
String yearLabel = String.valueOf(getYear - 1);
for (BigDecimal tenant : thisYearCus) {
if (newCus.contains(tenant) || startCus.contains(tenant)) {
endCus.add(tenant);
}
}
for (BigDecimal tenant : startCus) {
if (!thisYearCus.contains(tenant)) {
lostCus.add(tenant);
}
}

double rate = 1.0;
if (startCus.size() == 0) {
rate=1.0;
} else if (startCus.size() > 0){
rate = ((double) endCus.size() - (double) newCus.size())/(double) startCus.size();
}

rateL.add(BigDecimal.valueOf(rate));

recordYearlyData.put(alC+yearLabel, thisYearCus);
recordYearlyData.put(nwC+yearLabel, newCus);
recordYearlyData.put(lsC+yearLabel, lostCus);
recordYearlyData.put(rtC+yearLabel, rateL);

rateL.clear();
startCus.clear();
startCus.addAll(thisYearCus);
thisYearCus.clear();
endCus.clear();
newCus.clear();
lostCus.clear();
yearChecker = getYear;
}

if (!thisYearCus.contains(tenant_id)) {
thisYearCus.add(tenant_id);
}
if (!startCus.contains(tenant_id)) {
if(!newCus.contains(tenant_id)) {
newCus.add(tenant_id);
}
}
}



request.setAttribute("newCusTable", recordYearlyData.get("New Customers 2015"));
request.setAttribute("allCusTable", recordYearlyData.get("All Customers 2015"));
request.setAttribute("lostCusTable", recordYearlyData.get("Lost Customers 2015"));
request.setAttribute("retRate", recordYearlyData.get("Rate 2015"));

RequestDispatcher view = request.getRequestDispatcher("/Sales.jsp");
view.forward(request, response);
}

Answer Source

What happens is that you keep inserting references to the same lists into your map, instead of creating a new list each time. To fix, move the list declarations into the for loop:

for (MyDataType dataType : dataList) {
    List<BigDecimal> startCus = new ArrayList<>();
    List<BigDecimal> newCus = new ArrayList<>();
    List<BigDecimal> endCus = new ArrayList<>();
    List<BigDecimal> thisYearCus = new ArrayList<>();
    List<BigDecimal> lostCus = new ArrayList<>();
    List<BigDecimal> rateL = new ArrayList<>();
    ...
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download