summaryrefslogtreecommitdiff
path: root/src/main/java/sevenUnits/unit/Unit.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/sevenUnits/unit/Unit.java')
-rw-r--r--src/main/java/sevenUnits/unit/Unit.java131
1 files changed, 45 insertions, 86 deletions
diff --git a/src/main/java/sevenUnits/unit/Unit.java b/src/main/java/sevenUnits/unit/Unit.java
index 59e928a..40e6e0d 100644
--- a/src/main/java/sevenUnits/unit/Unit.java
+++ b/src/main/java/sevenUnits/unit/Unit.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2019 Adrien Hopkins
+ * Copyright (C) 2019, 2021, 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -28,22 +28,23 @@ import sevenUnits.utils.ObjectProduct;
/**
* A unit that is composed of base units.
- *
+ *
* @author Adrien Hopkins
* @since 2019-10-16
+ * @since v0.3.0
*/
public abstract class Unit implements Nameable {
/**
* Returns a unit from its base and the functions it uses to convert to and
* from its base.
- *
+ *
* <p>
* For example, to get a unit representing the degree Celsius, the following
* code can be used:
- *
+ *
* {@code Unit.fromConversionFunctions(SI.KELVIN, tempK -> tempK - 273.15, tempC -> tempC + 273.15);}
* </p>
- *
+ *
* @param base unit's base
* @param converterFrom function that accepts a value expressed in the unit's
* base and returns that value expressed in this unit.
@@ -51,6 +52,7 @@ public abstract class Unit implements Nameable {
* and returns that value expressed in the unit's base.
* @return a unit that uses the provided functions to convert.
* @since 2019-05-22
+ * @since v0.3.0
* @throws NullPointerException if any argument is null
*/
public static final Unit fromConversionFunctions(
@@ -63,14 +65,14 @@ public abstract class Unit implements Nameable {
/**
* Returns a unit from its base and the functions it uses to convert to and
* from its base.
- *
+ *
* <p>
* For example, to get a unit representing the degree Celsius, the following
* code can be used:
- *
+ *
* {@code Unit.fromConversionFunctions(SI.KELVIN, tempK -> tempK - 273.15, tempC -> tempC + 273.15);}
* </p>
- *
+ *
* @param base unit's base
* @param converterFrom function that accepts a value expressed in the unit's
* base and returns that value expressed in this unit.
@@ -79,6 +81,7 @@ public abstract class Unit implements Nameable {
* @param ns names and symbol of unit
* @return a unit that uses the provided functions to convert.
* @since 2019-05-22
+ * @since v0.3.0
* @throws NullPointerException if any argument is null
*/
public static final Unit fromConversionFunctions(
@@ -90,15 +93,17 @@ public abstract class Unit implements Nameable {
/**
* The combination of units that this unit is based on.
- *
+ *
* @since 2019-10-16
+ * @since v0.3.0
*/
private final ObjectProduct<BaseUnit> unitBase;
/**
* This unit's name(s) and symbol
- *
+ *
* @since 2020-09-07
+ * @since v0.3.0
*/
private final NameSymbol nameSymbol;
@@ -106,28 +111,30 @@ public abstract class Unit implements Nameable {
* Cache storing the result of getDimension()
*
* @since 2019-10-16
+ * @since v0.3.0
*/
private transient ObjectProduct<BaseDimension> dimension = null;
/**
* A constructor that constructs {@code BaseUnit} instances.
- *
+ *
* @since 2019-10-16
+ * @since v0.3.0
*/
Unit(final NameSymbol nameSymbol) {
- if (this instanceof BaseUnit) {
- this.unitBase = ObjectProduct.oneOf((BaseUnit) this);
- } else
+ if (!(this instanceof BaseUnit))
throw new AssertionError();
+ this.unitBase = ObjectProduct.oneOf((BaseUnit) this);
this.nameSymbol = nameSymbol;
}
/**
* Creates the {@code Unit}.
- *
+ *
* @param unitBase base of unit
* @param ns names and symbol of unit
* @since 2019-10-16
+ * @since v0.3.0
* @throws NullPointerException if unitBase or ns is null
*/
protected Unit(ObjectProduct<BaseUnit> unitBase, NameSymbol ns) {
@@ -137,18 +144,9 @@ public abstract class Unit implements Nameable {
}
/**
- * @return this unit as a {@link Unitlike}
- * @since 2020-09-07
- */
- public final Unitlike<Double> asUnitlike() {
- return Unitlike.fromConversionFunctions(this.getBase(),
- this::convertFromBase, this::convertToBase, this.getNameSymbol());
- }
-
- /**
* Checks if a value expressed in this unit can be converted to a value
* expressed in {@code other}
- *
+ *
* @param other unit or unitlike form to test with
* @return true if they are compatible
* @since 2019-01-13
@@ -161,21 +159,6 @@ public abstract class Unit implements Nameable {
}
/**
- * Checks if a value expressed in this unit can be converted to a value
- * expressed in {@code other}
- *
- * @param other unit or unitlike form to test with
- * @return true if they are compatible
- * @since 2019-01-13
- * @since v0.1.0
- * @throws NullPointerException if other is null
- */
- public final <W> boolean canConvertTo(final Unitlike<W> other) {
- Objects.requireNonNull(other, "other must not be null.");
- return Objects.equals(this.getBase(), other.getBase());
- }
-
- /**
* Converts from a value expressed in this unit's base unit to a value
* expressed in this unit.
* <p>
@@ -187,10 +170,10 @@ public abstract class Unit implements Nameable {
* If this unit <i>is</i> a base unit, this method should return
* {@code value}.
* </p>
- *
+ *
* @implSpec This method is used by {@link #convertTo}, and its behaviour
* affects the behaviour of {@code convertTo}.
- *
+ *
* @param value value expressed in <b>base</b> unit
* @return value expressed in <b>this</b> unit
* @since 2018-12-22
@@ -201,16 +184,17 @@ public abstract class Unit implements Nameable {
/**
* Converts a value expressed in this unit to a value expressed in
* {@code other}.
- *
+ *
* @implSpec If unit conversion is possible, this implementation returns
* {@code other.convertFromBase(this.convertToBase(value))}.
* Therefore, overriding either of those methods will change the
* output of this method.
- *
+ *
* @param other unit to convert to
* @param value value to convert
* @return converted value
* @since 2019-05-22
+ * @since v0.3.0
* @throws IllegalArgumentException if {@code other} is incompatible for
* conversion with this unit (as tested by
* {@link Unit#canConvertTo}).
@@ -220,37 +204,8 @@ public abstract class Unit implements Nameable {
Objects.requireNonNull(other, "other must not be null.");
if (this.canConvertTo(other))
return other.convertFromBase(this.convertToBase(value));
- else
- throw new IllegalArgumentException(
- String.format("Cannot convert from %s to %s.", this, other));
- }
-
- /**
- * Converts a value expressed in this unit to a value expressed in
- * {@code other}.
- *
- * @implSpec If conversion is possible, this implementation returns
- * {@code other.convertFromBase(this.convertToBase(value))}.
- * Therefore, overriding either of those methods will change the
- * output of this method.
- *
- * @param other unitlike form to convert to
- * @param value value to convert
- * @param <W> type of value to convert to
- * @return converted value
- * @since 2020-09-07
- * @throws IllegalArgumentException if {@code other} is incompatible for
- * conversion with this unit (as tested by
- * {@link Unit#canConvertTo}).
- * @throws NullPointerException if other is null
- */
- public final <W> W convertTo(final Unitlike<W> other, final double value) {
- Objects.requireNonNull(other, "other must not be null.");
- if (this.canConvertTo(other))
- return other.convertFromBase(this.convertToBase(value));
- else
- throw new IllegalArgumentException(
- String.format("Cannot convert from %s to %s.", this, other));
+ throw new IllegalArgumentException(
+ String.format("Cannot convert from %s to %s.", this, other));
}
/**
@@ -265,10 +220,10 @@ public abstract class Unit implements Nameable {
* If this unit <i>is</i> a base unit, this method should return
* {@code value}.
* </p>
- *
+ *
* @implSpec This method is used by {@link #convertTo}, and its behaviour
* affects the behaviour of {@code convertTo}.
- *
+ *
* @param value value expressed in <b>this</b> unit
* @return value expressed in <b>base</b> unit
* @since 2018-12-22
@@ -292,7 +247,7 @@ public abstract class Unit implements Nameable {
*/
public final ObjectProduct<BaseDimension> getDimension() {
if (this.dimension == null) {
- final Map<BaseUnit, Integer> mapping = this.unitBase.exponentMap();
+ final var mapping = this.unitBase.exponentMap();
final Map<BaseDimension, Integer> dimensionMap = new HashMap<>();
for (final BaseUnit key : mapping.keySet()) {
@@ -307,6 +262,7 @@ public abstract class Unit implements Nameable {
/**
* @return the nameSymbol
* @since 2020-09-07
+ * @since v0.3.0
*/
@Override
public final NameSymbol getNameSymbol() {
@@ -314,7 +270,7 @@ public abstract class Unit implements Nameable {
}
/**
- * Returns true iff this unit is metric.
+ * Determines whether this unit is metric.
* <p>
* "Metric" is defined by three conditions:
* <ul>
@@ -329,14 +285,17 @@ public abstract class Unit implements Nameable {
* <p>
* All SI units (as designated by the BIPM) except the degree Celsius are
* considered "metric" by this definition.
- *
+ *
+ * @return true iff this unit is metric.
+ *
* @since 2020-08-27
+ * @since v0.3.0
*/
public final boolean isMetric() {
// first condition - check that it is a linear unit
if (!(this instanceof LinearUnit))
return false;
- final LinearUnit linear = (LinearUnit) this;
+ final var linear = (LinearUnit) this;
// second condition - check that
for (final BaseUnit b : linear.getBase().getBaseSet()) {
@@ -352,18 +311,18 @@ public abstract class Unit implements Nameable {
/**
* @return a string representing this unit's definition
* @since 2022-03-10
+ * @since v0.3.0
*/
public String toDefinitionString() {
if (!this.unitBase.getNameSymbol().isEmpty())
return "derived from " + this.unitBase.getName();
- else
- return "derived from "
- + this.getBase().toString(BaseUnit::getShortName);
+ return "derived from " + this.getBase().toString(BaseUnit::getShortName);
}
/**
* @return a string containing both this unit's name and its definition
* @since 2022-03-10
+ * @since v0.3.0
*/
public final String toFullString() {
return this.toString() + " (" + this.toDefinitionString() + ")";
@@ -375,14 +334,14 @@ public abstract class Unit implements Nameable {
&& this.nameSymbol.getSymbol().isPresent())
return this.nameSymbol.getPrimaryName().orElseThrow() + " ("
+ this.nameSymbol.getSymbol().orElseThrow() + ")";
- else
- return this.getName();
+ return this.getName();
}
/**
* @param ns name(s) and symbol to use
* @return a copy of this unit with provided name(s) and symbol
* @since 2019-10-21
+ * @since v0.3.0
* @throws NullPointerException if ns is null
*/
public Unit withName(final NameSymbol ns) {