diff options
Diffstat (limited to 'src/org/unitConverter/unit/UnitValue.java')
-rw-r--r-- | src/org/unitConverter/unit/UnitValue.java | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/org/unitConverter/unit/UnitValue.java b/src/org/unitConverter/unit/UnitValue.java new file mode 100644 index 0000000..9e565d9 --- /dev/null +++ b/src/org/unitConverter/unit/UnitValue.java @@ -0,0 +1,114 @@ +package org.unitConverter.unit; + +import java.util.Objects; +import java.util.Optional; + +/** + * A value expressed in a unit. + * + * Unless otherwise indicated, all methods in this class throw a + * {@code NullPointerException} when an argument is null. + * + * @author Adrien Hopkins + * @since 2020-07-26 + */ +public final class UnitValue { + /** + * @param unit unit to use + * @param value value to use + * @return {@code UnitValue} instance + */ + public static UnitValue of(Unit unit, double value) { + return new UnitValue(Objects.requireNonNull(unit, "unit must not be null"), value); + } + + private final Unit unit; + private final double value; + + /** + * @param unit the unit being used + * @param value the value being represented + */ + private UnitValue(Unit unit, double value) { + this.unit = unit; + this.value = value; + } + + /** + * @return the unit + */ + public final Unit getUnit() { + return unit; + } + + /** + * @return the value + */ + public final double getValue() { + return value; + } + + /** + * Converts this {@code UnitValue} into an equivalent {@code LinearUnitValue} by + * using this unit's base unit. + * + * @param newName A new name for the base unit. Use {@link NameSymbol#EMPTY} if + * you don't want one. + */ + public final LinearUnitValue asLinearUnitValue(NameSymbol newName) { + LinearUnit base = LinearUnit.valueOf(unit.getBase(), 1, newName); + return LinearUnitValue.getExact(base, base.convertToBase(value)); + } + + /** + * @param other a {@code Unit} + * @return true iff this value can be represented with {@code other}. + */ + public final boolean canConvertTo(Unit other) { + return this.unit.canConvertTo(other); + } + + /** + * Returns a UnitValue that represents the same value expressed in a + * different unit + * + * @param other new unit to express value in + * @return value expressed in {@code other} + */ + public final UnitValue convertTo(Unit other) { + return UnitValue.of(other, this.getUnit().convertTo(other, this.getValue())); + } + + /** + * Returns true if this and obj represent the same value, regardless of whether + * or not they are expressed in the same unit. So (1000 m).equals(1 km) returns + * true. + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof UnitValue)) + return false; + final UnitValue other = (UnitValue) obj; + return Objects.equals(this.unit.getBase(), other.unit.getBase()) + && Double.doubleToLongBits(this.unit.convertToBase(this.getValue())) == Double + .doubleToLongBits(other.unit.convertToBase(other.getValue())); + } + + @Override + public int hashCode() { + return Objects.hash(this.unit.getBase(), this.unit.convertFromBase(this.getValue())); + } + + @Override + public String toString() { + Optional<String> primaryName = this.getUnit().getPrimaryName(); + Optional<String> symbol = this.getUnit().getSymbol(); + if (primaryName.isEmpty() && symbol.isEmpty()) { + double baseValue = this.getUnit().convertToBase(this.getValue()); + return String.format("%s unnamed unit (= %s %s)", this.getValue(), baseValue, this.getUnit().getBase()); + } else { + String unitName = symbol.orElse(primaryName.get()); + return this.getValue() + " " + unitName; + } + } +} |