package com.anjlab.ping.services; import java.util.Collections; import java.util.Comparator; import java.util.List; import com.anjlab.cubics.Aggregate; import com.anjlab.cubics.BeanValueProvider; import com.anjlab.cubics.FactValueProvider; public class GeneralStats { private double min; private double max; private double average; private double count; private double sum; private double squaredSigma; private double standard; private double median; private GeneralStats(double min, double max, double average, int count, double sum, double squaredSigma, double standard, double median) { this.min = min; this.max = max; this.average = average; this.count = count; this.sum = sum; this.squaredSigma = squaredSigma; this.standard = standard; this.median = median; } public double getMin() { return min; } public double getMax() { return max; } public double getAverage() { return average; } public double getCount() { return count; } public double getSum() { return sum; } public double getSquaredSigma() { return squaredSigma; } public double getStandard() { return standard; } public double getMedian() { return median; } @SuppressWarnings("unchecked") public static <T> GeneralStats calculate(Class<T> clazz, final String property, List<T> data) { final FactValueProvider<T> beanClass = new BeanValueProvider<T>(clazz); Collections.sort((List<T>)data, new Comparator<T>() { @Override @SuppressWarnings("rawtypes") public int compare(T o1, T o2) { Comparable v1 = (Comparable<?>) beanClass.getValue(property, o1); Comparable v2 = (Comparable<?>) beanClass.getValue(property, o2); return v1.compareTo(v2); } }); double median = ((Number) beanClass.getValue(property, data.get(data.size() / 2))).doubleValue(); Aggregate<T> aggregate = new Aggregate<T>(null); for (T item : data) { aggregate.add(beanClass.getValue(property, item)); } double avg = aggregate.getAverage(); // Dispersion double squaredSigma = 0; for (T item : data) { Number n = (Number) beanClass.getValue(property, item); squaredSigma += Math.pow(n.doubleValue() - avg, 2); } int N = aggregate.getCount(); squaredSigma = squaredSigma / N; double standard = Math.sqrt(N / (N - 1) * squaredSigma); return new GeneralStats( aggregate.getMin(), aggregate.getMax(), aggregate.getAverage(), aggregate.getCount(), aggregate.getSum(), squaredSigma, standard, median); } }