diff options
author | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2019-05-22 17:32:40 -0400 |
---|---|---|
committer | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2019-05-22 17:32:40 -0400 |
commit | 987fd8406d65505aedecd17e51216eb0ce393fbb (patch) | |
tree | b10a551a57cbd099450ffe539cb8d6d8e230459d /src/org | |
parent | 50a195ef78af5d15dd6e548d4d6928c281bbaac2 (diff) |
Added new default methods to the Unit interface.
Diffstat (limited to 'src/org')
-rwxr-xr-x | src/org/unitConverter/converterGUI/UnitConverterGUI.java | 4 | ||||
-rw-r--r-- | src/org/unitConverter/math/ExpressionParser.java | 8 | ||||
-rw-r--r-- | src/org/unitConverter/unit/AbstractUnit.java | 7 | ||||
-rw-r--r-- | src/org/unitConverter/unit/FunctionalUnit.java | 91 | ||||
-rwxr-xr-x | src/org/unitConverter/unit/NonlinearUnits.java | 28 | ||||
-rwxr-xr-x | src/org/unitConverter/unit/Unit.java | 46 |
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 |