/*
 * Copyright (C) 2012 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.common.math;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.math.DoubleUtils.ensureNonNegative;
import static com.google.common.math.StatsAccumulator.calculateNewMeanNonFinite;
import static com.google.common.primitives.Doubles.isFinite;
import static java.lang.Double.NaN;
import static java.lang.Double.doubleToLongBits;
import static java.lang.Double.isNaN;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Iterator;
import org.checkerframework.checker.nullness.qual.Nullable;

A bundle of statistical summary values -- sum, count, mean/average, min and max, and several forms of variance -- that were computed from a single set of zero or more floating-point values.

There are two ways to obtain a Stats instance:

  • If all the values you want to summarize are already known, use the appropriate Stats.of factory method below. Primitive arrays, iterables and iterators of any kind of Number, and primitive varargs are supported.
  • Or, to avoid storing up all the data first, create a StatsAccumulator instance, feed values to it as you get them, then call StatsAccumulator.snapshot.

Static convenience methods called meanOf are also provided for users who wish to calculate only the mean.

Java 8 users: If you are not using any of the variance statistics, you may wish to use built-in JDK libraries instead of this class.

Author:Pete Gillin, Kevin Bourrillion
Since:20.0
/** * A bundle of statistical summary values -- sum, count, mean/average, min and max, and several * forms of variance -- that were computed from a single set of zero or more floating-point values. * * <p>There are two ways to obtain a {@code Stats} instance: * * <ul> * <li>If all the values you want to summarize are already known, use the appropriate {@code * Stats.of} factory method below. Primitive arrays, iterables and iterators of any kind of * {@code Number}, and primitive varargs are supported. * <li>Or, to avoid storing up all the data first, create a {@link StatsAccumulator} instance, * feed values to it as you get them, then call {@link StatsAccumulator#snapshot}. * </ul> * * <p>Static convenience methods called {@code meanOf} are also provided for users who wish to * calculate <i>only</i> the mean. * * <p><b>Java 8 users:</b> If you are not using any of the variance statistics, you may wish to use * built-in JDK libraries instead of this class. * * @author Pete Gillin * @author Kevin Bourrillion * @since 20.0 */
@Beta @GwtIncompatible public final class Stats implements Serializable { private final long count; private final double mean; private final double sumOfSquaresOfDeltas; private final double min; private final double max;
Internal constructor. Users should use of or StatsAccumulator.snapshot.

To ensure that the created instance obeys its contract, the parameters should satisfy the following constraints. This is the callers responsibility and is not enforced here.

  • If count is 0, mean may have any finite value (its only usage will be to get multiplied by 0 to calculate the sum), and the other parameters may have any values (they will not be used).
  • If count is 1, sumOfSquaresOfDeltas must be exactly 0.0 or Double.NaN.
/** * Internal constructor. Users should use {@link #of} or {@link StatsAccumulator#snapshot}. * * <p>To ensure that the created instance obeys its contract, the parameters should satisfy the * following constraints. This is the callers responsibility and is not enforced here. * * <ul> * <li>If {@code count} is 0, {@code mean} may have any finite value (its only usage will be to * get multiplied by 0 to calculate the sum), and the other parameters may have any values * (they will not be used). * <li>If {@code count} is 1, {@code sumOfSquaresOfDeltas} must be exactly 0.0 or {@link * Double#NaN}. * </ul> */
Stats(long count, double mean, double sumOfSquaresOfDeltas, double min, double max) { this.count = count; this.mean = mean; this.sumOfSquaresOfDeltas = sumOfSquaresOfDeltas; this.min = min; this.max = max; }
Returns statistics over a dataset containing the given values.
Params:
  • values – a series of values, which will be converted to double values (this may cause loss of precision)
/** * Returns statistics over a dataset containing the given values. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision) */
public static Stats of(Iterable<? extends Number> values) { StatsAccumulator accumulator = new StatsAccumulator(); accumulator.addAll(values); return accumulator.snapshot(); }
Returns statistics over a dataset containing the given values.
Params:
  • values – a series of values, which will be converted to double values (this may cause loss of precision)
/** * Returns statistics over a dataset containing the given values. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision) */
public static Stats of(Iterator<? extends Number> values) { StatsAccumulator accumulator = new StatsAccumulator(); accumulator.addAll(values); return accumulator.snapshot(); }
Returns statistics over a dataset containing the given values.
Params:
  • values – a series of values
/** * Returns statistics over a dataset containing the given values. * * @param values a series of values */
public static Stats of(double... values) { StatsAccumulator acummulator = new StatsAccumulator(); acummulator.addAll(values); return acummulator.snapshot(); }
Returns statistics over a dataset containing the given values.
Params:
  • values – a series of values
/** * Returns statistics over a dataset containing the given values. * * @param values a series of values */
public static Stats of(int... values) { StatsAccumulator acummulator = new StatsAccumulator(); acummulator.addAll(values); return acummulator.snapshot(); }
Returns statistics over a dataset containing the given values.
Params:
  • values – a series of values, which will be converted to double values (this may cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15))
