(See the previous iteration.)
Now all operations of the data structure work in exact constant time, yet it came with the price: the state of this set maybe non-sensical. A user may end up with the set with negative number of elements in it. Basically, the client programmer must keep track of how he/she work with this set.
StatisticsNumberSet.java
package net.coderodde.stat;
/**
* This class provides the means for rapid statistics queries.
*
* @author Rodion "rodde" Efremov
* @version 1.618 (Mar 28, 2017)
*/
public class StatisticsNumberSet {
/**
* Holds the sum of all elements in this set.
*/
private double sum;
/**
* Holds the sum of square of each element in this set.
*/
private double squareSum;
/**
* Holds the number of elements currently in this set.
*/
private int size;
/**
* Adds the given number to this set.
*
* @param number the number to add.
*/
public void add(double number) {
checkNumberIsFinite(number);
sum += number;
squareSum += number * number;
size++;
}
/**
* Converts and adds the given number to this set.
*
* @param number the number to add.
*/
public void add(Number number) {
add(number.doubleValue());
}
/**
* Removes the given number from this set.
*
* @param number the number to remove.
*/
public void remove(double number) {
checkNumberIsFinite(number);
sum -= number;
squareSum -= number * number;
size--;
}
/**
* Converts and removes the given number from this set.
*
* @param number the number to remove.
*/
public void remove(Number number) {
remove(number.doubleValue());
}
/**
* Resets the state of this set to an empty set.
*/
public void clear() {
sum = 0.0;
squareSum = 0.0;
size = 0;
}
/**
* Returns the number of elements in this set.
*
* @return the size of this set.
*/
public int size() {
return size;
}
/**
* Computes the average of this set.
*
* @return the average.
*/
public double getAverage() {
return sum / size;
}
/**
* Computes the variance of this set.
*
* @return the variance.
*/
public double getVariance() {
double step1 = squareSum - sum * sum / size;
return step1 / (size - 1);
}
/**
* Computes the standard deviation of this set.
*
* @return the standard deviation.
*/
public strictfp double getStandardDeviation() {
return Math.sqrt(getVariance());
}
/**
* Returns the textual representation of the state of this set.
*
* @return the textual representation.
*/
@Override
public String toString() {
return "[Size = " + size + ", average = " + getAverage() +
", s.d. = " + getStandardDeviation() + ", variance = " +
getVariance() + "]";
}
public static void main(String[] args) {
StatisticsNumberSet set = new StatisticsNumberSet();
set.add(1);
set.add(1.0f);
set.add((byte) 3);
System.out.println(set);
set.remove(1.0f);
System.out.println(set);
set.clear();
System.out.println(set);
}
private void checkNumberIsFinite(double number) {
if (Double.isNaN(number)) {
throw new IllegalArgumentException("number is NaN");
}
if (Double.isInfinite(number)) {
throw new IllegalArgumentException("number is +Inf or -Inf");
}
}
}
As always, any critique is much appreciated.