/** * Calculates the statistics required for a {@link BoxAndWhiskerItem}. * * <p>Any items in the list that are not instances of the <code>Number</code> class are ignored. * Likewise, <code>null</code> values are ignored. * * @param values A list of numbers (a <code>null</code> list is not permitted). * @return Box-and-whisker statistics. */ public static BoxAndWhiskerItem calculateBoxAndWhiskerStatistics(final List values) { Collections.sort(values); final double mean = Statistics.calculateMean(values); final double median = Statistics.calculateMedian(values, false); final double q1 = calculateQ1(values); final double q3 = calculateQ3(values); final double interQuartileRange = q3 - q1; final double upperOutlierThreshold = q3 + (interQuartileRange * 1.5); final double lowerOutlierThreshold = q1 - (interQuartileRange * 1.5); final double upperFaroutThreshold = q3 + (interQuartileRange * 2.0); final double lowerFaroutThreshold = q1 - (interQuartileRange * 2.0); double minRegularValue = Double.POSITIVE_INFINITY; double maxRegularValue = Double.NEGATIVE_INFINITY; double minOutlier = Double.POSITIVE_INFINITY; double maxOutlier = Double.NEGATIVE_INFINITY; final List outliers = new ArrayList(); final Iterator iterator = values.iterator(); while (iterator.hasNext()) { final Object object = iterator.next(); if (object != null && object instanceof Number) { final Number number = (Number) object; final double value = number.doubleValue(); if (value > upperOutlierThreshold) { outliers.add(number); if (value > maxOutlier && value <= upperFaroutThreshold) { maxOutlier = value; } } else if (value < lowerOutlierThreshold) { outliers.add(number); if (value < minOutlier && value >= lowerFaroutThreshold) { minOutlier = value; } } else { if (minRegularValue == Double.NaN) { minRegularValue = value; } else { minRegularValue = Math.min(minRegularValue, value); } if (maxRegularValue == Double.NaN) { maxRegularValue = value; } else { maxRegularValue = Math.max(maxRegularValue, value); } } } } minOutlier = Math.min(minOutlier, minRegularValue); maxOutlier = Math.max(maxOutlier, maxRegularValue); return new BoxAndWhiskerItem( new Double(mean), new Double(median), new Double(q1), new Double(q3), new Double(minRegularValue), new Double(maxRegularValue), new Double(minOutlier), new Double(maxOutlier), outliers); }