/** * Returns statistics over a dataset containing the given values. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15)) */
public static Stats of(long... values) { StatsAccumulator acummulator = new StatsAccumulator(); acummulator.addAll(values); return acummulator.snapshot(); }
Returns the number of values.
/** Returns the number of values. */
public long count() { return count; }
Returns the arithmetic mean of the values. The count must be non-zero.

If these values are a sample drawn from a population, this is also an unbiased estimator of the arithmetic mean of the population.

Non-finite values

If the dataset contains Double.NaN then the result is Double.NaN. If it contains both Double.POSITIVE_INFINITY and Double.NEGATIVE_INFINITY then the result is Double.NaN. If it contains Double.POSITIVE_INFINITY and finite values only or Double.POSITIVE_INFINITY only, the result is Double.POSITIVE_INFINITY. If it contains Double.NEGATIVE_INFINITY and finite values only or Double.NEGATIVE_INFINITY only, the result is Double.NEGATIVE_INFINITY.

If you only want to calculate the mean, use {#meanOf} instead of creating a Stats instance.

Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>If these values are a sample drawn from a population, this is also an unbiased estimator of * the arithmetic mean of the population. * * <h3>Non-finite values</h3> * * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it * contains both {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} then the * result is {@link Double#NaN}. If it contains {@link Double#POSITIVE_INFINITY} and finite values * only or {@link Double#POSITIVE_INFINITY} only, the result is {@link Double#POSITIVE_INFINITY}. * If it contains {@link Double#NEGATIVE_INFINITY} and finite values only or {@link * Double#NEGATIVE_INFINITY} only, the result is {@link Double#NEGATIVE_INFINITY}. * * <p>If you only want to calculate the mean, use {#meanOf} instead of creating a {@link Stats} * instance. * * @throws IllegalStateException if the dataset is empty */
public double mean() { checkState(count != 0); return mean; }
Returns the sum of the values.

Non-finite values

If the dataset contains Double.NaN then the result is Double.NaN. If it contains both Double.POSITIVE_INFINITY and Double.NEGATIVE_INFINITY then the result is Double.NaN. If it contains Double.POSITIVE_INFINITY and finite values only or Double.POSITIVE_INFINITY only, the result is Double.POSITIVE_INFINITY. If it contains Double.NEGATIVE_INFINITY and finite values only or Double.NEGATIVE_INFINITY only, the result is Double.NEGATIVE_INFINITY.

/** * Returns the sum of the values. * * <h3>Non-finite values</h3> * * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it * contains both {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} then the * result is {@link Double#NaN}. If it contains {@link Double#POSITIVE_INFINITY} and finite values * only or {@link Double#POSITIVE_INFINITY} only, the result is {@link Double#POSITIVE_INFINITY}. * If it contains {@link Double#NEGATIVE_INFINITY} and finite values only or {@link * Double#NEGATIVE_INFINITY} only, the result is {@link Double#NEGATIVE_INFINITY}. */
public double sum() { return mean * count; }
Returns the population variance of the values. The count must be non-zero.

This is guaranteed to return zero if the dataset contains only exactly one finite value. It is not guaranteed to return zero when the dataset consists of the same value multiple times, due to numerical errors. However, it is guaranteed never to return a negative result.

Non-finite values

If the dataset contains any non-finite values (Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, or Double.NaN) then the result is Double.NaN.

Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Variance#Population_variance">population * variance</a> of the values. The count must be non-zero. * * <p>This is guaranteed to return zero if the dataset contains only exactly one finite value. It * is not guaranteed to return zero when the dataset consists of the same value multiple times, * due to numerical errors. However, it is guaranteed never to return a negative result. * * <h3>Non-finite values</h3> * * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. * * @throws IllegalStateException if the dataset is empty */
public double populationVariance() { checkState(count > 0); if (isNaN(sumOfSquaresOfDeltas)) { return NaN; } if (count == 1) { return 0.0; } return ensureNonNegative(sumOfSquaresOfDeltas) / count(); }
Returns the population standard deviation of the values. The count must be non-zero.

This is guaranteed to return zero if the dataset contains only exactly one finite value. It is not guaranteed to return zero when the dataset consists of the same value multiple times, due to numerical errors. However, it is guaranteed never to return a negative result.

Non-finite values

If the dataset contains any non-finite values (Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, or Double.NaN) then the result is Double.NaN.

Throws:
/** * Returns the <a * href="http://en.wikipedia.org/wiki/Standard_deviation#Definition_of_population_values"> * population standard deviation</a> of the values. The count must be non-zero. * * <p>This is guaranteed to return zero if the dataset contains only exactly one finite value. It * is not guaranteed to return zero when the dataset consists of the same value multiple times, * due to numerical errors. However, it is guaranteed never to return a negative result. * * <h3>Non-finite values</h3> * * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. * * @throws IllegalStateException if the dataset is empty */
public double populationStandardDeviation() { return Math.sqrt(populationVariance()); }
Returns the unbiased sample variance of the values. If this dataset is a sample drawn from a population, this is an unbiased estimator of the population variance of the population. The count must be greater than one.

This is not guaranteed to return zero when the dataset consists of the same value multiple times, due to numerical errors. However, it is guaranteed never to return a negative result.

Non-finite values

If the dataset contains any non-finite values (Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, or Double.NaN) then the result is Double.NaN.

Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Variance#Sample_variance">unbiased sample * variance</a> of the values. If this dataset is a sample drawn from a population, this is an * unbiased estimator of the population variance of the population. The count must be greater than * one. * * <p>This is not guaranteed to return zero when the dataset consists of the same value multiple * times, due to numerical errors. However, it is guaranteed never to return a negative result. * * <h3>Non-finite values</h3> * * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. * * @throws IllegalStateException if the dataset is empty or contains a single value */
public double sampleVariance() { checkState(count > 1); if (isNaN(sumOfSquaresOfDeltas)) { return NaN; } return ensureNonNegative(sumOfSquaresOfDeltas) / (count - 1); }
Returns the corrected sample standard deviation of the values. If this dataset is a sample drawn from a population, this is an estimator of the population standard deviation of the population which is less biased than populationStandardDeviation() (the unbiased estimator depends on the distribution). The count must be greater than one.

This is not guaranteed to return zero when the dataset consists of the same value multiple times, due to numerical errors. However, it is guaranteed never to return a negative result.

Non-finite values

If the dataset contains any non-finite values (Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, or Double.NaN) then the result is Double.NaN.

Throws:
/** * Returns the <a * href="http://en.wikipedia.org/wiki/Standard_deviation#Corrected_sample_standard_deviation"> * corrected sample standard deviation</a> of the values. If this dataset is a sample drawn from a * population, this is an estimator of the population standard deviation of the population which * is less biased than {@link #populationStandardDeviation()} (the unbiased estimator depends on * the distribution). The count must be greater than one. * * <p>This is not guaranteed to return zero when the dataset consists of the same value multiple * times, due to numerical errors. However, it is guaranteed never to return a negative result. * * <h3>Non-finite values</h3> * * <p>If the dataset contains any non-finite values ({@link Double#POSITIVE_INFINITY}, {@link * Double#NEGATIVE_INFINITY}, or {@link Double#NaN}) then the result is {@link Double#NaN}. * * @throws IllegalStateException if the dataset is empty or contains a single value */
public double sampleStandardDeviation() { return Math.sqrt(sampleVariance()); }
Returns the lowest value in the dataset. The count must be non-zero.

Non-finite values

If the dataset contains Double.NaN then the result is Double.NaN. If it contains Double.NEGATIVE_INFINITY and not Double.NaN then the result is Double.NEGATIVE_INFINITY. If it contains Double.POSITIVE_INFINITY and finite values only then the result is the lowest finite value. If it contains Double.POSITIVE_INFINITY only then the result is Double.POSITIVE_INFINITY.

Throws:
/** * Returns the lowest value in the dataset. The count must be non-zero. * * <h3>Non-finite values</h3> * * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it * contains {@link Double#NEGATIVE_INFINITY} and not {@link Double#NaN} then the result is {@link * Double#NEGATIVE_INFINITY}. If it contains {@link Double#POSITIVE_INFINITY} and finite values * only then the result is the lowest finite value. If it contains {@link * Double#POSITIVE_INFINITY} only then the result is {@link Double#POSITIVE_INFINITY}. * * @throws IllegalStateException if the dataset is empty */
public double min() { checkState(count != 0); return min; }
Returns the highest value in the dataset. The count must be non-zero.

Non-finite values

If the dataset contains Double.NaN then the result is Double.NaN. If it contains Double.POSITIVE_INFINITY and not Double.NaN then the result is Double.POSITIVE_INFINITY. If it contains Double.NEGATIVE_INFINITY and finite values only then the result is the highest finite value. If it contains Double.NEGATIVE_INFINITY only then the result is Double.NEGATIVE_INFINITY.

Throws:
/** * Returns the highest value in the dataset. The count must be non-zero. * * <h3>Non-finite values</h3> * * <p>If the dataset contains {@link Double#NaN} then the result is {@link Double#NaN}. If it * contains {@link Double#POSITIVE_INFINITY} and not {@link Double#NaN} then the result is {@link * Double#POSITIVE_INFINITY}. If it contains {@link Double#NEGATIVE_INFINITY} and finite values * only then the result is the highest finite value. If it contains {@link * Double#NEGATIVE_INFINITY} only then the result is {@link Double#NEGATIVE_INFINITY}. * * @throws IllegalStateException if the dataset is empty */
public double max() { checkState(count != 0); return max; }
{@inheritDoc}

Note: This tests exact equality of the calculated statistics, including the floating point values. Two instances are guaranteed to be considered equal if one is copied from the other using second = new StatsAccumulator().addAll(first).snapshot(), if both were obtained by calling snapshot() on the same StatsAccumulator without adding any values in between the two calls, or if one is obtained from the other after round-tripping through java serialization. However, floating point rounding errors mean that it may be false for some instances where the statistics are mathematically equal, including instances constructed from the same values in a different order... or (in the general case) even in the same order. (It is guaranteed to return true for instances constructed from the same values in the same order if strictfp is in effect, or if the system architecture guarantees strictfp-like semantics.)

/** * {@inheritDoc} * * <p><b>Note:</b> This tests exact equality of the calculated statistics, including the floating * point values. Two instances are guaranteed to be considered equal if one is copied from the * other using {@code second = new StatsAccumulator().addAll(first).snapshot()}, if both were * obtained by calling {@code snapshot()} on the same {@link StatsAccumulator} without adding any * values in between the two calls, or if one is obtained from the other after round-tripping * through java serialization. However, floating point rounding errors mean that it may be false * for some instances where the statistics are mathematically equal, including instances * constructed from the same values in a different order... or (in the general case) even in the * same order. (It is guaranteed to return true for instances constructed from the same values in * the same order if {@code strictfp} is in effect, or if the system architecture guarantees * {@code strictfp}-like semantics.) */
@Override public boolean equals(@Nullable Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Stats other = (Stats) obj; return (count == other.count) && (doubleToLongBits(mean) == doubleToLongBits(other.mean)) && (doubleToLongBits(sumOfSquaresOfDeltas) == doubleToLongBits(other.sumOfSquaresOfDeltas)) && (doubleToLongBits(min) == doubleToLongBits(other.min)) && (doubleToLongBits(max) == doubleToLongBits(other.max)); }
{@inheritDoc}

Note: This hash code is consistent with exact equality of the calculated statistics, including the floating point values. See the note on equals for details.

/** * {@inheritDoc} * * <p><b>Note:</b> This hash code is consistent with exact equality of the calculated statistics, * including the floating point values. See the note on {@link #equals} for details. */
@Override public int hashCode() { return Objects.hashCode(count, mean, sumOfSquaresOfDeltas, min, max); } @Override public String toString() { if (count() > 0) { return MoreObjects.toStringHelper(this) .add("count", count) .add("mean", mean) .add("populationStandardDeviation", populationStandardDeviation()) .add("min", min) .add("max", max) .toString(); } else { return MoreObjects.toStringHelper(this).add("count", count).toString(); } } double sumOfSquaresOfDeltas() { return sumOfSquaresOfDeltas; }
Returns the arithmetic mean of the values. The count must be non-zero.

The definition of the mean is the same as mean.

Params:
  • values – a series of values, which will be converted to double values (this may cause loss of precision)
Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision) * @throws IllegalArgumentException if the dataset is empty */
public static double meanOf(Iterable<? extends Number> values) { return meanOf(values.iterator()); }
Returns the arithmetic mean of the values. The count must be non-zero.

The definition of the mean is the same as mean.

Params:
  • values – a series of values, which will be converted to double values (this may cause loss of precision)
Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision) * @throws IllegalArgumentException if the dataset is empty */
public static double meanOf(Iterator<? extends Number> values) { checkArgument(values.hasNext()); long count = 1; double mean = values.next().doubleValue(); while (values.hasNext()) { double value = values.next().doubleValue(); count++; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / count; } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
Returns the arithmetic mean of the values. The count must be non-zero.

The definition of the mean is the same as mean.

Params:
  • values – a series of values
Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values * @throws IllegalArgumentException if the dataset is empty */
public static double meanOf(double... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
Returns the arithmetic mean of the values. The count must be non-zero.

The definition of the mean is the same as mean.

Params:
  • values – a series of values
Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values * @throws IllegalArgumentException if the dataset is empty */
public static double meanOf(int... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; }
Returns the arithmetic mean of the values. The count must be non-zero.

The definition of the mean is the same as mean.

Params:
  • values – a series of values, which will be converted to double values (this may cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15))
Throws:
/** * Returns the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic mean</a> of the * values. The count must be non-zero. * * <p>The definition of the mean is the same as {@link Stats#mean}. * * @param values a series of values, which will be converted to {@code double} values (this may * cause loss of precision for longs of magnitude over 2^53 (slightly over 9e15)) * @throws IllegalArgumentException if the dataset is empty */
public static double meanOf(long... values) { checkArgument(values.length > 0); double mean = values[0]; for (int index = 1; index < values.length; index++) { double value = values[index]; if (isFinite(value) && isFinite(mean)) { // Art of Computer Programming vol. 2, Knuth, 4.2.2, (15) mean += (value - mean) / (index + 1); } else { mean = calculateNewMeanNonFinite(mean, value); } } return mean; } // Serialization helpers
The size of byte array representation in bytes.
/** The size of byte array representation in bytes. */
static final int BYTES = (Long.SIZE + Double.SIZE * 4) / Byte.SIZE;
Gets a byte array representation of this instance.

Note: No guarantees are made regarding stability of the representation between versions.

/** * Gets a byte array representation of this instance. * * <p><b>Note:</b> No guarantees are made regarding stability of the representation between * versions. */
public byte[] toByteArray() { ByteBuffer buff = ByteBuffer.allocate(BYTES).order(ByteOrder.LITTLE_ENDIAN); writeTo(buff); return buff.array(); }
Writes to the given ByteBuffer a byte representation of this instance.

Note: No guarantees are made regarding stability of the representation between versions.

Params:
/** * Writes to the given {@link ByteBuffer} a byte representation of this instance. * * <p><b>Note:</b> No guarantees are made regarding stability of the representation between * versions. * * @param buffer A {@link ByteBuffer} with at least BYTES {@link ByteBuffer#remaining}, ordered as * {@link ByteOrder#LITTLE_ENDIAN}, to which a BYTES-long byte representation of this instance * is written. In the process increases the position of {@link ByteBuffer} by BYTES. */
void writeTo(ByteBuffer buffer) { checkNotNull(buffer); checkArgument( buffer.remaining() >= BYTES, "Expected at least Stats.BYTES = %s remaining , got %s", BYTES, buffer.remaining()); buffer .putLong(count) .putDouble(mean) .putDouble(sumOfSquaresOfDeltas) .putDouble(min) .putDouble(max); }
Creates a Stats instance from the given byte representation which was obtained by toByteArray.

Note: No guarantees are made regarding stability of the representation between versions.

/** * Creates a Stats instance from the given byte representation which was obtained by {@link * #toByteArray}. * * <p><b>Note:</b> No guarantees are made regarding stability of the representation between * versions. */
public static Stats fromByteArray(byte[] byteArray) { checkNotNull(byteArray); checkArgument( byteArray.length == BYTES, "Expected Stats.BYTES = %s remaining , got %s", BYTES, byteArray.length); return readFrom(ByteBuffer.wrap(byteArray).order(ByteOrder.LITTLE_ENDIAN)); }
Creates a Stats instance from the byte representation read from the given ByteBuffer.

Note: No guarantees are made regarding stability of the representation between versions.

Params:
/** * Creates a Stats instance from the byte representation read from the given {@link ByteBuffer}. * * <p><b>Note:</b> No guarantees are made regarding stability of the representation between * versions. * * @param buffer A {@link ByteBuffer} with at least BYTES {@link ByteBuffer#remaining}, ordered as * {@link ByteOrder#LITTLE_ENDIAN}, from which a BYTES-long byte representation of this * instance is read. In the process increases the position of {@link ByteBuffer} by BYTES. */
static Stats readFrom(ByteBuffer buffer) { checkNotNull(buffer); checkArgument( buffer.remaining() >= BYTES, "Expected at least Stats.BYTES = %s remaining , got %s", BYTES, buffer.remaining()); return new Stats( buffer.getLong(), buffer.getDouble(), buffer.getDouble(), buffer.getDouble(), buffer.getDouble()); } private static final long serialVersionUID = 0; }