summaryrefslogtreecommitdiff
path: root/src/org/unitConverter/unit/UnitValue.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/unitConverter/unit/UnitValue.java')
-rw-r--r--src/org/unitConverter/unit/UnitValue.java114
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;
+ }
+ }
+}