I am a beginner in Java and I have a hobby project to create a tool for statistical calculations.
Users can upload csv with results of a survey. The responses stored in a Response
object which has two maps: Map<Integer, String> questionMap
, Map<Integer, String> answerMap
, where the integer(questionID
) links the question and answer.
I would like implement an extra feature: to filter the responses to certain values. Therefore the Filter
class stores a questionID
(int
) and a filterValue
(String
).
Now I would like to calculate the averages of the fields. I have a working implementation but I hope you can help me to make it better:
public List<AverageResult> calculateAverage(List<Response> responses, List<Filter> filters){
List<Response> responsesCopy = new ArrayList<>(responses);
List<AverageResult> averages = new LinkedList<>();
Set<Integer> questionIDSet = responses.get(0).getAnswerMap().keySet();
for(Integer questionID :questionIDSet) {
double sum = 0;
int count=0;
for(Iterator<Response> iter = responsesCopy.iterator(); iter.hasNext();) {
Response actualResponse = iter.next();
if(filterMatch(actualResponse,filters)) {
if(isNumber(actualResponse, questionID)) {
sum += Double.valueOf(actualResponse.getAnswerMap().get(questionID));
count += 1;
}
}else {
iter.remove();
}
}
Double average = null;
if(count != 0) {
average = sum/count;
AverageResult avRes = new AverageResult();
avRes.setAverage(average);
avRes.setQuestionID(questionID);
avRes.setCount(count);
averages.add(avRes);
}
}
return averages;
}
private boolean isNumber(Response response, int questionID) {
Pattern p = Pattern.compile("[0-9]*\\.?[0-9]+");
return (p.matcher(response.getAnswerMap().get(questionID)).matches());
}
private boolean filterMatch(Response response, List<Filter> filters) {
for(Filter filter: filters) {
if(!response.getAnswerMap().get(filter.getQuestionID()).equals(filter.getFilterValue())) {
return false;
}
}
return true;
}