summaryrefslogtreecommitdiff
path: root/src/org
diff options
context:
space:
mode:
authorAdrien Hopkins <adrien.p.hopkins@gmail.com>2019-05-22 17:32:40 -0400
committerAdrien Hopkins <adrien.p.hopkins@gmail.com>2019-05-22 17:32:40 -0400
commit987fd8406d65505aedecd17e51216eb0ce393fbb (patch)
treeb10a551a57cbd099450ffe539cb8d6d8e230459d /src/org
parent50a195ef78af5d15dd6e548d4d6928c281bbaac2 (diff)
Added new default methods to the Unit interface.
Diffstat (limited to 'src/org')
-rwxr-xr-xsrc/org/unitConverter/converterGUI/UnitConverterGUI.java4
-rw-r--r--src/org/unitConverter/math/ExpressionParser.java8
-rw-r--r--src/org/unitConverter/unit/AbstractUnit.java7
-rw-r--r--src/org/unitConverter/unit/FunctionalUnit.java91
-rwxr-xr-xsrc/org/unitConverter/unit/NonlinearUnits.java28
-rwxr-xr-xsrc/org/unitConverter/unit/Unit.java46
6 files changed, 154 insertions, 30 deletions
diff --git a/src/org/unitConverter/converterGUI/UnitConverterGUI.java b/src/org/unitConverter/converterGUI/UnitConverterGUI.java
index e258c6f..2d3d1a5 100755
--- a/src/org/unitConverter/converterGUI/UnitConverterGUI.java
+++ b/src/org/unitConverter/converterGUI/UnitConverterGUI.java
@@ -191,7 +191,7 @@ final class UnitConverterGUI {
return;
}
final double beforeValue = Double.parseDouble(input);
- final double value = to.convertFromBase(from.convertToBase(beforeValue));
+ final double value = from.convertTo(to, beforeValue);
final String output = this.getRoundedString(value);
@@ -254,7 +254,7 @@ final class UnitConverterGUI {
return;
}
- value = to.convertFromBase(from.convertToBase(1));
+ value = from.convertTo(to, 1);
// round value
final String output = this.getRoundedString(value);
diff --git a/src/org/unitConverter/math/ExpressionParser.java b/src/org/unitConverter/math/ExpressionParser.java
index b2261ed..8a0e97d 100644
--- a/src/org/unitConverter/math/ExpressionParser.java
+++ b/src/org/unitConverter/math/ExpressionParser.java
@@ -55,7 +55,7 @@ public final class ExpressionParser<T> {
* @since 2019-03-14
* @since v0.2.0
*/
- private final Function<String, T> objectObtainer;
+ private final Function<String, ? extends T> objectObtainer;
/**
* The function of the space as an operator (like 3 x y)
@@ -91,7 +91,7 @@ public final class ExpressionParser<T> {
* @since 2019-03-17
* @since v0.2.0
*/
- public Builder(final Function<String, T> objectObtainer) {
+ public Builder(final Function<String, ? extends T> objectObtainer) {
this.objectObtainer = Objects.requireNonNull(objectObtainer, "objectObtainer must not be null.");
this.unaryOperators = new HashMap<>();
this.binaryOperators = new HashMap<>();
@@ -397,7 +397,7 @@ public final class ExpressionParser<T> {
* @since 2019-03-14
* @since v0.2.0
*/
- private final Function<String, T> objectObtainer;
+ private final Function<String, ? extends T> objectObtainer;
/**
* A map mapping operator strings to operator functions, for unary operators.
@@ -437,7 +437,7 @@ public final class ExpressionParser<T> {
* @since 2019-03-14
* @since v0.2.0
*/
- private ExpressionParser(final Function<String, T> objectObtainer,
+ private ExpressionParser(final Function<String, ? extends T> objectObtainer,
final Map<String, PriorityUnaryOperator<T>> unaryOperators,
final Map<String, PriorityBinaryOperator<T>> binaryOperators, final String spaceOperator) {
this.objectObtainer = objectObtainer;
diff --git a/src/org/unitConverter/unit/AbstractUnit.java b/src/org/unitConverter/unit/AbstractUnit.java
index 05a6c17..6045127 100644
--- a/src/org/unitConverter/unit/AbstractUnit.java
+++ b/src/org/unitConverter/unit/AbstractUnit.java
@@ -23,6 +23,13 @@ import org.unitConverter.dimension.UnitDimension;
/**
* The default abstract implementation of the {@code Unit} interface.
*
+ * <p>
+ * With the addition of {@link Unit#fromConversionFunctions}, there is no longer any reason to use {@code AbstractUnit}
+ * for any purpose other than making subclasses. Units should never be declared as {@code AbstractUnit}, they should be
+ * declared as {@code Unit}. Now that {@code Unit.fromConversionFunctions} exists, it is preferred to creating anonymous
+ * inner types of {@code AbstractUnit}.
+ * </p>
+ *
* @author Adrien Hopkins
* @since 2018-12-22
* @since v0.1.0
diff --git a/src/org/unitConverter/unit/FunctionalUnit.java b/src/org/unitConverter/unit/FunctionalUnit.java
new file mode 100644
index 0000000..c2aae6d
--- /dev/null
+++ b/src/org/unitConverter/unit/FunctionalUnit.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2019 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package org.unitConverter.unit;
+
+import java.util.function.DoubleUnaryOperator;
+
+/**
+ * A unit that uses functional objects to convert to and from its base.
+ *
+ * @author Adrien Hopkins
+ * @since 2019-05-22
+ */
+final class FunctionalUnit extends AbstractUnit {
+ /**
+ * Returns a unit from its base and the functions it uses to convert to and from its base.
+ *
+ * @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.
+ * @param converterTo
+ * function that accepts a value expressed in the unit and returns that value expressed in the unit's
+ * base.
+ * @return a unit that uses the provided functions to convert.
+ * @since 2019-05-22
+ */
+ public static FunctionalUnit valueOf(final BaseUnit base, final DoubleUnaryOperator converterFrom,
+ final DoubleUnaryOperator converterTo) {
+ return new FunctionalUnit(base, converterFrom, converterTo);
+ }
+
+ /**
+ * A function that accepts a value expressed in the unit's base and returns that value expressed in this unit.
+ *
+ * @since 2019-05-22
+ */
+ private final DoubleUnaryOperator converterFrom;
+
+ /**
+ * A function that accepts a value expressed in the unit and returns that value expressed in the unit's base.
+ *
+ * @since 2019-05-22
+ */
+ private final DoubleUnaryOperator converterTo;
+
+ /**
+ * Creates the {@code FunctionalUnit}.
+ *
+ * @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.
+ * @param converterTo
+ * function that accepts a value expressed in the unit and returns that value expressed in the unit's
+ * base.
+ * @since 2019-05-22
+ */
+ private FunctionalUnit(final BaseUnit base, final DoubleUnaryOperator converterFrom,
+ final DoubleUnaryOperator converterTo) {
+ super(base);
+ this.converterFrom = converterFrom;
+ this.converterTo = converterTo;
+ }
+
+ @Override
+ public double convertFromBase(final double value) {
+ return this.converterFrom.applyAsDouble(value);
+ }
+
+ @Override
+ public double convertToBase(final double value) {
+ return this.converterTo.applyAsDouble(value);
+ }
+
+}
diff --git a/src/org/unitConverter/unit/NonlinearUnits.java b/src/org/unitConverter/unit/NonlinearUnits.java
index e47c28f..eda4a74 100755
--- a/src/org/unitConverter/unit/NonlinearUnits.java
+++ b/src/org/unitConverter/unit/NonlinearUnits.java
@@ -24,31 +24,11 @@ package org.unitConverter.unit;
* @since v0.1.0
*/
public final class NonlinearUnits {
- public static final Unit CELSIUS = new AbstractUnit(SI.KELVIN) {
+ public static final Unit CELSIUS = Unit.fromConversionFunctions(SI.KELVIN, tempK -> tempK - 273.15,
+ tempC -> tempC + 273.15);
- @Override
- public double convertFromBase(final double value) {
- return value - 273.15;
- }
-
- @Override
- public double convertToBase(final double value) {
- return value + 273.15;
- }
- };
-
- public static final Unit FAHRENHEIT = new AbstractUnit(SI.KELVIN) {
-
- @Override
- public double convertFromBase(final double value) {
- return 1.8 * value - 459.67;
- }
-
- @Override
- public double convertToBase(final double value) {
- return (value + 459.67) / 1.8;
- }
- };
+ public static final Unit FAHRENHEIT = Unit.fromConversionFunctions(SI.KELVIN, tempK -> tempK * 1.8 - 459.67,
+ tempF -> (tempF + 459.67) / 1.8);
// You may NOT get a NonlinearUnits instance.
private NonlinearUnits() {
diff --git a/src/org/unitConverter/unit/Unit.java b/src/org/unitConverter/unit/Unit.java
index 86fc5a2..2ac107e 100755
--- a/src/org/unitConverter/unit/Unit.java
+++ b/src/org/unitConverter/unit/Unit.java
@@ -17,6 +17,7 @@
package org.unitConverter.unit;
import java.util.Objects;
+import java.util.function.DoubleUnaryOperator;
import org.unitConverter.dimension.UnitDimension;
@@ -29,6 +30,31 @@ import org.unitConverter.dimension.UnitDimension;
*/
public interface Unit {
/**
+ * 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.
+ * @param converterTo
+ * function that accepts a value expressed in the unit and returns that value expressed in the unit's
+ * base.
+ * @return a unit that uses the provided functions to convert.
+ * @since 2019-05-22
+ */
+ public static Unit fromConversionFunctions(final BaseUnit base, final DoubleUnaryOperator converterFrom,
+ final DoubleUnaryOperator converterTo) {
+ return FunctionalUnit.valueOf(base, converterFrom, converterTo);
+ }
+
+ /**
* Checks if a value expressed in this unit can be converted to a value expressed in {@code other}
*
* @param other
@@ -60,6 +86,26 @@ public interface Unit {
double convertFromBase(double value);
/**
+ * Converts a value expressed in this unit to a value expressed in {@code other}.
+ *
+ * @param other
+ * unit to convert to
+ * @param value
+ * value to convert
+ * @return converted value
+ * @since 2019-05-22
+ * @throws IllegalArgumentException
+ * if {@code other} is incompatible for conversion with this unit (as tested by
+ * {@link Unit#canConvertTo}).
+ */
+ default double convertTo(final Unit other, final double value) {
+ 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 from a value expressed in this unit to a value expressed in this unit's base unit.
* <p>
* This must be the inverse of {@code convertFromBase}, so {@code convertToBase(convertFromBase(value))} must be