2016-03-29 6 views
0

Ich habe eine Sammlung von täglichen Daten, die ich aus einem Mongo db mit dem mongo-java-Treiber abrufen. Die Tabelle, die ich abfrage, hat tägliche Daten nur für heute. Sobald ich das Ergebnis eingestellt habe, erstelle ich Durchschnittswerte für eines der Felder (ein doppelter Wert) im Dokument für alle zweistündigen Intervalle an einem Tag (00:00 - 02:00, 02:00 - 04:00 usw.).Was ist der effizienteste Weg, um Durchschnittswerte in Zeitintervallen von 2 Stunden zu berechnen

Dies ist der Code, den ich derzeit verwende. Die Liste der täglichen Daten wird im Parameter der Methode gesendet, nachdem ich sie einem DailyData-Modell (unter Verwendung eines JsonTransformers) zugeordnet habe.

Ich habe den Code abgespeckte es einfacher zu machen, zu lesen:

public List<Model> getDailyData(List<DailyData> data) throws ParseException { 

    //These are all the variables I use in my code, I have omitted their usage in this snippet in order to trim it down 

    double occurenceOfDateRange1 = 0; 
    double occurenceOfDateRange2 = 0; 
    double occurenceOfDateRange3 = 0; 
    double occurenceOfDateRange4 = 0; 
    double occurenceOfDateRange5 = 0; 
    double occurenceOfDateRange6 = 0; 
    double occurenceOfDateRange7 = 0; 
    double occurenceOfDateRange8 = 0; 
    double occurenceOfDateRange9 = 0; 
    double occurenceOfDateRange10 = 0; 
    double occurenceOfDateRange11 = 0; 
    double occurenceOfDateRange12 = 0; 

    double percentage1 = 0; 
    double percentage2 = 0; 
    double percentage3 = 0; 
    double percentage4 = 0; 
    double percentage5 = 0; 
    double percentage6 = 0; 
    double percentage7 = 0; 
    double percentage8 = 0; 
    double percentage9 = 0; 
    double percentage10 = 0; 
    double percentage11 = 0; 
    double percentage12 = 0; 

    List<Model> modelList = new ArrayList<Model>(); 

    String pattern = "yyyy-MM-ddHH:mm:ss"; 

//There are 9 more date variables created like these three below (06:00:00, 08:00:00, 10:00:00 etc to 23:59:59) 

    String dateStr1 = getdate() + " 00:00:00"; //getDate() refers to a separate method in which I return the current date in yyyy/MM/dd string format 
    Date date1 = new SimpleDateFormat(pattern).parse(dateStr1); 

    String dateStr2 = getdate() + " 02:00:00"; 
    Date date2 = new SimpleDateFormat(pattern).parse(dateStr2); 

    String dateStr3 = getdate() + " 04:00:00"; 
    Date date3 = new SimpleDateFormat(pattern).parse(dateStr3); 

    //the other 9 date variables are created here 

    if (data != null) { 
     for (int num = 0; num < data.size(); num++) { 
      Date recordDate = new SimpleDateFormat(pattern).parse(data.get(num).getCheckDate()); 

      //Ten more checks along with the following two are done, I have omitted them to slim the code down (checks between date3 and date4, between date4 and date 5 etc) 

      if (recordDate.after(date1) && recordDate.before(date2)) { 
       percentage1 += data.get(num).getPercentage(); 
       occurenceOfDateRange1 += 1; 

      } 

      if (recordDate.after(date2) && recordDate.before(date3)) { 
       percentage2 += data.get(num).getPercentage(); 
       occurenceOfDateRange2 += 1; 
      } 

      //checks for the rest of the dates are done here 
     } 

     Model model = new Model(); 

     //the following if blocks are repeated 10 more times for percentage3 to percentage12 

     if (percentage1 != 0) { 
      model = new Model(); 
      model.setDate_time_stamp(dateStr1); 
      if (occurenceOfDateRange1 != 0) { 
       model.setAvgPerc(percentage1/occurenceOfDateRange1); 
      } else { 
       model.setAvgPerc(0); 
      } 
      modelList.add(model); 
     } 

     if (percentage2 != 0) { 
      model = new Model(); 
      model.setDate_time_stamp(dateStr2); 
      if (occurenceOfDateRange2 != 0) { 
       model.setAvgPerc(percentage2/occurenceOfDateRange2); 
      } else { 
       model.setAvgPerc(0); 
      } 
      modelList.add(model); 
     } 
    } 

    return modelList; 
} 

Meine Frage ist - Gibt es eine effizientere (oder klüger, wenn man so will) Art und Weise der durchschnittliche Prozentsatz zwischen zwei der Berechnung stündliche Intervalle ohne die Verwendung so vieler if-Blöcke?

+3

Nun ... Sie könnten ein 'double [] occurenceOfDateRanges' verwenden und ein' double [] percentages' (und Arrays für alle anderen Variablen, die Sie Verwenden Sie auf diese Weise) und eine einfache for-Schleife. – Seelenvirtuose

+0

Sie könnten die Zeit in Millis analysieren und durch "2 * 60 * 60 * 1000" dividieren, um die Intervallnummer zu erhalten. –

Antwort

1

Ich denke, dass ich es so machen könnte:

public List<Model> getDailyData(List<DailyData> data) throws ParseException { 

    List<Model> modelList = new ArrayList<Model>(); 

    String pattern = "yyyy-MM-ddHH:mm:ss"; 

    double[] occurenceOfDateRange = {0.0, 0.0, 0.0, 
     0.0, 0.0, 0.0, 
     0.0, 0.0, 0.0, 
     0.0, 0.0, 0.0}; 
    double[] percentages = {0.0, 0.0, 0.0, 
     0.0, 0.0, 0.0, 
     0.0, 0.0, 0.0, 
     0.0, 0.0, 0.0}; 

    if (data != null) { 
     SimpleDateFormat df = new SimpleDateFormat(pattern); 
     for (int num = 0; num < data.size(); num++) { 
      Calendar recordDate = Calendar.getInstance(); 
      recordDate.setTime(
        new SimpleDateFormat(pattern).parse(data.get(num).getCheckDate())); 

      percentages[recordDate.get(Calendar.HOUR_OF_DAY)/2] += data.get(num).getPercentage(); 
      occurenceOfDateRange[recordDate.get(Calendar.HOUR_OF_DAY)/2] += 1; 

     } 

     Calendar base = Calendar.getInstance(); 
     base.set(Calendar.HOUR, 0); 

     for (int i = 0; i < 12; i++) { 
      Model model = new Model(); 
      model.setDate_time_stamp(df.format(base)); 
      if (occurenceOfDateRange[i] != 0) { 
       model.setAvgPerc(percentages[i]/occurenceOfDateRange[i]); 
      } else { 
       model.setAvgPerc(0); 
      } 
      modelList.add(model); 
      base.set(Calendar.HOUR, base.get(Calendar.HOUR) + 2); 
     } 
    } 

    return modelList; 
} 
+0

Sie können 'data.get (num)' in eine lokale Variable extrahieren –

+0

Danke. Klappt wunderbar. –

Verwandte Themen