0

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);
}
eancu
  • 53
  • 9

1 Answers1

1

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<>();
    ...
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Do not need to call `clear` with this solution – Scary Wombat Aug 16 '17 at 06:51
  • Didn't quite work but using this and Scary Wombat's suggestion I got it to work. I created new lists in the for loop, and then added my previous list into the clones to generate the results. – eancu Aug 16 '17 at 07:12