diff options
author | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2019-03-22 17:00:58 -0400 |
---|---|---|
committer | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2019-03-22 17:00:58 -0400 |
commit | 943496888d18b031be19ba8e7348ec188dc8eb6b (patch) | |
tree | 03b440bf7d7789be5fd88b8ce3785f900804c773 /src/org/unitConverter/unit/LinearUnit.java | |
parent | ea940f2c5b6450231ff9ce61f4b6704babdb0d9e (diff) |
Made BaseUnit a subclass of LinearUnit and made an expression parser
Diffstat (limited to 'src/org/unitConverter/unit/LinearUnit.java')
-rw-r--r-- | src/org/unitConverter/unit/LinearUnit.java | 164 |
1 files changed, 103 insertions, 61 deletions
diff --git a/src/org/unitConverter/unit/LinearUnit.java b/src/org/unitConverter/unit/LinearUnit.java index 64eff1f..c755f79 100644 --- a/src/org/unitConverter/unit/LinearUnit.java +++ b/src/org/unitConverter/unit/LinearUnit.java @@ -19,6 +19,7 @@ package org.unitConverter.unit; import java.util.Objects; import org.unitConverter.dimension.UnitDimension; +import org.unitConverter.math.DecimalComparison; /** * A unit that is equal to a certain number multiplied by its base. @@ -27,7 +28,7 @@ import org.unitConverter.dimension.UnitDimension; * @since 2018-12-22 * @since v0.1.0 */ -public final class LinearUnit extends AbstractUnit implements OperatableUnit { +public class LinearUnit extends AbstractUnit { /** * The value of one of this unit in this unit's base unit * @@ -91,20 +92,33 @@ public final class LinearUnit extends AbstractUnit implements OperatableUnit { } /** - * Divides this unit by another unit. + * 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 other + * @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 other is null + * if {@code divisor} is null * @since 2018-12-22 * @since v0.1.0 */ - public LinearUnit dividedBy(final LinearUnit other) { - Objects.requireNonNull(other, "other must not be null"); - final BaseUnit base = this.getBase().dividedBy(other.getBase()); - return new LinearUnit(base, this.getConversionFactor() / other.getConversionFactor()); + 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()); } @Override @@ -112,12 +126,13 @@ public final class LinearUnit extends AbstractUnit implements OperatableUnit { if (!(obj instanceof LinearUnit)) return false; final LinearUnit other = (LinearUnit) obj; - return Objects.equals(this.getBase(), other.getBase()) - && Objects.equals(this.getConversionFactor(), other.getConversionFactor()); + return Objects.equals(this.getSystem(), other.getSystem()) + && Objects.equals(this.getDimension(), other.getDimension()) + && DecimalComparison.equals(this.getConversionFactor(), other.getConversionFactor()); } /** - * @return conversionFactor + * @return conversion factor between this unit and its base * @since 2018-12-22 * @since v0.1.0 */ @@ -129,43 +144,66 @@ public final class LinearUnit extends AbstractUnit implements OperatableUnit { public int hashCode() { final int prime = 31; int result = 1; - result = result * prime + this.getBase().hashCode(); + result = result * prime + this.getSystem().hashCode(); + result = result * prime + this.getDimension().hashCode(); result = result * prime + Double.hashCode(this.getConversionFactor()); return result; } - @Override - public LinearUnit negated() { - return new LinearUnit(this.getBase(), -this.getConversionFactor()); + /** + * Returns the difference of this unit and another. + * <p> + * Two units can be subtracted if they have the same base. If {@code subtrahend} does not meet this condition, an + * {@code IllegalArgumentException} will be thrown. + * </p> + * + * @param subtrahend + * unit to subtract + * @return difference of units + * @throws IllegalArgumentException + * if {@code subtrahend} is not compatible for subtraction as described above + * @throws NullPointerException + * if {@code subtrahend} is null + * @since 2019-03-17 + */ + public LinearUnit minus(final LinearUnit subtrahendend) { + Objects.requireNonNull(subtrahendend, "addend must not be null."); + + // reject subtrahends that cannot be added to this unit + if (!this.getBase().equals(subtrahendend.getBase())) + throw new IllegalArgumentException( + String.format("Incompatible units for subtraction \"%s\" and \"%s\".", this, subtrahendend)); + + // add the units + return new LinearUnit(this.getBase(), this.getConversionFactor() - subtrahendend.getConversionFactor()); } - @Override - public OperatableUnit plus(final OperatableUnit addend) { + /** + * Returns the sum of this unit and another. + * <p> + * Two units can be added if they have the same base. If {@code addend} does not meet this condition, an + * {@code IllegalArgumentException} will be thrown. + * </p> + * + * @param addend + * unit to add + * @return sum of units + * @throws IllegalArgumentException + * if {@code addend} is not compatible for addition as described above + * @throws NullPointerException + * if {@code addend} is null + * @since 2019-03-17 + */ + public LinearUnit plus(final LinearUnit addend) { Objects.requireNonNull(addend, "addend must not be null."); // reject addends that cannot be added to this unit - if (!this.getSystem().equals(addend.getSystem())) - throw new IllegalArgumentException( - String.format("Incompatible units for addition or subtraction \"%s\" and \"%s\".", this, addend)); - if (!this.getDimension().equals(addend.getDimension())) + if (!this.getBase().equals(addend.getBase())) throw new IllegalArgumentException( - String.format("Incompatible units for addition or subtraction \"%s\" and \"%s\".", this, addend)); + String.format("Incompatible units for addition \"%s\" and \"%s\".", this, addend)); // add the units - if (addend instanceof BaseUnit) - // since addend's dimension is equal to this unit's dimension, and there is only one base unit per - // system-dimension, addend must be this unit's base. - return new LinearUnit(this.getBase(), this.getConversionFactor() + 1); - else if (addend instanceof LinearUnit) - return new LinearUnit(this.getBase(), - this.getConversionFactor() + ((LinearUnit) addend).getConversionFactor()); - else - return addend.times(this); - } - - @Override - public LinearUnit reciprocal() { - return this.toExponent(-1); + return new LinearUnit(this.getBase(), this.getConversionFactor() + addend.getConversionFactor()); } /** @@ -182,40 +220,33 @@ public final class LinearUnit extends AbstractUnit implements OperatableUnit { } /** - * Multiplies this unit by another unit. + * 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 other - * unit to multiply by= + * @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 other is null + * if {@code multiplier} is null * @since 2018-12-22 * @since v0.1.0 */ - public LinearUnit times(final LinearUnit other) { - Objects.requireNonNull(other, "other must not be null"); - final BaseUnit base = this.getBase().times(other.getBase()); - return new LinearUnit(base, this.getConversionFactor() * other.getConversionFactor()); - } - - @Override - public OperatableUnit times(final OperatableUnit multiplier) { - Objects.requireNonNull(multiplier, "multiplier must not be null."); + public LinearUnit times(final LinearUnit multiplier) { + Objects.requireNonNull(multiplier, "other must not be null"); - // reject multipliers that cannot be muliplied by this unit + // check that these units can be multiplied if (!this.getSystem().equals(multiplier.getSystem())) - throw new IllegalArgumentException(String - .format("Incompatible units for multiplication or division \"%s\" and \"%s\".", this, multiplier)); + throw new IllegalArgumentException( + String.format("Incompatible units for multiplication \"%s\" and \"%s\".", this, multiplier)); // multiply the units - if (multiplier instanceof BaseUnit) { - final BaseUnit newBase = this.getBase().times((BaseUnit) multiplier); - return new LinearUnit(newBase, this.getConversionFactor()); - } else if (multiplier instanceof LinearUnit) { - final BaseUnit base = this.getBase().times(multiplier.getBase()); - return new LinearUnit(base, this.getConversionFactor() * ((LinearUnit) multiplier).getConversionFactor()); - } else - return multiplier.times(this); + final BaseUnit base = this.getBase().times(multiplier.getBase()); + return new LinearUnit(base, this.getConversionFactor() * multiplier.getConversionFactor()); } /** @@ -227,7 +258,6 @@ public final class LinearUnit extends AbstractUnit implements OperatableUnit { * @since 2019-01-15 * @since v0.1.0 */ - @Override public LinearUnit toExponent(final int exponent) { return new LinearUnit(this.getBase().toExponent(exponent), Math.pow(this.conversionFactor, exponent)); } @@ -236,4 +266,16 @@ public final class LinearUnit extends AbstractUnit implements OperatableUnit { public String toString() { return super.toString() + String.format(" (equal to %s * base)", this.getConversionFactor()); } + + /** + * Returns the result of applying {@code prefix} to this unit. + * + * @param prefix + * prefix to apply + * @return unit with prefix + * @since 2019-03-18 + */ + public LinearUnit withPrefix(final UnitPrefix prefix) { + return this.times(prefix.getMultiplier()); + } } |