/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.measure.quantity.Quantity;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;
/**
* This class represents the result of a measurement stated in a
* known unit.
*
* There is no constraint upon the measurement value itself: scalars,
* vectors, or even data sets are valid values as long as
* an aggregate magnitude can be determined (see {@link Measurable}).
*
* @author Jean-Marie Dautelle
* @version 4.2, August 26, 2007
*/
public abstract class Measure implements Measurable,
Serializable {
/**
* Default constructor.
*/
protected Measure() {
}
/**
* Returns the scalar measure for the specified double
* stated in the specified unit.
*
* @param doubleValue the measurement value.
* @param unit the measurement unit.
*/
public static Measure valueOf(
double doubleValue, Unit unit) {
return new Double(doubleValue, unit);
}
/**
* Returns the scalar measure for the specified double
* stated in the specified unit.
*
* @param longValue the measurement value.
* @param unit the measurement unit.
*/
public static Measure valueOf(
long longValue, Unit unit) {
return new Long(longValue, unit);
}
/**
* Returns the scalar measure for the specified float
* stated in the specified unit.
*
* @param floatValue the measurement value.
* @param unit the measurement unit.
*/
public static Measure valueOf(
float floatValue, Unit unit) {
return new Float(floatValue, unit);
}
/**
* Returns the scalar measure for the specified int
* stated in the specified unit.
*
* @param intValue the measurement value.
* @param unit the measurement unit.
*/
public static Measure valueOf(
int intValue, Unit unit) {
return new Integer(intValue, unit);
}
/**
* Returns the measurement value of this measure.
*
* @return the measurement value.
*/
public abstract V getValue();
/**
* Returns the measurement unit of this measure.
*
* @return the measurement unit.
*/
public abstract Unit getUnit();
/**
* Returns the measure equivalent to this measure but stated in the
* specified unit. This method may result in lost of precision
* (e.g. measure of integral value).
*
* @param unit the new measurement unit.
* @return the measure stated in the specified unit.
*/
public abstract Measure to(Unit unit);
/**
* Returns the value of this measure stated in the specified unit as
* a double. If the measure has too great a magnitude to
* be represented as a double, it will be converted to
* Double.NEGATIVE_INFINITY or
* Double.POSITIVE_INFINITY as appropriate.
*
* @param unit the unit in which this measure is stated.
* @return the numeric value after conversion to type double.
*/
public abstract double doubleValue(Unit unit);
/**
* Returns the estimated integral value of this measure stated in
* the specified unit as a long.
*
* Note: This method differs from the Number.longValue()
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type long.
* @throws ArithmeticException if this quantity cannot be represented
* as a long number in the specified unit.
*/
public long longValue(Unit unit) throws ArithmeticException {
double doubleValue = doubleValue(unit);
if (java.lang.Double.isNaN(doubleValue)
|| (doubleValue < java.lang.Long.MIN_VALUE)
|| (doubleValue > java.lang.Long.MAX_VALUE))
throw new ArithmeticException(doubleValue + " " + unit
+ " cannot be represented as long");
return Math.round(doubleValue);
}
/**
* Returns the value of this measure stated in the specified unit as a
* float. If the measure has too great a magnitude to be
* represented as a float, it will be converted to
* Float.NEGATIVE_INFINITY or
* Float.POSITIVE_INFINITY as appropriate.
*
* @param unit the unit in which the measure is stated.
* @return the numeric value after conversion to type float.
*/
public float floatValue(Unit unit) {
return (float) doubleValue(unit);
}
/**
* Returns the estimated integral value of this measure stated in
* the specified unit as a int.
*
* Note: This method differs from the Number.intValue()
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type int.
* @throws ArithmeticException if this quantity cannot be represented
* as a int number in the specified unit.
*/
public int intValue(Unit unit) {
long longValue = longValue(unit);
if ((longValue > java.lang.Integer.MAX_VALUE)
|| (longValue < java.lang.Integer.MIN_VALUE))
throw new ArithmeticException("Overflow");
return (int) longValue;
}
/**
* Compares this measure against the specified object for
* strict equality (same unit and amount).
* To compare measures stated using different units the
* {@link #compareTo} method should be used.
*
* @param obj the object to compare with.
* @return true if both objects are identical (same
* unit and same amount); false otherwise.
*/
@SuppressWarnings("unchecked")
public boolean equals(Object obj) {
if (!(obj instanceof Measure))
return false;
Measure that = (Measure) obj;
return this.getUnit().equals(that.getUnit())
&& this.getValue().equals(that.getValue());
}
/**
* Returns the hash code for this scalar.
*
* @return the hash code value.
*/
public int hashCode() {
return getUnit().hashCode() + getValue().hashCode();
}
/**
* Returns the String representation of this measure
* The string produced for a given measure is always the same;
* it is not affected by locale. This means that it can be used
* as a canonical string representation for exchanging data,
* or as a key for a Hashtable, etc. Locale-sensitive
* measure formatting and parsing is handled by the {@link
* MeasureFormat} class and its subclasses.
*
* @return the string representation of this measure.
*/
public String toString() {
if (getUnit() instanceof CompoundUnit)
return MeasureFormat.DEFAULT.formatCompound(doubleValue(getUnit()),
getUnit(), new StringBuffer(), null).toString();
return getValue() + " " + getUnit();
}
/**
* Compares this measure to the specified measurable quantity.
* This method compares the {@link Measurable#doubleValue(Unit)} of
* both this measure and the specified measurable stated in the
* same unit (this measure's {@link #getUnit() unit}).
*
* @return a negative integer, zero, or a positive integer as this measure
* is less than, equal to, or greater than the specified measurable
* quantity.
* @return Double.compare(this.doubleValue(getUnit()),
* that.doubleValue(getUnit()))
*/
public int compareTo(Measurable that) {
return java.lang.Double.compare(doubleValue(getUnit()), that
.doubleValue(getUnit()));
}
/**
* Holds scalar implementation for double values.
*/
private static final class Double extends
Measure {
private final double _value;
private final Unit _unit;
public Double(double value, Unit unit) {
_value = value;
_unit = unit;
}
@Override
public Unit getUnit() {
return _unit;
}
@Override
public java.lang.Double getValue() {
return _value;
}
@Override
public Measure to(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Double(doubleValue(unit), unit);
}
public double doubleValue(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for long values.
*/
private static final class Long extends
Measure {
private final long _value;
private final Unit _unit;
public Long(long value, Unit unit) {
_value = value;
_unit = unit;
}
@Override
public Unit getUnit() {
return _unit;
}
@Override
public java.lang.Long getValue() {
return _value;
}
@Override
public Measure to(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Long(longValue(unit), unit);
}
public double doubleValue(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
public long longValue(Unit unit) throws ArithmeticException {
if ((unit == _unit) || (unit.equals(_unit)))
return _value; // No conversion, returns value directly.
return super.longValue(unit);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for float values.
*/
private static final class Float extends
Measure {
private final float _value;
private final Unit _unit;
public Float(float value, Unit unit) {
_value = value;
_unit = unit;
}
@Override
public Unit getUnit() {
return _unit;
}
@Override
public java.lang.Float getValue() {
return _value;
}
@Override
public Measure to(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Float(floatValue(unit), unit);
}
public double doubleValue(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for long values.
*/
private static final class Integer extends
Measure {
private final int _value;
private final Unit _unit;
public Integer(int value, Unit unit) {
_value = value;
_unit = unit;
}
@Override
public Unit getUnit() {
return _unit;
}
@Override
public java.lang.Integer getValue() {
return _value;
}
@Override
public Measure to(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Integer(intValue(unit), unit);
}
public double doubleValue(Unit unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
public long longValue(Unit unit) throws ArithmeticException {
if ((unit == _unit) || (unit.equals(_unit)))
return _value; // No conversion, returns value directly.
return super.longValue(unit);
}
private static final long serialVersionUID = 1L;
}
/**
* @deprecated {@link DecimalMeasure} should be used directly.
*/
public static Measure valueOf(
BigDecimal decimal, Unit unit) {
return DecimalMeasure.valueOf(decimal, unit);
}
/**
* @deprecated {@link DecimalMeasure} should be used directly and
* MathContext specified explicitly when
* {@link DecimalMeasure#to(Unit, MathContext) converting}.
*/
public static Measure valueOf(
BigDecimal decimal, Unit unit, MathContext mathContext) {
return DecimalMeasure.valueOf(decimal, unit);
}
/**
* @deprecated {@link VectorMeasure} should be used directly.
*/
public static Measure valueOf(
double[] components, Unit unit) {
return VectorMeasure.valueOf(components, unit);
}
}
Ads help maintain this website.