diff options
author | Adrien Hopkins <masterofnumbers17@gmail.com> | 2019-10-16 12:31:09 -0400 |
---|---|---|
committer | Adrien Hopkins <masterofnumbers17@gmail.com> | 2019-10-16 12:31:09 -0400 |
commit | 145f524f19b3d61cd12441c2f1a8de05d7dcfe60 (patch) | |
tree | c840fa8c9dd872505984a672712541f4cc44f378 /src | |
parent | 69f2849d25a41ae7c0383636557deda1bc64247d (diff) |
Created the new BaseUnit, Unit and AbstractUnit implementations.
Diffstat (limited to 'src')
-rw-r--r-- | src/org/unitConverter/newUnits/AbstractUnit.java | 76 | ||||
-rw-r--r-- | src/org/unitConverter/newUnits/BaseUnit.java | 102 | ||||
-rw-r--r-- | src/org/unitConverter/newUnits/FunctionalUnit.java | 98 | ||||
-rw-r--r-- | src/org/unitConverter/newUnits/Unit.java | 145 | ||||
-rw-r--r-- | src/org/unitConverter/newUnits/package-info.java | 23 |
5 files changed, 444 insertions, 0 deletions
diff --git a/src/org/unitConverter/newUnits/AbstractUnit.java b/src/org/unitConverter/newUnits/AbstractUnit.java new file mode 100644 index 0000000..909ea8b --- /dev/null +++ b/src/org/unitConverter/newUnits/AbstractUnit.java @@ -0,0 +1,76 @@ +/** + * 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.newUnits; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.unitConverter.dimension.BaseDimension; +import org.unitConverter.math.ObjectProduct; + +/** + * @author Adrien Hopkins + * @since 2019-10-16 + */ +public abstract class AbstractUnit implements Unit { + /** + * The combination of units that this unit is based on. + */ + private final ObjectProduct<BaseUnit> unitBase; + + /** + * Cache storing the result of getDimension() + */ + private transient ObjectProduct<BaseDimension> dimension = null; + + /** + * Creates the {@code AbstractUnit}. + * + * @param unitBase + * @since 2019-10-16 + * @throws NullPointerException + * if unitBase is null + */ + public AbstractUnit(final ObjectProduct<BaseUnit> unitBase) { + this.unitBase = Objects.requireNonNull(unitBase, "unitBase must not be null."); + } + + /** + * @return unitBase + * @since 2019-10-16 + */ + @Override + public final ObjectProduct<BaseUnit> getBase() { + return this.unitBase; + } + + @Override + public ObjectProduct<BaseDimension> getDimension() { + if (this.dimension == null) { + final Map<BaseUnit, Integer> mapping = this.unitBase.exponentMap(); + final Map<BaseDimension, Integer> dimensionMap = new HashMap<>(); + + for (final BaseUnit key : mapping.keySet()) { + dimensionMap.put(key.getBaseDimension(), mapping.get(key)); + } + + this.dimension = ObjectProduct.fromExponentMapping(dimensionMap); + } + return this.dimension; + } +} diff --git a/src/org/unitConverter/newUnits/BaseUnit.java b/src/org/unitConverter/newUnits/BaseUnit.java new file mode 100644 index 0000000..69e8b8b --- /dev/null +++ b/src/org/unitConverter/newUnits/BaseUnit.java @@ -0,0 +1,102 @@ +/** + * 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.newUnits; + +import java.util.Objects; + +import org.unitConverter.dimension.BaseDimension; +import org.unitConverter.math.ObjectProduct; + +/** + * A unit that other units are defined by. + * + * @author Adrien Hopkins + * @since 2019-10-16 + */ +public final class BaseUnit implements Unit { + private final BaseDimension dimension; + private final String name; + private final String symbol; + + /** + * Creates the {@code BaseUnit}. + * + * @param dimension + * dimension of unit + * @param name + * name of unit + * @param symbol + * symbol of unit + * @throws NullPointerException + * if any argument is null + * @since 2019-10-16 + */ + private BaseUnit(final BaseDimension dimension, final String name, final String symbol) { + this.dimension = Objects.requireNonNull(dimension, "dimension must not be null."); + this.name = Objects.requireNonNull(name, "name must not be null."); + this.symbol = Objects.requireNonNull(symbol, "symbol must not be null."); + } + + @Override + public double convertFromBase(final double value) { + return value; + } + + @Override + public double convertToBase(final double value) { + return value; + } + + @Override + public ObjectProduct<BaseUnit> getBase() { + return ObjectProduct.oneOf(this); + } + + /** + * @return dimension + * @since 2019-10-16 + */ + public final BaseDimension getBaseDimension() { + return this.dimension; + } + + @Override + public ObjectProduct<BaseDimension> getDimension() { + return ObjectProduct.oneOf(this.getBaseDimension()); + } + + /** + * @return name + * @since 2019-10-16 + */ + public final String getName() { + return this.name; + } + + /** + * @return symbol + * @since 2019-10-16 + */ + public final String getSymbol() { + return this.symbol; + } + + @Override + public String toString() { + return String.format("%s (%s)", this.getName(), this.getSymbol()); + } +} diff --git a/src/org/unitConverter/newUnits/FunctionalUnit.java b/src/org/unitConverter/newUnits/FunctionalUnit.java new file mode 100644 index 0000000..99ff833 --- /dev/null +++ b/src/org/unitConverter/newUnits/FunctionalUnit.java @@ -0,0 +1,98 @@ +/** + * 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.newUnits; + +import java.util.Objects; +import java.util.function.DoubleUnaryOperator; + +import org.unitConverter.math.ObjectProduct; + +/** + * 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 + * @throws NullPointerException + * if any argument is null + */ + public static FunctionalUnit valueOf(final ObjectProduct<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. + * @throws NullPointerException + * if any argument is null + * @since 2019-05-22 + */ + private FunctionalUnit(final ObjectProduct<BaseUnit> base, final DoubleUnaryOperator converterFrom, + final DoubleUnaryOperator converterTo) { + super(base); + this.converterFrom = Objects.requireNonNull(converterFrom, "converterFrom must not be null."); + this.converterTo = Objects.requireNonNull(converterTo, "converterTo must not be null."); + } + + @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/newUnits/Unit.java b/src/org/unitConverter/newUnits/Unit.java new file mode 100644 index 0000000..339afde --- /dev/null +++ b/src/org/unitConverter/newUnits/Unit.java @@ -0,0 +1,145 @@ +/** + * 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.newUnits; + +import java.util.Objects; +import java.util.function.DoubleUnaryOperator; + +import org.unitConverter.dimension.BaseDimension; +import org.unitConverter.math.ObjectProduct; + +/** + * @author Adrien Hopkins + * @since 2019-10-16 + */ +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 + * @throws NullPointerException + * if any argument is null + */ + public static Unit fromConversionFunctions(final ObjectProduct<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 + * unit to test with + * @return true if the units are compatible + * @since 2019-01-13 + * @since v0.1.0 + * @throws NullPointerException + * if other is null + */ + default boolean canConvertTo(final Unit 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> + * This must be the inverse of {@code convertToBase}, so {@code convertFromBase(convertToBase(value))} must be equal + * to {@code value} for any value, ignoring precision loss by roundoff error. + * </p> + * <p> + * If this unit <i>is</i> a base unit, this method should return {@code value}. + * </p> + * + * @param value + * value expressed in <b>base</b> unit + * @return value expressed in <b>this</b> unit + * @since 2018-12-22 + * @since v0.1.0 + */ + 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}). + * @throws NullPointerException + * if other is null + */ + default double convertTo(final Unit 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)); + } + + /** + * 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 + * equal to {@code value} for any value, ignoring precision loss by roundoff error. + * </p> + * <p> + * If this unit <i>is</i> a base unit, this method should return {@code value}. + * </p> + * + * @param value + * value expressed in <b>this</b> unit + * @return value expressed in <b>base</b> unit + * @since 2018-12-22 + * @since v0.1.0 + */ + double convertToBase(double value); + + /** + * @return combination of units that this unit is based on + * @since 2018-12-22 + * @since v0.1.0 + */ + ObjectProduct<BaseUnit> getBase(); + + /** + * @return dimension measured by this unit + * @since 2018-12-22 + * @since v0.1.0 + */ + ObjectProduct<BaseDimension> getDimension(); +}
\ No newline at end of file diff --git a/src/org/unitConverter/newUnits/package-info.java b/src/org/unitConverter/newUnits/package-info.java new file mode 100644 index 0000000..9cd0d1a --- /dev/null +++ b/src/org/unitConverter/newUnits/package-info.java @@ -0,0 +1,23 @@ +/** + * 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/>. + */ +/** + * The new definition for units. + * + * @author Adrien Hopkins + * @since 2019-10-16 + */ +package org.unitConverter.newUnits;
\ No newline at end of file |