ucar.units.DerivedUnitImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package ucar.units;
/**
* Provides support for a concrete implementation of derived units.
*
* @author Steven R. Emmerson
*/
// @Immutable
public class DerivedUnitImpl extends UnitImpl implements DerivedUnit, DerivableUnit {
private static final long serialVersionUID = 1L;
/**
* The dimensionless derived unit.
*/
public static final DerivedUnitImpl DIMENSIONLESS = new DerivedUnitImpl();
/**
* The dimension of this derived unit.
*
* @serial
*/
private /* final */ UnitDimension dimension;
/**
* Constructs a dimensionless derived unit from nothing.
*/
protected DerivedUnitImpl() {
// dimensionless derived unit
this(new UnitDimension(), dimensionlessID());
}
/**
* Returns the identifiers associated with the dimensionless, derived unit.
*
* @return The identifiers of the dimensionless, derived unit.
*/
private static UnitName dimensionlessID() {
UnitName id;
try {
id = UnitName.newUnitName("1", "1", "1");
} catch (final NameException e) {
id = null;
}
return id;
}
/**
* Constructs from a unit dimension. This is a trusted constructor for use
* by subclasses only.
*
* @param dimension
* The unit dimension.
*/
protected DerivedUnitImpl(final UnitDimension dimension) {
this(dimension, null);
}
/**
* Constructs from identifiers. This is a trusted constructor for use by
* subclasses only.
*
* @param id
* The identifiers for the unit.
*/
protected DerivedUnitImpl(final UnitName id) {
this(null, id);
}
/**
* Constructs from a unit dimension and identifiers. This is a trusted
* constructor for use by subclasses only.
*
* @param dimension
* The unit dimension.
* @param id
* The identifiers for the unit.
*/
protected DerivedUnitImpl(final UnitDimension dimension, final UnitName id) {
super(id);
this.dimension = dimension;
}
/**
* Sets the unit dimension of this derived unit. This is a trusted method
* for use by subclasses only and should be called only once immediately
* after construction of this superinstance.
*
* @param dimension
* The unit dimension.
*/
protected void setDimension(final UnitDimension dimension) {
this.dimension = dimension;
}
/**
* Returns the unit dimension of this derived unit.
*
* @return The unit dimension of this derived unit.
*/
public final UnitDimension getDimension() {
return dimension;
}
/**
* Returns the quantity dimension of this derived unit.
*
* @return The quantity dimension of this derived unit.
*/
public final QuantityDimension getQuantityDimension() {
return getDimension().getQuantityDimension();
}
/*
* From DerivedUnit:
*/
/**
* Indicates if this derived unit is the reciprocal of another derived unit
* (e.g. "second" and "hertz").
*
* @param that
* The other, derived unit.
*/
public final boolean isReciprocalOf(final DerivedUnit that) {
return dimension.isReciprocalOf(that.getDimension());
}
/*
* From UnitImpl:
*/
/**
* Returns the derived unit that is convertible with this unit. Obviously,
* the method returns this derived unit.
*
* @return this
.
*/
public final DerivedUnit getDerivedUnit() {
return this;
}
/**
* Clones the derived unit changing the identifiers.
*
* @param id
* The identifiers for the new unit.
* @return The new unit.
*/
public final Unit clone(final UnitName id) {
return new DerivedUnitImpl(dimension, id);
}
/**
* Multiplies this derived unit by another.
*
* @param that
* The other unit.
* @return The product of the two units.
* @throws MultiplyException
* Can't multiply these units.
*/
@Override
protected Unit myMultiplyBy(final Unit that) throws MultiplyException {
Unit result;
if (dimension.getRank() == 0) {
result = that;
} else {
if (!(that instanceof DerivedUnit)) {
result = that.multiplyBy(this);
} else {
final UnitDimension thatDimension = ((DerivedUnit) that).getDimension();
result = thatDimension.getRank() == 0 ? this : new DerivedUnitImpl(dimension.multiplyBy(thatDimension));
}
}
return result;
}
/**
* Divides this derived unit by another.
*
* @param that
* The other unit.
* @return The quotient of the two units.
* @throws OperationException
* Can't divide these units.
*/
@Override
protected Unit myDivideBy(final Unit that) throws OperationException {
Unit result;
if (dimension.getRank() == 0) {
result = that.raiseTo(-1);
} else {
if (!(that instanceof DerivedUnit)) {
result = that.divideInto(this);
} else {
final UnitDimension thatDimension = ((DerivedUnit) that).getDimension();
result = thatDimension.getRank() == 0 ? this : new DerivedUnitImpl(dimension.divideBy(thatDimension));
}
}
return result;
}
/**
* Divides this derived unit into another.
*
* @param that
* The other unit.
* @return The quotient of the two units.
* @throws OperationException
* Can't divide these units.
*/
@Override
protected Unit myDivideInto(final Unit that) throws OperationException {
return that.divideBy(this);
}
/**
* Raises this derived unit to a power.
*
* @param power
* The power.
* @return This derived unit raised to the given power.
*/
@Override
protected Unit myRaiseTo(final int power) {
return power == 1 ? this : new DerivedUnitImpl(dimension.raiseTo(power));
}
/**
* Converts a numerical value from this unit to the derived unit. Obviously,
* the numerical value is unchanged.
*
* @param amount
* The numerical values in this unit.
* @return The numerical value in the derived unit.
*/
public final float toDerivedUnit(final float amount) {
return amount;
}
/**
* Converts a numerical value from this unit to the derived unit. Obviously,
* the numerical value is unchanged.
*
* @param amount
* The numerical values in this unit.
* @return The numerical value in the derived unit.
*/
public final double toDerivedUnit(final double amount) {
return amount;
}
/**
* Converts numerical values from this unit to the derived unit. Obviously,
* the numerical values are unchanged.
*
* @param input
* The numerical values in this unit.
* @param output
* The numerical values in the derived unit. May be the same
* array as input
.
* @return output
.
*/
public final float[] toDerivedUnit(final float[] input, final float[] output) {
if (input != output) {
System.arraycopy(input, 0, output, 0, input.length);
}
return output;
}
/**
* Converts numerical values from this unit to the derived unit. Obviously,
* the numerical values are unchanged.
*
* @param input
* The numerical values in this unit.
* @param output
* The numerical values in the derived unit. May be the same
* array as input
.
* @return output
.
*/
public final double[] toDerivedUnit(final double[] input, final double[] output) {
if (input != output) {
System.arraycopy(input, 0, output, 0, input.length);
}
return output;
}
/**
* Converts a numerical value to this unit from the derived unit. Obviously,
* the numerical value is unchanged.
*
* @param amount
* The numerical values in the derived unit.
* @return The numerical value in this unit.
*/
public final float fromDerivedUnit(final float amount) {
return amount;
}
/**
* Converts a numerical value to this unit from the derived unit. Obviously,
* the numerical value is unchanged.
*
* @param amount
* The numerical values in the derived unit.
* @return The numerical value in this unit.
*/
public final double fromDerivedUnit(final double amount) {
return amount;
}
/**
* Converts numerical values to this unit from the derived unit. Obviously,
* the numerical values are unchanged.
*
* @param input
* The numerical values in the derived unit.
* @param output
* The numerical values in this unit. May be the same array as
* input
.
* @return output
.
*/
public final float[] fromDerivedUnit(final float[] input, final float[] output) {
return toDerivedUnit(input, output);
}
/**
* Converts numerical values to this unit from the derived unit. Obviously,
* the numerical values are unchanged.
*
* @param input
* The numerical values in the derived unit.
* @param output
* The numerical values in this unit. May be the same array as
* input
.
* @return output
.
*/
public final double[] fromDerivedUnit(final double[] input, final double[] output) {
return toDerivedUnit(input, output);
}
/**
* Indicates if values in this unit are convertible with another unit.
*
* @param that
* The other unit.
* @return true
if and only if values in this unit are
* convertible to values in
* that
.
*/
@Override
public final boolean isCompatible(final Unit that) {
final DerivedUnit unit = that.getDerivedUnit();
return equals(unit) || isReciprocalOf(unit);
}
/**
* Indicates if this derived unit is semantically identical to an object.
*
* @param object
* The object
* @return true
if and only if this derived unit is
* semantically identical to
* object
.
*/
@Override
public boolean equals(final Object object) {
if (this == object) {
return true;
}
if (!(object instanceof DerivedUnit)) {
return false;
}
final DerivedUnit that = (DerivedUnit) object;
return (!(this instanceof BaseUnit) || !(that instanceof BaseUnit)) && dimension.equals(that.getDimension());
}
/**
* Returns the hash code of this instance.
*
* @return The hash code of this instance.
*/
@Override
public int hashCode() {
return this instanceof BaseUnit ? System.identityHashCode(this) : dimension.hashCode();
}
/**
* Indicates if this derived unit is dimensionless.
*
* @return true
if and only if this derived unit is
* dimensionless.
*/
public boolean isDimensionless() {
return dimension.isDimensionless();
}
/**
* Returns a string representation of this unit. If the symbol or name is
* available, then that is returned; otherwise, the corresponding expression
* in base units is returned.
*
* @return The string expression for this derived unit.
*/
@Override
public String toString() {
final String string = super.toString(); // get symbol or name
return string != null ? string : getCanonicalString();
}
/**
* Returns the canonical string representation of the unit.
*
* @return The canonical string representation.
*/
public String getCanonicalString() {
return dimension.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy