diff options
Diffstat (limited to 'src/org/unitConverter/unit/LinearUnit.java')
-rw-r--r-- | src/org/unitConverter/unit/LinearUnit.java | 166 |
1 files changed, 80 insertions, 86 deletions
diff --git a/src/org/unitConverter/unit/LinearUnit.java b/src/org/unitConverter/unit/LinearUnit.java index 1b1ac97..c397250 100644 --- a/src/org/unitConverter/unit/LinearUnit.java +++ b/src/org/unitConverter/unit/LinearUnit.java @@ -18,73 +18,78 @@ package org.unitConverter.unit; import java.util.Objects; -import org.unitConverter.dimension.UnitDimension; import org.unitConverter.math.DecimalComparison; +import org.unitConverter.math.ObjectProduct; /** - * A unit that is equal to a certain number multiplied by its base. - * <p> - * {@code LinearUnit} does not have any public constructors or static factories. In order to obtain a {@code LinearUnit} - * instance, multiply its base by the conversion factor. Example: - * - * <pre> - * LinearUnit foot = METRE.times(0.3048); - * </pre> - * - * (where {@code METRE} is a {@code BaseUnit} instance) - * </p> + * A unit that can be expressed as a product of its base and a number. For example, kilometres, inches and pounds. * * @author Adrien Hopkins - * @since 2018-12-22 - * @since v0.1.0 + * @since 2019-10-16 */ -public class LinearUnit extends AbstractUnit { +public final class LinearUnit extends Unit { /** - * The value of one of this unit in this unit's base unit + * Gets a {@code LinearUnit} from a unit and a value. For example, converts '59 °F' to a linear unit with the value + * of '288.15 K' * - * @since 2018-12-22 - * @since v0.1.0 + * @param unit + * unit to convert + * @param value + * value to convert + * @return value expressed as a {@code LinearUnit} + * @since 2019-10-16 */ - private final double conversionFactor; + public static LinearUnit fromUnitValue(final Unit unit, final double value) { + return new LinearUnit(unit.getBase(), unit.convertToBase(value)); + } /** + * Gets a {@code LinearUnit} from a unit base and a conversion factor. In other words, gets the product of + * {@code unitBase} and {@code conversionFactor}, expressed as a {@code LinearUnit}. * - * Creates the {@code LinearUnit}. - * - * @param base - * unit's base + * @param unitBase + * unit base to multiply by * @param conversionFactor - * value of one of this unit in its base - * @since 2018-12-23 - * @since v0.1.0 + * number to multiply base by + * @return product of base and conversion factor + * @since 2019-10-16 */ - LinearUnit(final BaseUnit base, final double conversionFactor) { - super(base); - this.conversionFactor = conversionFactor; + public static LinearUnit valueOf(final ObjectProduct<BaseUnit> unitBase, final double conversionFactor) { + return new LinearUnit(unitBase, conversionFactor); } /** - * Creates the {@code LinearUnit} as a base unit. + * The value of this unit as represented in its base form. Mathematically, * - * @param dimension - * dimension measured by unit - * @param system - * system unit is part of - * @since 2019-01-25 - * @since v0.1.0 + * <pre> + * this = conversionFactor * getBase() + * </pre> + * + * @since 2019-10-16 + */ + private final double conversionFactor; + + /** + * Creates the {@code LinearUnit}. + * + * @param unitBase + * base of linear unit + * @param conversionFactor + * conversion factor between base and unit + * @since 2019-10-16 */ - LinearUnit(final UnitDimension dimension, final UnitSystem system, final double conversionFactor) { - super(dimension, system); + private LinearUnit(final ObjectProduct<BaseUnit> unitBase, final double conversionFactor) { + super(unitBase); this.conversionFactor = conversionFactor; } @Override - public double convertFromBase(final double value) { + protected double convertFromBase(final double value) { return value / this.getConversionFactor(); } @Override - public double convertToBase(final double value) { + protected double convertToBase(final double value) { return value * this.getConversionFactor(); } @@ -98,21 +103,15 @@ public class LinearUnit extends AbstractUnit { * @since v0.1.0 */ public LinearUnit dividedBy(final double divisor) { - return new LinearUnit(this.getBase(), this.getConversionFactor() / divisor); + return valueOf(this.getBase(), this.getConversionFactor() / divisor); } /** * Returns the quotient of this unit and another. - * <p> - * Two units can be divided if they are part of the same unit system. If {@code divisor} does not meet this - * condition, an {@code IllegalArgumentException} should be thrown. - * </p> * * @param divisor * unit to divide by * @return quotient of two units - * @throws IllegalArgumentException - * if {@code divisor} is not compatible for division as described above * @throws NullPointerException * if {@code divisor} is null * @since 2018-12-22 @@ -121,14 +120,9 @@ public class LinearUnit extends AbstractUnit { public LinearUnit dividedBy(final LinearUnit divisor) { Objects.requireNonNull(divisor, "other must not be null"); - // check that these units can be multiplied - if (!this.getSystem().equals(divisor.getSystem())) - throw new IllegalArgumentException( - String.format("Incompatible units for division \"%s\" and \"%s\".", this, divisor)); - // divide the units - final BaseUnit base = this.getBase().dividedBy(divisor.getBase()); - return new LinearUnit(base, this.getConversionFactor() / divisor.getConversionFactor()); + final ObjectProduct<BaseUnit> base = this.getBase().dividedBy(divisor.getBase()); + return valueOf(base, this.getConversionFactor() / divisor.getConversionFactor()); } @Override @@ -136,28 +130,38 @@ public class LinearUnit extends AbstractUnit { if (!(obj instanceof LinearUnit)) return false; final LinearUnit other = (LinearUnit) obj; - return Objects.equals(this.getSystem(), other.getSystem()) - && Objects.equals(this.getDimension(), other.getDimension()) + return Objects.equals(this.getBase(), other.getBase()) && DecimalComparison.equals(this.getConversionFactor(), other.getConversionFactor()); } /** - * @return conversion factor between this unit and its base - * @since 2018-12-22 - * @since v0.1.0 + * @return conversion factor + * @since 2019-10-16 */ - public final double getConversionFactor() { + public double getConversionFactor() { return this.conversionFactor; } @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = result * prime + this.getSystem().hashCode(); - result = result * prime + this.getDimension().hashCode(); - result = result * prime + Double.hashCode(this.getConversionFactor()); - return result; + return 31 * this.getBase().hashCode() + DecimalComparison.hash(this.getConversionFactor()); + } + + /** + * @return whether this unit is equivalent to a {@code BaseUnit} (i.e. there is a {@code BaseUnit b} where + * {@code b.asLinearUnit().equals(this)} returns {@code true}.) + * @since 2019-10-16 + */ + public boolean isBase() { + return this.isCoherent() && this.getBase().isSingleObject(); + } + + /** + * @return whether this unit is coherent (i.e. has conversion factor 1) + * @since 2019-10-16 + */ + public boolean isCoherent() { + return this.getConversionFactor() == 1; } /** @@ -186,7 +190,7 @@ public class LinearUnit extends AbstractUnit { String.format("Incompatible units for subtraction \"%s\" and \"%s\".", this, subtrahendend)); // add the units - return new LinearUnit(this.getBase(), this.getConversionFactor() - subtrahendend.getConversionFactor()); + return valueOf(this.getBase(), this.getConversionFactor() - subtrahendend.getConversionFactor()); } /** @@ -215,7 +219,7 @@ public class LinearUnit extends AbstractUnit { String.format("Incompatible units for addition \"%s\" and \"%s\".", this, addend)); // add the units - return new LinearUnit(this.getBase(), this.getConversionFactor() + addend.getConversionFactor()); + return valueOf(this.getBase(), this.getConversionFactor() + addend.getConversionFactor()); } /** @@ -228,21 +232,15 @@ public class LinearUnit extends AbstractUnit { * @since v0.1.0 */ public LinearUnit times(final double multiplier) { - return new LinearUnit(this.getBase(), this.getConversionFactor() * multiplier); + return valueOf(this.getBase(), this.getConversionFactor() * multiplier); } /** * Returns the product of this unit and another. - * <p> - * Two units can be multiplied if they are part of the same unit system. If {@code multiplier} does not meet this - * condition, an {@code IllegalArgumentException} should be thrown. - * </p> * * @param multiplier * unit to multiply by * @return product of two units - * @throws IllegalArgumentException - * if {@code multiplier} is not compatible for multiplication as described above * @throws NullPointerException * if {@code multiplier} is null * @since 2018-12-22 @@ -251,32 +249,28 @@ public class LinearUnit extends AbstractUnit { public LinearUnit times(final LinearUnit multiplier) { Objects.requireNonNull(multiplier, "other must not be null"); - // check that these units can be multiplied - if (!this.getSystem().equals(multiplier.getSystem())) - throw new IllegalArgumentException( - String.format("Incompatible units for multiplication \"%s\" and \"%s\".", this, multiplier)); - // multiply the units - final BaseUnit base = this.getBase().times(multiplier.getBase()); - return new LinearUnit(base, this.getConversionFactor() * multiplier.getConversionFactor()); + final ObjectProduct<BaseUnit> base = this.getBase().times(multiplier.getBase()); + return valueOf(base, this.getConversionFactor() * multiplier.getConversionFactor()); } /** * Returns this unit but to an exponent. * * @param exponent - * exponent to exponientate unit to - * @return exponientated unit + * exponent to exponentiate unit to + * @return exponentiated unit * @since 2019-01-15 * @since v0.1.0 */ public LinearUnit toExponent(final int exponent) { - return new LinearUnit(this.getBase().toExponent(exponent), Math.pow(this.conversionFactor, exponent)); + return valueOf(this.getBase().toExponent(exponent), Math.pow(this.conversionFactor, exponent)); } + // returns a definition of the unit @Override public String toString() { - return super.toString() + String.format(" (equal to %s * base)", this.getConversionFactor()); + return Double.toString(this.conversionFactor) + " * " + this.getBase().toString(BaseUnit::getSymbol); } /** |