diff options
55 files changed, 1680 insertions, 1843 deletions
diff --git a/src/main/java/sevenUnits/ProgramInfo.java b/src/main/java/sevenUnits/ProgramInfo.java index 9b9832e..5ed1309 100644 --- a/src/main/java/sevenUnits/ProgramInfo.java +++ b/src/main/java/sevenUnits/ProgramInfo.java @@ -20,20 +20,20 @@ import sevenUnits.utils.SemanticVersionNumber; /** * Information about 7Units - * + * * @since 2021-06-28 * @since v0.3.1 */ public final class ProgramInfo { - + /** The version number (1.0.0-beta.2) */ public static final SemanticVersionNumber VERSION = SemanticVersionNumber .preRelease(1, 0, 0, "beta", 2); - + private ProgramInfo() { // this class is only for static variables, you shouldn't be able to // construct an instance throw new AssertionError(); } - + } diff --git a/src/main/java/sevenUnits/package-info.java b/src/main/java/sevenUnits/package-info.java index b90a5ea..dc27e1f 100644 --- a/src/main/java/sevenUnits/package-info.java +++ b/src/main/java/sevenUnits/package-info.java @@ -16,7 +16,7 @@ */ /** * A program that converts units. - * + * * @author Adrien Hopkins * @version v0.3.0 * @since 2019-01-25 diff --git a/src/main/java/sevenUnits/unit/BaseDimension.java b/src/main/java/sevenUnits/unit/BaseDimension.java index fe7b772..11b822e 100644 --- a/src/main/java/sevenUnits/unit/BaseDimension.java +++ b/src/main/java/sevenUnits/unit/BaseDimension.java @@ -23,7 +23,7 @@ import sevenUnits.utils.Nameable; /** * A dimension that defines a {@code BaseUnit} - * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.3.0 @@ -31,7 +31,7 @@ import sevenUnits.utils.Nameable; public final class BaseDimension implements Nameable { /** * Gets a {@code BaseDimension} with the provided name and symbol. - * + * * @param name name of dimension * @param symbol symbol used for dimension * @return dimension @@ -42,9 +42,7 @@ public final class BaseDimension implements Nameable { return new BaseDimension(name, symbol); } - /** - * The name of the dimension. - */ + /** The name of the dimension. */ private final String name; /** * The symbol used by the dimension. Symbols should be short, generally one @@ -54,7 +52,7 @@ public final class BaseDimension implements Nameable { /** * Creates the {@code BaseDimension}. - * + * * @param name name of unit * @param symbol symbol of unit * @throws NullPointerException if any argument is null @@ -66,9 +64,7 @@ public final class BaseDimension implements Nameable { this.symbol = Objects.requireNonNull(symbol, "symbol must not be null."); } - /** - * @since v0.4.0 - */ + /** @since v0.4.0 */ @Override public NameSymbol getNameSymbol() { return NameSymbol.of(this.name, this.symbol); diff --git a/src/main/java/sevenUnits/unit/BaseUnit.java b/src/main/java/sevenUnits/unit/BaseUnit.java index 2898de5..13e76d9 100644 --- a/src/main/java/sevenUnits/unit/BaseUnit.java +++ b/src/main/java/sevenUnits/unit/BaseUnit.java @@ -28,7 +28,7 @@ import sevenUnits.utils.NameSymbol; * Note that BaseUnits <b>must</b> have names and symbols. This is because they * are used for toString code. Therefore, the Optionals provided by * {@link #getPrimaryName} and {@link #getSymbol} will always contain a value. - * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.3.0 @@ -36,7 +36,7 @@ import sevenUnits.utils.NameSymbol; public final class BaseUnit extends Unit { /** * Gets a base unit from the dimension it measures, its name and its symbol. - * + * * @param dimension dimension measured by this unit * @param name name of unit * @param symbol symbol of unit @@ -51,7 +51,7 @@ public final class BaseUnit extends Unit { /** * Gets a base unit from the dimension it measures, its name and its symbol. - * + * * @param dimension dimension measured by this unit * @param name name of unit * @param symbol symbol of unit @@ -65,14 +65,12 @@ public final class BaseUnit extends Unit { return new BaseUnit(dimension, name, symbol, otherNames); } - /** - * The dimension measured by this base unit. - */ + /** The dimension measured by this base unit. */ private final BaseDimension dimension; /** * Creates the {@code BaseUnit}. - * + * * @param dimension dimension of unit * @param primaryName name of unit * @param symbol symbol of unit @@ -91,7 +89,7 @@ public final class BaseUnit extends Unit { * Returns a {@code LinearUnit} with this unit as a base and a conversion * factor of 1. This operation must be done in order to allow units to be * created with operations. - * + * * @return this unit as a {@code LinearUnit} * @since 2019-10-16 * @since v0.3.0 @@ -115,7 +113,7 @@ public final class BaseUnit extends Unit { * @since 2019-10-16 * @since v0.3.0 */ - public final BaseDimension getBaseDimension() { + public BaseDimension getBaseDimension() { return this.dimension; } diff --git a/src/main/java/sevenUnits/unit/BritishImperial.java b/src/main/java/sevenUnits/unit/BritishImperial.java index a6fd43f..408e9e8 100644 --- a/src/main/java/sevenUnits/unit/BritishImperial.java +++ b/src/main/java/sevenUnits/unit/BritishImperial.java @@ -20,7 +20,7 @@ import sevenUnits.utils.NameSymbol; /** * A static utility class that contains units in the British Imperial system. - * + * * @author Adrien Hopkins * @since 2019-10-21 * @since v0.3.0 @@ -31,7 +31,7 @@ import sevenUnits.utils.NameSymbol; public final class BritishImperial { /** * Imperial units that measure area - * + * * @author Adrien Hopkins * @since 2019-11-08 * @since v0.3.0 @@ -47,7 +47,7 @@ public final class BritishImperial { /** * Imperial units that measure length - * + * * @author Adrien Hopkins * @since 2019-10-28 * @since v0.3.0 @@ -70,7 +70,9 @@ public final class BritishImperial { /** A league, equal to 3 miles. */ public static final LinearUnit LEAGUE = MILE.times(3); - /** A nautical mile, around 1 arcminute around the Earth's circumference. */ + /** + * A nautical mile, around 1 arcminute around the Earth's circumference. + */ public static final LinearUnit NAUTICAL_MILE = Metric.METRE.times(1852); public static final LinearUnit CABLE = NAUTICAL_MILE.dividedBy(10); public static final LinearUnit FATHOM = CABLE.dividedBy(100); @@ -81,7 +83,7 @@ public final class BritishImperial { /** * British Imperial units that measure mass. - * + * * @author Adrien Hopkins * @since 2019-11-08 * @since v0.3.0 @@ -100,7 +102,7 @@ public final class BritishImperial { /** * British Imperial units that measure volume - * + * * @author Adrien Hopkins * @since 2019-11-08 * @since v0.3.0 diff --git a/src/main/java/sevenUnits/unit/FunctionalUnit.java b/src/main/java/sevenUnits/unit/FunctionalUnit.java index 41db164..1d55b42 100644 --- a/src/main/java/sevenUnits/unit/FunctionalUnit.java +++ b/src/main/java/sevenUnits/unit/FunctionalUnit.java @@ -24,7 +24,7 @@ import sevenUnits.utils.ObjectProduct; /** * A unit that uses functional objects to convert to and from its base. - * + * * @author Adrien Hopkins * @since 2019-05-22 * @since v0.3.0 @@ -33,7 +33,7 @@ final class FunctionalUnit extends Unit { /** * A function that accepts a value expressed in the unit's base and returns * that value expressed in this unit. - * + * * @since 2019-05-22 * @since v0.3.0 */ @@ -42,7 +42,7 @@ final class FunctionalUnit extends Unit { /** * A function that accepts a value expressed in the unit and returns that * value expressed in the unit's base. - * + * * @since 2019-05-22 * @since v0.3.0 */ @@ -50,7 +50,7 @@ final class FunctionalUnit extends Unit { /** * 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. @@ -72,7 +72,7 @@ final class FunctionalUnit extends Unit { /** * 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. @@ -95,7 +95,7 @@ final class FunctionalUnit extends Unit { /** * {@inheritDoc} - * + * * Uses {@code converterFrom} to convert. */ @Override @@ -105,7 +105,7 @@ final class FunctionalUnit extends Unit { /** * {@inheritDoc} - * + * * Uses {@code converterTo} to convert. */ @Override diff --git a/src/main/java/sevenUnits/unit/LinearUnit.java b/src/main/java/sevenUnits/unit/LinearUnit.java index 7191196..22105b6 100644 --- a/src/main/java/sevenUnits/unit/LinearUnit.java +++ b/src/main/java/sevenUnits/unit/LinearUnit.java @@ -26,7 +26,7 @@ import sevenUnits.utils.UncertainDouble; /** * A unit that can be expressed as a product of its base and a number. For * example, kilometres, inches and pounds. - * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.3.0 @@ -35,7 +35,7 @@ public final class LinearUnit extends Unit { /** * Gets a {@code LinearUnit} from a unit and a value. For example, converts * '59 °F' to a linear unit with the value of '288.15 K' - * + * * @param unit unit to convert * @param value value to convert * @return value expressed as a {@code LinearUnit} @@ -48,11 +48,11 @@ public final class LinearUnit extends Unit { Objects.requireNonNull(unit, "unit must not be null.").getBase(), unit.convertToBase(value), NameSymbol.EMPTY); } - + /** * Gets a {@code LinearUnit} from a unit and a value. For example, converts * '59 °F' to a linear unit with the value of '288.15 K' - * + * * @param unit unit to convert * @param value value to convert * @param ns name(s) and symbol of unit @@ -67,7 +67,7 @@ public final class LinearUnit extends Unit { Objects.requireNonNull(unit, "unit must not be null.").getBase(), unit.convertToBase(value), ns); } - + /** * @param unit unit to get base version of * @return the base unit associated with {@code unit}, as a @@ -78,12 +78,12 @@ public final class LinearUnit extends Unit { public static LinearUnit getBase(final Unit unit) { return new LinearUnit(unit.getBase(), 1, NameSymbol.EMPTY); } - + /** * Gets a {@code LinearUnit} from a unit base and a conversion factor. In * other words, gets the product of {@code unitBase} and * {@code conversionFactor}, expressed as a {@code LinearUnit}. - * + * * @param unitBase unit base to multiply by * @param conversionFactor number to multiply base by * @return product of base and conversion factor @@ -95,12 +95,12 @@ public final class LinearUnit extends Unit { final double conversionFactor) { return new LinearUnit(unitBase, conversionFactor, NameSymbol.EMPTY); } - + /** * Gets a {@code LinearUnit} from a unit base and a conversion factor. In * other words, gets the product of {@code unitBase} and * {@code conversionFactor}, expressed as a {@code LinearUnit}. - * + * * @param unitBase unit base to multiply by * @param conversionFactor number to multiply base by * @param ns name(s) and symbol of unit @@ -113,22 +113,22 @@ public final class LinearUnit extends Unit { final double conversionFactor, final NameSymbol ns) { return new LinearUnit(unitBase, conversionFactor, ns); } - + /** * The value of this unit as represented in its base form. Mathematically, - * + * * <pre> * this = conversionFactor * getBase() * </pre> - * + * * @since 2019-10-16 * @since v0.3.0 */ private final double conversionFactor; - + /** * Creates the {@code LinearUnit}. - * + * * @param unitBase base of linear unit * @param conversionFactor conversion factor between base and unit * @since 2019-10-16 @@ -139,21 +139,21 @@ public final class LinearUnit extends Unit { super(unitBase, ns); this.conversionFactor = conversionFactor; } - + /** * {@inheritDoc} - * + * * Converts by dividing by {@code conversionFactor} */ @Override protected double convertFromBase(final double value) { return value / this.getConversionFactor(); } - + /** * Converts an {@code UncertainDouble} value expressed in this unit to an * {@code UncertainValue} value expressed in {@code other}. - * + * * @param other unit to convert to * @param value value to convert * @return converted value @@ -170,35 +170,34 @@ public final class LinearUnit extends Unit { if (this.canConvertTo(other)) return value.timesExact( this.getConversionFactor() / other.getConversionFactor()); - 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)); + } - + /** * {@inheritDoc} - * + * * Converts by multiplying by {@code conversionFactor} */ @Override protected double convertToBase(final double value) { return value * this.getConversionFactor(); } - + /** * Converts an {@code UncertainDouble} to the base unit. - * + * * @since 2020-09-07 * @since v0.3.0 */ UncertainDouble convertToBase(final UncertainDouble value) { return value.timesExact(this.getConversionFactor()); } - + /** * Divides this unit by a scalar. - * + * * @param divisor scalar to divide by * @return quotient * @since 2018-12-23 @@ -207,10 +206,10 @@ public final class LinearUnit extends Unit { public LinearUnit dividedBy(final double divisor) { return valueOf(this.getBase(), this.getConversionFactor() / divisor); } - + /** * Returns the quotient of this unit and another. - * + * * @param divisor unit to divide by * @return quotient of two units * @throws NullPointerException if {@code divisor} is null @@ -219,24 +218,24 @@ public final class LinearUnit extends Unit { */ public LinearUnit dividedBy(final LinearUnit divisor) { Objects.requireNonNull(divisor, "other must not be null"); - + // divide the units - final ObjectProduct<BaseUnit> base = this.getBase() + final var base = this.getBase() .dividedBy(divisor.getBase()); return valueOf(base, this.getConversionFactor() / divisor.getConversionFactor()); } - + /** * {@inheritDoc} - * + * * Uses the base and conversion factor of units to test for equality. */ @Override public boolean equals(final Object obj) { if (!(obj instanceof LinearUnit)) return false; - final LinearUnit other = (LinearUnit) obj; + final var other = (LinearUnit) obj; return Objects.equals(this.getBase(), other.getBase()) && Double.compare(this.getConversionFactor(), other.getConversionFactor()) == 0; @@ -244,18 +243,18 @@ public final class LinearUnit extends Unit { /** * @param other unit to test equality with - * @return true iff this unit and other are equal, - * ignoring small differences caused by floating-point error. - * - * @apiNote This method is not transitive, - * so it cannot be used as an equals method. + * @return true iff this unit and other are equal, ignoring small differences + * caused by floating-point error. + * + * @apiNote This method is not transitive, so it cannot be used as an equals + * method. */ public boolean equalsApproximately(final LinearUnit other) { return Objects.equals(this.getBase(), other.getBase()) && DecimalComparison.equals(this.getConversionFactor(), other.getConversionFactor()); } - + /** * @return conversion factor * @since 2019-10-16 @@ -264,10 +263,10 @@ public final class LinearUnit extends Unit { public double getConversionFactor() { return this.conversionFactor; } - + /** * {@inheritDoc} - * + * * Uses the base and conversion factor to compute a hash code. */ @Override @@ -275,7 +274,7 @@ public final class LinearUnit extends Unit { return 31 * this.getBase().hashCode() + Double.hashCode(this.getConversionFactor()); } - + /** * @return whether this unit is equivalent to a {@code BaseUnit} (i.e. there * is a {@code BaseUnit b} where @@ -286,7 +285,7 @@ public final class LinearUnit extends Unit { public boolean isBase() { return this.isCoherent() && this.getBase().isSingleObject(); } - + /** * @return whether this unit is coherent (i.e. has conversion factor 1) * @since 2019-10-16 @@ -295,7 +294,7 @@ public final class LinearUnit extends Unit { public boolean isCoherent() { return this.getConversionFactor() == 1; } - + /** * Returns the difference of this unit and another. * <p> @@ -304,7 +303,7 @@ public final class LinearUnit extends Unit { * does not meet this condition, an {@code IllegalArgumentException} will be * thrown. * </p> - * + * * @param subtrahend unit to subtract * @return difference of units * @throws IllegalArgumentException if {@code subtrahend} is not compatible @@ -315,18 +314,18 @@ public final class LinearUnit extends Unit { */ public LinearUnit minus(final LinearUnit subtrahend) { Objects.requireNonNull(subtrahend, "addend must not be null."); - + // reject subtrahends that cannot be added to this unit if (!this.getBase().equals(subtrahend.getBase())) throw new IllegalArgumentException(String.format( "Incompatible units for subtraction \"%s\" and \"%s\".", this, subtrahend)); - + // subtract the units return valueOf(this.getBase(), this.getConversionFactor() - subtrahend.getConversionFactor()); } - + /** * Returns the sum of this unit and another. * <p> @@ -335,7 +334,7 @@ public final class LinearUnit extends Unit { * does not meet this condition, an {@code IllegalArgumentException} will be * thrown. * </p> - * + * * @param addend unit to add * @return sum of units * @throws IllegalArgumentException if {@code addend} is not compatible for @@ -346,21 +345,21 @@ public final class LinearUnit extends Unit { */ public LinearUnit plus(final LinearUnit addend) { Objects.requireNonNull(addend, "addend must not be null."); - + // reject addends that cannot be added to this unit if (!this.getBase().equals(addend.getBase())) throw new IllegalArgumentException(String.format( "Incompatible units for addition \"%s\" and \"%s\".", this, addend)); - + // add the units return valueOf(this.getBase(), this.getConversionFactor() + addend.getConversionFactor()); } - + /** * Multiplies this unit by a scalar. - * + * * @param multiplier scalar to multiply by * @return product * @since 2018-12-23 @@ -369,10 +368,10 @@ public final class LinearUnit extends Unit { public LinearUnit times(final double multiplier) { return valueOf(this.getBase(), this.getConversionFactor() * multiplier); } - + /** * Returns the product of this unit and another. - * + * * @param multiplier unit to multiply by * @return product of two units * @throws NullPointerException if {@code multiplier} is null @@ -381,24 +380,24 @@ public final class LinearUnit extends Unit { */ public LinearUnit times(final LinearUnit multiplier) { Objects.requireNonNull(multiplier, "other must not be null"); - + // multiply the units - final ObjectProduct<BaseUnit> base = this.getBase() + final var base = this.getBase() .times(multiplier.getBase()); return valueOf(base, this.getConversionFactor() * multiplier.getConversionFactor()); } - + @Override public String toDefinitionString() { return Double.toString(this.conversionFactor) + (this.getBase().equals(ObjectProduct.empty()) ? "" : " " + this.getBase().toString(BaseUnit::getShortName)); } - + /** * Returns this unit but to an exponent. - * + * * @param exponent exponent to exponentiate unit to * @return exponentiated unit * @since 2019-01-15 @@ -408,11 +407,11 @@ public final class LinearUnit extends Unit { return valueOf(this.getBase().toExponent(exponent), Math.pow(this.conversionFactor, exponent)); } - + /** * Returns this unit to an exponent, rounding the resulting dimensions to the * nearest integer. - * + * * @param exponent exponent to raise unit to * @return result of rounded exponentation * @since 2024-08-22 @@ -423,12 +422,12 @@ public final class LinearUnit extends Unit { return valueOf(this.getBase().toExponentRounded(exponent), Math.pow(this.conversionFactor, exponent)); } - + @Override public LinearUnit withName(final NameSymbol ns) { return valueOf(this.getBase(), this.getConversionFactor(), ns); } - + /** * Returns the result of applying {@code prefix} to this unit. * <p> @@ -438,7 +437,7 @@ public final class LinearUnit extends Unit { * have a symbol. <br> * This method ignores alternate names of both this unit and the provided * prefix. - * + * * @param prefix prefix to apply * @return unit with prefix * @since 2019-03-18 @@ -446,8 +445,8 @@ public final class LinearUnit extends Unit { * @throws NullPointerException if prefix is null */ public LinearUnit withPrefix(final UnitPrefix prefix) { - final LinearUnit unit = this.times(prefix.getMultiplier()); - + final var unit = this.times(prefix.getMultiplier()); + // create new name and symbol, if possible final String name; if (this.getPrimaryName().isPresent() @@ -456,14 +455,14 @@ public final class LinearUnit extends Unit { } else { name = null; } - + final String symbol; if (this.getSymbol().isPresent() && prefix.getSymbol().isPresent()) { symbol = prefix.getSymbol().get() + this.getSymbol().get(); } else { symbol = null; } - + return unit.withName(NameSymbol.ofNullable(name, symbol)); } } diff --git a/src/main/java/sevenUnits/unit/LinearUnitValue.java b/src/main/java/sevenUnits/unit/LinearUnitValue.java index 86520d7..9a99e00 100644 --- a/src/main/java/sevenUnits/unit/LinearUnitValue.java +++ b/src/main/java/sevenUnits/unit/LinearUnitValue.java @@ -20,7 +20,6 @@ import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.Optional; import sevenUnits.utils.DecimalComparison; import sevenUnits.utils.ObjectProduct; @@ -28,10 +27,10 @@ import sevenUnits.utils.UncertainDouble; /** * A possibly uncertain value expressed in a linear 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 * @since v0.3.0 @@ -42,14 +41,14 @@ public final class LinearUnitValue { /** * Gets an exact {@code LinearUnitValue} - * + * * @param unit unit to express with * @param value value to express * @return exact {@code LinearUnitValue} instance * @since 2020-07-26 * @since v0.3.0 */ - public static final LinearUnitValue getExact(final LinearUnit unit, + public static LinearUnitValue getExact(final LinearUnit unit, final double value) { return new LinearUnitValue( Objects.requireNonNull(unit, "unit must not be null"), @@ -58,14 +57,14 @@ public final class LinearUnitValue { /** * Gets an uncertain {@code LinearUnitValue} - * + * * @param unit unit to express with * @param value value to express * @return uncertain {@code LinearUnitValue} instance * @since 2020-07-26 * @since v0.3.0 */ - public static final LinearUnitValue of(final LinearUnit unit, + public static LinearUnitValue of(final LinearUnit unit, final UncertainDouble value) { return new LinearUnitValue( Objects.requireNonNull(unit, "unit must not be null"), @@ -93,7 +92,7 @@ public final class LinearUnitValue { * @since 2020-08-04 * @since v0.3.0 */ - public final UnitValue asUnitValue() { + public UnitValue asUnitValue() { return UnitValue.of(this.unit, this.value.value()); } @@ -103,20 +102,20 @@ public final class LinearUnitValue { * @since 2020-07-26 * @since v0.3.0 */ - public final boolean canConvertTo(final LinearUnit other) { + public boolean canConvertTo(final LinearUnit other) { return this.unit.canConvertTo(other); } /** * Returns a LinearUnitValue that represents the same value expressed in a * different unit - * + * * @param other new unit to express value in * @return value expressed in {@code other} * @since 2020-07-26 * @since v0.3.0 */ - public final LinearUnitValue convertTo(final LinearUnit other) { + public LinearUnitValue convertTo(final LinearUnit other) { return LinearUnitValue.of(other, this.unit.convertTo(other, this.value)); } @@ -131,7 +130,7 @@ public final class LinearUnitValue { * @since 2024-08-15 * @since v1.0.0 */ - public final List<LinearUnitValue> convertToMultiple( + public List<LinearUnitValue> convertToMultiple( final List<LinearUnit> others) { if (others.size() < 1) throw new IllegalArgumentException("Must have at least one unit"); @@ -141,17 +140,17 @@ public final class LinearUnitValue { "All provided units must have the same base as the value."); } - LinearUnitValue remaining = this; + var remaining = this; final List<LinearUnitValue> values = new ArrayList<>(others.size()); for (final LinearUnit unit : others.subList(0, others.size() - 1)) { - final LinearUnitValue remainingInUnit = remaining.convertTo(unit); - final LinearUnitValue value = getExact(unit, + final var remainingInUnit = remaining.convertTo(unit); + final var value = getExact(unit, Math.floor(remainingInUnit.getValueExact() + 1e-12)); values.add(value); remaining = remaining.minus(value); } - final LinearUnitValue lastValue = remaining + final var lastValue = remaining .convertTo(others.get(others.size() - 1)); values.add(lastValue); return values; @@ -159,7 +158,7 @@ public final class LinearUnitValue { /** * Divides this value by a scalar - * + * * @param divisor value to divide by * @return multiplied value * @since 2020-07-28 @@ -171,7 +170,7 @@ public final class LinearUnitValue { /** * Divides this value by another value - * + * * @param divisor value to multiply by * @return quotient * @since 2020-07-28 @@ -186,7 +185,7 @@ public final class LinearUnitValue { * 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. - * + * * @since 2020-07-26 * @since v0.3.0 * @see #equals(Object, boolean) @@ -195,7 +194,7 @@ public final class LinearUnitValue { public boolean equals(final Object obj) { if (!(obj instanceof LinearUnitValue)) return false; - final LinearUnitValue other = (LinearUnitValue) obj; + final var other = (LinearUnitValue) obj; return Objects.equals(this.unit.getBase(), other.unit.getBase()) && this.unit.convertToBase(this.value) .equals(other.unit.convertToBase(other.value)); @@ -205,13 +204,13 @@ public final class LinearUnitValue { * 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. - * + * * @param obj object to test equality with * @param avoidFPErrors if true, this method will attempt to avoid * floating-point errors, at the cost of not always * being transitive. * @return true iff this and obj are equal - * + * * @since 2020-07-28 * @since v0.3.0 */ @@ -220,7 +219,7 @@ public final class LinearUnitValue { return this.equals(obj); if (!(obj instanceof LinearUnitValue)) return false; - final LinearUnitValue other = (LinearUnitValue) obj; + final var other = (LinearUnitValue) obj; return Objects.equals(this.unit.getBase(), other.unit.getBase()) && DecimalComparison.equals(this.unit.convertToBase(this.value), other.unit.convertToBase(other.value)); @@ -229,7 +228,7 @@ public final class LinearUnitValue { /** * @param other another {@code LinearUnitValue} * @return true iff this and other are within each other's uncertainty range - * + * * @since 2020-07-26 * @since v0.3.0 */ @@ -237,9 +236,9 @@ public final class LinearUnitValue { if (other == null || !Objects.equals(this.unit.getBase(), other.unit.getBase())) return false; - final LinearUnit base = LinearUnit.valueOf(this.unit.getBase(), 1); - final LinearUnitValue thisBase = this.convertTo(base); - final LinearUnitValue otherBase = other.convertTo(base); + final var base = LinearUnit.valueOf(this.unit.getBase(), 1); + final var thisBase = this.convertTo(base); + final var otherBase = other.convertTo(base); return thisBase.value.equivalent(otherBase.value); } @@ -249,7 +248,7 @@ public final class LinearUnitValue { * @since 2020-09-29 * @since v0.3.0 */ - public final LinearUnit getUnit() { + public LinearUnit getUnit() { return this.unit; } @@ -258,7 +257,7 @@ public final class LinearUnitValue { * @since 2020-09-29 * @since v0.3.0 */ - public final UncertainDouble getValue() { + public UncertainDouble getValue() { return this.value; } @@ -267,7 +266,7 @@ public final class LinearUnitValue { * @since 2020-09-07 * @since v0.3.0 */ - public final double getValueExact() { + public double getValueExact() { return this.value.value(); } @@ -280,7 +279,7 @@ public final class LinearUnitValue { /** * Returns the difference of this value and another, expressed in this * value's unit - * + * * @param subtrahend value to subtract * @return difference of values * @throws IllegalArgumentException if {@code subtrahend} has a unit that is @@ -296,14 +295,14 @@ public final class LinearUnitValue { "Incompatible units for subtraction \"%s\" and \"%s\".", this.unit, subtrahend.unit)); - final LinearUnitValue otherConverted = subtrahend.convertTo(this.unit); + final var otherConverted = subtrahend.convertTo(this.unit); return LinearUnitValue.of(this.unit, this.value.minus(otherConverted.value)); } /** * Returns the sum of this value and another, expressed in this value's unit - * + * * @param addend value to add * @return sum of values * @throws IllegalArgumentException if {@code addend} has a unit that is not @@ -319,14 +318,14 @@ public final class LinearUnitValue { "Incompatible units for addition \"%s\" and \"%s\".", this.unit, addend.unit)); - final LinearUnitValue otherConverted = addend.convertTo(this.unit); + final var otherConverted = addend.convertTo(this.unit); return LinearUnitValue.of(this.unit, this.value.plus(otherConverted.value)); } /** * Multiplies this value by a scalar - * + * * @param multiplier value to multiply by * @return multiplied value * @since 2020-07-28 @@ -338,7 +337,7 @@ public final class LinearUnitValue { /** * Multiplies this value by another value - * + * * @param multiplier value to multiply by * @return product * @since 2020-07-28 @@ -351,7 +350,7 @@ public final class LinearUnitValue { /** * Raises a value to an exponent - * + * * @param exponent exponent to raise to * @return result of exponentiation * @since 2020-07-28 @@ -364,7 +363,7 @@ public final class LinearUnitValue { /** * Raises this value to an exponent, rounding all dimensions to integers. - * + * * @param exponent exponent to raise this value to * @return result of exponentation * @@ -391,28 +390,28 @@ public final class LinearUnitValue { * single numbers. * <p> * Non-exact values are rounded intelligently based on their uncertainty. - * + * * @param showUncertainty whether to show the value's uncertainty - * @param roundingMode how to round numbers in this string + * @param roundingMode how to round numbers in this string * @return string representing this value - * + * * @since 2020-07-26 * @since v0.3.0 */ public String toString(final boolean showUncertainty, RoundingMode roundingMode) { - final Optional<String> primaryName = this.unit.getPrimaryName(); - final Optional<String> symbol = this.unit.getSymbol(); - final String chosenName = symbol.orElse(primaryName.orElse(null)); + final var primaryName = this.unit.getPrimaryName(); + final var symbol = this.unit.getSymbol(); + final var chosenName = symbol.orElse(primaryName.orElse(null)); - final UncertainDouble baseValue = this.unit.convertToBase(this.value); + final var baseValue = this.unit.convertToBase(this.value); // get rounded strings // if showUncertainty is true, add brackets around the string - final String valueString = (showUncertainty ? "(" : "") + final var valueString = (showUncertainty ? "(" : "") + this.value.toString(showUncertainty, roundingMode) + (showUncertainty ? ")" : ""); - final String baseValueString = (showUncertainty ? "(" : "") + final var baseValueString = (showUncertainty ? "(" : "") + baseValue.toString(showUncertainty, roundingMode) + (showUncertainty ? ")" : ""); @@ -421,7 +420,6 @@ public final class LinearUnitValue { return String.format("%s unnamed unit (= %s %s)", valueString, baseValueString, this.unit.getBase() .toString(unit -> unit.getSymbol().orElseThrow())); - else - return String.format("%s %s", valueString, chosenName); + return String.format("%s %s", valueString, chosenName); } } diff --git a/src/main/java/sevenUnits/unit/LoadingException.java b/src/main/java/sevenUnits/unit/LoadingException.java index 7b3d708..2a75c99 100644 --- a/src/main/java/sevenUnits/unit/LoadingException.java +++ b/src/main/java/sevenUnits/unit/LoadingException.java @@ -22,15 +22,17 @@ import java.util.Optional; /** * An exception that occurred when loading a file. This wrapper class adds more * info about the error. - * + * * @author Adrien Hopkins * @since 2024-08-22 * @since v1.0.0 */ public final class LoadingException extends RuntimeException { /** The type of file that was being loaded. */ - public static enum FileType { - @SuppressWarnings("javadoc") UNIT, @SuppressWarnings("javadoc") DIMENSION + public enum FileType { + @SuppressWarnings("javadoc") + UNIT, @SuppressWarnings("javadoc") + DIMENSION } private static final long serialVersionUID = -8167971828216907607L; @@ -45,7 +47,7 @@ public final class LoadingException extends RuntimeException { /** * Create a LoadingException from some information, without a file. - * + * * @param lineNumber line number error happened on * @param line text of invalid line * @param fileType type of file @@ -63,7 +65,7 @@ public final class LoadingException extends RuntimeException { /** * Create a LoadingException from some information, with a file. - * + * * @param lineNumber line number error happened on * @param line text of invalid line * @param file file error happened on @@ -80,16 +82,12 @@ public final class LoadingException extends RuntimeException { this.problem = problem; } - /** - * @return the file this error happened in, if there is one - */ + /** @return the file this error happened in, if there is one */ public Optional<Path> file() { return this.file; } - /** - * @return type of file that this error happened in - */ + /** @return type of file that this error happened in */ public FileType fileType() { return this.fileType; } @@ -107,23 +105,17 @@ public final class LoadingException extends RuntimeException { this.line, this.problem)); } - /** - * @return text of line that caused this error - */ + /** @return text of line that caused this error */ public String line() { return this.line; } - /** - * @return number of line that caused this error - */ + /** @return number of line that caused this error */ public long lineNumber() { return this.lineNumber; } - /** - * @return the error, as an exception - */ + /** @return the error, as an exception */ public RuntimeException problem() { return this.problem; } diff --git a/src/main/java/sevenUnits/unit/Metric.java b/src/main/java/sevenUnits/unit/Metric.java index 34fd0b8..e712dc3 100644 --- a/src/main/java/sevenUnits/unit/Metric.java +++ b/src/main/java/sevenUnits/unit/Metric.java @@ -24,16 +24,16 @@ import sevenUnits.utils.ObjectProduct; /** * All of the units, prefixes and dimensions that are used by the SI, as well as * some outside the SI. - * + * * <p> * This class does not include prefixed units. To obtain prefixed units, use * {@link LinearUnit#withPrefix}: - * + * * <pre> * LinearUnit KILOMETRE = SI.METRE.withPrefix(SI.KILO); * </pre> - * - * + * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.3.0 @@ -107,7 +107,7 @@ public final class Metric { /** * Constants that relate to the SI or other systems. - * + * * @author Adrien Hopkins * @since 2019-11-08 * @since v0.3.0 @@ -350,7 +350,7 @@ public final class Metric { pr -> 0.5 * Math.log(pr), Np -> Math.exp(2 * Np)) .withName(NameSymbol.of("neper", "Np")); public static final Unit BEL = Unit.fromConversionFunctions(ONE.getBase(), - pr -> Math.log10(pr), dB -> Math.pow(10, dB)) + Math::log10, dB -> Math.pow(10, dB)) .withName(NameSymbol.of("bel", "B")); public static final Unit DECIBEL = Unit .fromConversionFunctions(ONE.getBase(), pr -> 10 * Math.log10(pr), diff --git a/src/main/java/sevenUnits/unit/USCustomary.java b/src/main/java/sevenUnits/unit/USCustomary.java index be8c5e2..ef12043 100644 --- a/src/main/java/sevenUnits/unit/USCustomary.java +++ b/src/main/java/sevenUnits/unit/USCustomary.java @@ -18,7 +18,7 @@ package sevenUnits.unit; /** * A static utility class that contains units in the US Customary system. - * + * * @author Adrien Hopkins * @since 2019-10-21 * @since v0.3.0 @@ -29,7 +29,7 @@ package sevenUnits.unit; public final class USCustomary { /** * US Customary units that measure area - * + * * @author Adrien Hopkins * @since 2019-11-08 * @since v0.3.0 @@ -48,7 +48,7 @@ public final class USCustomary { /** * US Customary units that measure length - * + * * @author Adrien Hopkins * @since 2019-10-28 * @since v0.3.0 @@ -79,7 +79,7 @@ public final class USCustomary { /** * mass units - * + * * @author Adrien Hopkins * @since 2019-11-08 * @since v0.3.0 @@ -100,7 +100,7 @@ public final class USCustomary { /** * Volume units - * + * * @author Adrien Hopkins * @since 2019-11-08 * @since v0.3.0 diff --git a/src/main/java/sevenUnits/unit/Unit.java b/src/main/java/sevenUnits/unit/Unit.java index d651fe2..40e6e0d 100644 --- a/src/main/java/sevenUnits/unit/Unit.java +++ b/src/main/java/sevenUnits/unit/Unit.java @@ -28,7 +28,7 @@ import sevenUnits.utils.ObjectProduct; /** * A unit that is composed of base units. - * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.3.0 @@ -37,14 +37,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. @@ -65,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. @@ -93,7 +93,7 @@ public abstract class Unit implements Nameable { /** * The combination of units that this unit is based on. - * + * * @since 2019-10-16 * @since v0.3.0 */ @@ -101,7 +101,7 @@ public abstract class Unit implements Nameable { /** * This unit's name(s) and symbol - * + * * @since 2020-09-07 * @since v0.3.0 */ @@ -117,21 +117,20 @@ public abstract class Unit implements Nameable { /** * 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 @@ -147,7 +146,7 @@ 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 @@ -171,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 @@ -185,12 +184,12 @@ 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 @@ -205,9 +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)); + throw new IllegalArgumentException( + String.format("Cannot convert from %s to %s.", this, other)); } /** @@ -222,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 @@ -249,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()) { @@ -287,9 +285,9 @@ 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 */ @@ -297,7 +295,7 @@ public abstract class Unit implements Nameable { // 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()) { @@ -318,9 +316,7 @@ public abstract class Unit implements Nameable { 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); } /** @@ -338,8 +334,7 @@ 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(); } /** diff --git a/src/main/java/sevenUnits/unit/UnitDatabase.java b/src/main/java/sevenUnits/unit/UnitDatabase.java index a85ec5f..05e9cc9 100644 --- a/src/main/java/sevenUnits/unit/UnitDatabase.java +++ b/src/main/java/sevenUnits/unit/UnitDatabase.java @@ -40,7 +40,6 @@ import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; -import java.util.regex.Matcher; import java.util.regex.Pattern; import sevenUnits.utils.ConditionalExistenceCollections; @@ -51,7 +50,7 @@ import sevenUnits.utils.UncertainDouble; /** * A database of units, prefixes and dimensions, and their names. - * + * * @author Adrien Hopkins * @since 2019-01-07 * @since v0.1.0 @@ -88,7 +87,7 @@ public final class UnitDatabase { * Because of ambiguities between prefixes (i.e. kilokilo = mega), * {@link #containsValue} and {@link #values()} currently ignore prefixes. * </p> - * + * * @author Adrien Hopkins * @since 2019-04-13 * @since v0.2.0 @@ -96,7 +95,7 @@ public final class UnitDatabase { private static final class PrefixedUnitMap implements Map<String, Unit> { /** * The class used for entry sets. - * + * * <p> * If the map that created this set is infinite in size (has at least one * unit and at least one prefix), this set is infinite as well. If this @@ -104,7 +103,7 @@ public final class UnitDatabase { * {@code IllegalStateException} instead of creating an infinite-sized * array. * </p> - * + * * @author Adrien Hopkins * @since 2019-04-13 * @since v0.2.0 @@ -113,7 +112,7 @@ public final class UnitDatabase { extends AbstractSet<Map.Entry<String, Unit>> { /** * The entry for this set. - * + * * @author Adrien Hopkins * @since 2019-04-14 * @since v0.2.0 @@ -125,7 +124,7 @@ public final class UnitDatabase { /** * Creates the {@code PrefixedUnitEntry}. - * + * * @param key key * @param value value * @since 2019-04-14 @@ -181,7 +180,7 @@ public final class UnitDatabase { * string is the string representation of the key, then the equals * ({@code =}) character, then the string representation of the * value. - * + * * @since 2019-05-03 * @since v0.3.0 */ @@ -194,7 +193,7 @@ public final class UnitDatabase { /** * An iterator that iterates over the units of a * {@code PrefixedUnitNameSet}. - * + * * @author Adrien Hopkins * @since 2019-04-14 * @since v0.2.0 @@ -214,9 +213,9 @@ public final class UnitDatabase { /** * Creates the * {@code UnitsDatabase.PrefixedUnitMap.PrefixedUnitNameSet.PrefixedUnitNameIterator}. - * + * * @param map map to base iterator on - * + * * @since 2019-04-14 * @since v0.2.0 */ @@ -232,7 +231,7 @@ public final class UnitDatabase { * @since v0.2.0 */ private String getCurrentUnitName() { - final StringBuilder unitName = new StringBuilder(); + final var unitName = new StringBuilder(); for (final int i : this.prefixCoordinates) { unitName.append(this.prefixNames.get(i)); } @@ -245,18 +244,15 @@ public final class UnitDatabase { public boolean hasNext() { if (this.unitNames.isEmpty()) return false; - else { - if (this.prefixNames.isEmpty()) - return this.prefixCoordinates.isEmpty() - && this.unitNamePosition < this.unitNames.size(); - else - return true; - } + if (this.prefixNames.isEmpty()) + return this.prefixCoordinates.isEmpty() + && this.unitNamePosition < this.unitNames.size(); + return true; } /** * Changes this iterator's position to the next available one. - * + * * @since 2019-04-14 * @since v0.2.0 */ @@ -272,7 +268,7 @@ public final class UnitDatabase { this.prefixCoordinates.add(0, 0); } else { // get the prefix coordinate to increment, then increment - int i = this.prefixCoordinates.size() - 1; + var i = this.prefixCoordinates.size() - 1; this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1); @@ -298,7 +294,7 @@ public final class UnitDatabase { @Override public Entry<String, Unit> next() { // get next element - final Entry<String, Unit> nextEntry = this.peek(); + final var nextEntry = this.peek(); // iterate to next position this.incrementPosition(); @@ -327,7 +323,7 @@ public final class UnitDatabase { } } - final String nextName = this.getCurrentUnitName(); + final var nextName = this.getCurrentUnitName(); return new PrefixedUnitEntry(nextName, this.map.get(nextName)); } @@ -335,7 +331,7 @@ public final class UnitDatabase { /** * Returns a string representation of the object. The exact details * of the representation are unspecified and subject to change. - * + * * @since 2019-05-03 * @since v0.3.0 */ @@ -352,7 +348,7 @@ public final class UnitDatabase { /** * Creates the {@code PrefixedUnitNameSet}. - * + * * @param map map that created this set * @since 2019-04-13 * @since v0.2.0 @@ -389,7 +385,7 @@ public final class UnitDatabase { // This is OK because I'm in a try-catch block, catching the // exact exception that would be thrown. @SuppressWarnings("unchecked") - final Entry<String, Unit> tempEntry = (Entry<String, Unit>) o; + final var tempEntry = (Entry<String, Unit>) o; entry = tempEntry; } catch (final ClassCastException e) { throw new IllegalArgumentException( @@ -447,55 +443,45 @@ public final class UnitDatabase { public int size() { if (this.map.units.isEmpty()) return 0; - else { - if (this.map.prefixes.isEmpty()) - return this.map.units.size(); - else - // infinite set - return Integer.MAX_VALUE; - } + if (this.map.prefixes.isEmpty()) + return this.map.units.size(); + // infinite set + return Integer.MAX_VALUE; } - /** - * @throws IllegalStateException if the set is infinite in size - */ + /** @throws IllegalStateException if the set is infinite in size */ @Override public Object[] toArray() { if (this.map.units.isEmpty() || this.map.prefixes.isEmpty()) return super.toArray(); - else - // infinite set - throw new IllegalStateException( - "Cannot make an infinite set into an array."); + // infinite set + throw new IllegalStateException( + "Cannot make an infinite set into an array."); } - /** - * @throws IllegalStateException if the set is infinite in size - */ + /** @throws IllegalStateException if the set is infinite in size */ @Override public <T> T[] toArray(final T[] a) { if (this.map.units.isEmpty() || this.map.prefixes.isEmpty()) return super.toArray(a); - else - // infinite set - throw new IllegalStateException( - "Cannot make an infinite set into an array."); + // infinite set + throw new IllegalStateException( + "Cannot make an infinite set into an array."); } @Override public String toString() { if (this.map.units.isEmpty() || this.map.prefixes.isEmpty()) return super.toString(); - else - return String.format( - "Infinite set of name-unit entries created from units %s and prefixes %s", - this.map.units, this.map.prefixes); + return String.format( + "Infinite set of name-unit entries created from units %s and prefixes %s", + this.map.units, this.map.prefixes); } } /** * The class used for unit name sets. - * + * * <p> * If the map that created this set is infinite in size (has at least one * unit and at least one prefix), this set is infinite as well. If this @@ -503,7 +489,7 @@ public final class UnitDatabase { * {@code IllegalStateException} instead of creating an infinite-sized * array. * </p> - * + * * @author Adrien Hopkins * @since 2019-04-13 * @since v0.2.0 @@ -513,7 +499,7 @@ public final class UnitDatabase { /** * An iterator that iterates over the units of a * {@code PrefixedUnitNameSet}. - * + * * @author Adrien Hopkins * @since 2019-04-14 * @since v0.2.0 @@ -533,9 +519,9 @@ public final class UnitDatabase { /** * Creates the * {@code UnitsDatabase.PrefixedUnitMap.PrefixedUnitNameSet.PrefixedUnitNameIterator}. - * + * * @param map map to base itorator on - * + * * @since 2019-04-14 * @since v0.2.0 */ @@ -551,7 +537,7 @@ public final class UnitDatabase { * @since v0.2.0 */ private String getCurrentUnitName() { - final StringBuilder unitName = new StringBuilder(); + final var unitName = new StringBuilder(); for (final int i : this.prefixCoordinates) { unitName.append(this.prefixNames.get(i)); } @@ -564,18 +550,15 @@ public final class UnitDatabase { public boolean hasNext() { if (this.unitNames.isEmpty()) return false; - else { - if (this.prefixNames.isEmpty()) - return this.prefixCoordinates.isEmpty() - && this.unitNamePosition < this.unitNames.size(); - else - return true; - } + if (this.prefixNames.isEmpty()) + return this.prefixCoordinates.isEmpty() + && this.unitNamePosition < this.unitNames.size(); + return true; } /** * Changes this iterator's position to the next available one. - * + * * @since 2019-04-14 * @since v0.2.0 */ @@ -591,7 +574,7 @@ public final class UnitDatabase { this.prefixCoordinates.add(0, 0); } else { // get the prefix coordinate to increment, then increment - int i = this.prefixCoordinates.size() - 1; + var i = this.prefixCoordinates.size() - 1; this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1); @@ -616,7 +599,7 @@ public final class UnitDatabase { @Override public String next() { - final String nextName = this.peek(); + final var nextName = this.peek(); this.incrementPosition(); @@ -649,7 +632,7 @@ public final class UnitDatabase { /** * Returns a string representation of the object. The exact details * of the representation are unspecified and subject to change. - * + * * @since 2019-05-03 * @since v0.3.0 */ @@ -666,7 +649,7 @@ public final class UnitDatabase { /** * Creates the {@code PrefixedUnitNameSet}. - * + * * @param map map that created this set * @since 2019-04-13 * @since v0.2.0 @@ -744,56 +727,46 @@ public final class UnitDatabase { public int size() { if (this.map.units.isEmpty()) return 0; - else { - if (this.map.prefixes.isEmpty()) - return this.map.units.size(); - else - // infinite set - return Integer.MAX_VALUE; - } + if (this.map.prefixes.isEmpty()) + return this.map.units.size(); + // infinite set + return Integer.MAX_VALUE; } - /** - * @throws IllegalStateException if the set is infinite in size - */ + /** @throws IllegalStateException if the set is infinite in size */ @Override public Object[] toArray() { if (this.map.units.isEmpty() || this.map.prefixes.isEmpty()) return super.toArray(); - else - // infinite set - throw new IllegalStateException( - "Cannot make an infinite set into an array."); + // infinite set + throw new IllegalStateException( + "Cannot make an infinite set into an array."); } - /** - * @throws IllegalStateException if the set is infinite in size - */ + /** @throws IllegalStateException if the set is infinite in size */ @Override public <T> T[] toArray(final T[] a) { if (this.map.units.isEmpty() || this.map.prefixes.isEmpty()) return super.toArray(a); - else - // infinite set - throw new IllegalStateException( - "Cannot make an infinite set into an array."); + // infinite set + throw new IllegalStateException( + "Cannot make an infinite set into an array."); } @Override public String toString() { if (this.map.units.isEmpty() || this.map.prefixes.isEmpty()) return super.toString(); - else - return String.format( - "Infinite set of name-unit entries created from units %s and prefixes %s", - this.map.units, this.map.prefixes); + return String.format( + "Infinite set of name-unit entries created from units %s and prefixes %s", + this.map.units, this.map.prefixes); } } /** * The units stored in this collection, without prefixes. - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -801,7 +774,7 @@ public final class UnitDatabase { /** * The available prefixes for use. - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -814,7 +787,7 @@ public final class UnitDatabase { /** * Creates the {@code PrefixedUnitMap}. - * + * * @param units map mapping unit names to units * @param prefixes map mapping prefix names to prefixes * @since 2019-04-13 @@ -865,11 +838,11 @@ public final class UnitDatabase { if (!(key instanceof String)) throw new IllegalArgumentException( "Attempted to test for a unit using a non-string name."); - final String unitName = (String) key; + final var unitName = (String) key; // Then, look for the longest prefix that is attached to a valid unit String longestPrefix = null; - int longestLength = 0; + var longestLength = 0; for (final String prefixName : this.prefixes.keySet()) { // a prefix name is valid if: @@ -881,7 +854,7 @@ public final class UnitDatabase { // linear units can have prefixes) if (unitName.startsWith(prefixName) && prefixName.length() > longestLength) { - final String rest = unitName.substring(prefixName.length()); + final var rest = unitName.substring(prefixName.length()); if (this.containsKey(rest) && this.get(rest) instanceof LinearUnit) { longestPrefix = prefixName; @@ -895,7 +868,7 @@ public final class UnitDatabase { /** * {@inheritDoc} - * + * * <p> * Because of ambiguities between prefixes (i.e. kilokilo = mega), this * method only tests for prefixless units. @@ -924,11 +897,11 @@ public final class UnitDatabase { if (!(key instanceof String)) throw new IllegalArgumentException( "Attempted to obtain a unit using a non-string name."); - final String unitName = (String) key; + final var unitName = (String) key; // Then, look for the longest prefix that is attached to a valid unit String longestPrefix = null; - int longestLength = 0; + var longestLength = 0; for (final String prefixName : this.prefixes.keySet()) { // a prefix name is valid if: @@ -940,7 +913,7 @@ public final class UnitDatabase { // linear units can have prefixes) if (unitName.startsWith(prefixName) && prefixName.length() > longestLength) { - final String rest = unitName.substring(prefixName.length()); + final var rest = unitName.substring(prefixName.length()); if (this.containsKey(rest) && this.get(rest) instanceof LinearUnit) { longestPrefix = prefixName; @@ -952,16 +925,14 @@ public final class UnitDatabase { // if none found, returns null if (longestPrefix == null) return null; - else { - // get necessary data - final String rest = unitName.substring(longestLength); - // this cast will not fail because I verified that it would work - // before selecting this prefix - final LinearUnit unit = (LinearUnit) this.get(rest); - final UnitPrefix prefix = this.prefixes.get(longestPrefix); - - return unit.withPrefix(prefix); - } + // get necessary data + final var rest = unitName.substring(longestLength); + // this cast will not fail because I verified that it would work + // before selecting this prefix + final var unit = (LinearUnit) this.get(rest); + final var prefix = this.prefixes.get(longestPrefix); + + return unit.withPrefix(prefix); } @Override @@ -1038,28 +1009,24 @@ public final class UnitDatabase { public int size() { if (this.units.isEmpty()) return 0; - else { - if (this.prefixes.isEmpty()) - return this.units.size(); - else - // infinite set - return Integer.MAX_VALUE; - } + if (this.prefixes.isEmpty()) + return this.units.size(); + // infinite set + return Integer.MAX_VALUE; } @Override public String toString() { if (this.units.isEmpty() || this.prefixes.isEmpty()) return new HashMap<>(this).toString(); - else - return String.format( - "Infinite map of name-unit entries created from units %s and prefixes %s", - this.units, this.prefixes); + return String.format( + "Infinite map of name-unit entries created from units %s and prefixes %s", + this.units, this.prefixes); } /** * {@inheritDoc} - * + * * <p> * Because of ambiguities between prefixes (i.e. kilokilo = mega), this * method ignores prefixes. @@ -1090,60 +1057,60 @@ public final class UnitDatabase { /** * The exponent operator - * + * * @param base base of exponentiation * @param exponentUnit exponent * @return result * @since 2019-04-10 * @since v0.2.0 */ - private static final LinearUnit exponentiateUnits(final LinearUnit base, + private static LinearUnit exponentiateUnits(final LinearUnit base, final LinearUnit exponentUnit) { if (!exponentUnit.getBase().equals(Metric.ONE.getBase())) throw new IllegalArgumentException(String.format( "Tried to exponentiate %s^%s, but exponents must be dimensionless numbers.", base, exponentUnit)); - final double exponent = exponentUnit.getConversionFactor(); + final var exponent = exponentUnit.getConversionFactor(); return base.toExponentRounded(exponent); } /** * The exponent operator - * + * * @param base base of exponentiation * @param exponentUnit exponent * @return result * @since 2020-08-04 * @since v0.3.0 */ - private static final LinearUnitValue exponentiateUnitValues( + private static LinearUnitValue exponentiateUnitValues( final LinearUnitValue base, final LinearUnitValue exponentValue) { if (!exponentValue.canConvertTo(Metric.ONE)) throw new IllegalArgumentException(String.format( "Tried to exponentiate %s^%s, but exponents must be dimensionless numbers.", base, exponentValue)); - final double exponent = exponentValue.getValueExact(); + final var exponent = exponentValue.getValueExact(); return base.toExponentRounded(exponent); } /** * Formats an expression so it can be parsed by the expression parser. - * + * * Specifically, puts spaces around all operators so they can be parsed as * words. - * + * * @param expression expression to format * @return formatted expression * @since 2025-06-07 * @since v1.0.0 */ - static final String formatExpression(String expression) { - String modifiedExpression = expression; + static String formatExpression(String expression) { + var modifiedExpression = expression; for (final String operator : Arrays.asList("\\*", "/", "\\|", "\\^")) { - modifiedExpression = modifiedExpression.replaceAll( - operator, " " + operator + " "); + modifiedExpression = modifiedExpression.replaceAll(operator, + " " + operator + " "); } modifiedExpression = modifiedExpression.replaceAll("\\s+", " "); @@ -1158,8 +1125,8 @@ public final class UnitDatabase { static <T> boolean isRemovableDuplicate(Map<String, T> map, Entry<String, T> entry) { for (final Entry<String, T> e : map.entrySet()) { - final String name = e.getKey(); - final T value = e.getValue(); + final var name = e.getKey(); + final var value = e.getValue(); if (lengthFirstComparator.compare(entry.getKey(), name) < 0 && Objects.equals(map.get(entry.getKey()), value)) return true; @@ -1169,7 +1136,7 @@ public final class UnitDatabase { /** * The units in this system, excluding prefixes. - * + * * @since 2019-01-07 * @since v0.1.0 */ @@ -1177,7 +1144,7 @@ public final class UnitDatabase { /** * The unit prefixes in this system. - * + * * @since 2019-01-14 * @since v0.1.0 */ @@ -1185,7 +1152,7 @@ public final class UnitDatabase { /** * The dimensions in this system. - * + * * @since 2019-03-14 * @since v0.2.0 */ @@ -1193,7 +1160,7 @@ public final class UnitDatabase { /** * A map mapping strings to units (including prefixes) - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -1201,7 +1168,7 @@ public final class UnitDatabase { /** * A map mapping strings to unit sets - * + * * @since 2024-08-16 * @since v1.0.0 */ @@ -1221,74 +1188,74 @@ public final class UnitDatabase { /** * A parser that can parse unit expressions. - * + * * @since 2019-03-22 * @since v0.2.0 */ private final ExpressionParser<LinearUnit> unitExpressionParser = new ExpressionParser.Builder<>( - this::getLinearUnit).addBinaryOperator("+", (o1, o2) -> o1.plus(o2), 0) - .addBinaryOperator("-", (o1, o2) -> o1.minus(o2), 0) - .addBinaryOperator("*", (o1, o2) -> o1.times(o2), 1) - .addBinaryOperator("space_times", (o1, o2) -> o1.times(o2), 2) + this::getLinearUnit).addBinaryOperator("+", LinearUnit::plus, 0) + .addBinaryOperator("-", LinearUnit::minus, 0) + .addBinaryOperator("*", LinearUnit::times, 1) + .addBinaryOperator("space_times", LinearUnit::times, 2) .addSpaceFunction("space_times") - .addBinaryOperator("/", (o1, o2) -> o1.dividedBy(o2), 1) - .addBinaryOperator("|", (o1, o2) -> o1.dividedBy(o2), 4) + .addBinaryOperator("/", LinearUnit::dividedBy, 1) + .addBinaryOperator("|", LinearUnit::dividedBy, 4) .addBinaryOperator("^", UnitDatabase::exponentiateUnits, 3).build(); /** * A parser that can parse unit value expressions. - * + * * @since 2020-08-04 * @since v0.3.0 */ private final ExpressionParser<LinearUnitValue> unitValueExpressionParser = new ExpressionParser.Builder<>( this::getLinearUnitValue) - .addBinaryOperator("+", (o1, o2) -> o1.plus(o2), 0) - .addBinaryOperator("-", (o1, o2) -> o1.minus(o2), 0) - .addBinaryOperator("*", (o1, o2) -> o1.times(o2), 1) - .addBinaryOperator("space_times", (o1, o2) -> o1.times(o2), 2) + .addBinaryOperator("+", LinearUnitValue::plus, 0) + .addBinaryOperator("-", LinearUnitValue::minus, 0) + .addBinaryOperator("*", LinearUnitValue::times, 1) + .addBinaryOperator("space_times", LinearUnitValue::times, 2) .addSpaceFunction("space_times") - .addBinaryOperator("/", (o1, o2) -> o1.dividedBy(o2), 1) - .addBinaryOperator("|", (o1, o2) -> o1.dividedBy(o2), 4) + .addBinaryOperator("/", LinearUnitValue::dividedBy, 1) + .addBinaryOperator("|", LinearUnitValue::dividedBy, 4) .addBinaryOperator("^", UnitDatabase::exponentiateUnitValues, 3) .build(); /** * A parser that can parse unit prefix expressions - * + * * @since 2019-04-13 * @since v0.2.0 */ private final ExpressionParser<UnitPrefix> prefixExpressionParser = new ExpressionParser.Builder<>( - this::getPrefix).addBinaryOperator("+", (o1, o2) -> o1.plus(o2), 0) - .addBinaryOperator("-", (o1, o2) -> o1.minus(o2), 0) - .addBinaryOperator("*", (o1, o2) -> o1.times(o2), 1) + this::getPrefix).addBinaryOperator("+", UnitPrefix::plus, 0) + .addBinaryOperator("-", UnitPrefix::minus, 0) + .addBinaryOperator("*", UnitPrefix::times, 1) .addSpaceFunction("*") - .addBinaryOperator("/", (o1, o2) -> o1.dividedBy(o2), 1) - .addBinaryOperator("|", (o1, o2) -> o1.dividedBy(o2), 3) + .addBinaryOperator("/", UnitPrefix::dividedBy, 1) + .addBinaryOperator("|", UnitPrefix::dividedBy, 3) .addBinaryOperator("^", (o1, o2) -> o1.toExponent(o2.getMultiplier()), 2) .build(); /** * A parser that can parse unit dimension expressions. - * + * * @since 2019-04-13 * @since v0.2.0 */ private final ExpressionParser<ObjectProduct<BaseDimension>> unitDimensionParser = new ExpressionParser.Builder<>( - this::getDimension).addBinaryOperator("*", (o1, o2) -> o1.times(o2), 0) + this::getDimension).addBinaryOperator("*", ObjectProduct::times, 0) .addSpaceFunction("*") - .addBinaryOperator("/", (o1, o2) -> o1.dividedBy(o2), 0) - .addBinaryOperator("|", (o1, o2) -> o1.dividedBy(o2), 2) + .addBinaryOperator("/", ObjectProduct::dividedBy, 0) + .addBinaryOperator("|", ObjectProduct::dividedBy, 2) .addNumericOperator("^", (o1, o2) -> { - final int exponent = (int) Math.round(o2.value()); + final var exponent = (int) Math.round(o2.value()); return o1.toExponent(exponent); }, 1).build(); /** * Creates the {@code UnitsDatabase}. - * + * * @since 2019-01-10 * @since v0.1.0 */ @@ -1298,7 +1265,7 @@ public final class UnitDatabase { /** * Creates the {@code UnitsDatabase} - * + * * @param prefixRepetitionRule the rule that determines when prefix * repetition is allowed * @since 2020-08-26 @@ -1318,7 +1285,7 @@ public final class UnitDatabase { /** * Adds a unit dimension to the database. - * + * * @param name dimension's name * @param dimension dimension to add * @throws NullPointerException if name or dimension is null @@ -1329,14 +1296,14 @@ public final class UnitDatabase { final ObjectProduct<BaseDimension> dimension) { Objects.requireNonNull(name, "name may not be null"); Objects.requireNonNull(dimension, "dimension may not be null"); - final ObjectProduct<BaseDimension> namedDimension = dimension + final var namedDimension = dimension .withName(dimension.getNameSymbol().withExtraName(name)); this.dimensions.put(name, namedDimension); } /** * Adds to the list from a line in a unit dimension file. - * + * * @param line line to look at * @param lineCounter number of line, for error messages * @since 2019-04-10 @@ -1354,13 +1321,13 @@ public final class UnitDatabase { } // divide line into name and expression - final Matcher lineMatcher = NAME_EXPRESSION.matcher(line); + final var lineMatcher = NAME_EXPRESSION.matcher(line); if (!lineMatcher.matches()) throw new IllegalArgumentException(String.format( "Error at line %d: Lines of a dimension file must consist of a dimension name, then spaces or tabs, then a dimension expression.", lineCounter)); - final String name = lineMatcher.group(1); - final String expression = lineMatcher.group(2); + final var name = lineMatcher.group(1); + final var expression = lineMatcher.group(2); // if (name.endsWith(" ")) { // System.err.printf("Warning - line %d's dimension name ends in a space", @@ -1380,7 +1347,7 @@ public final class UnitDatabase { /** * Adds a unit prefix to the database. - * + * * @param name prefix's name * @param prefix prefix to add * @throws NullPointerException if name or prefix is null @@ -1397,7 +1364,7 @@ public final class UnitDatabase { /** * Adds a unit to the database. - * + * * @param name unit's name * @param unit unit to add * @throws NullPointerException if unit is null @@ -1414,7 +1381,7 @@ public final class UnitDatabase { /** * Adds to the list from a line in a unit file. - * + * * @param line line to look at * @param lineCounter number of line, for error messages * @since 2019-04-10 @@ -1432,14 +1399,14 @@ public final class UnitDatabase { } // divide line into name and expression - final Matcher lineMatcher = NAME_EXPRESSION.matcher(line); + final var lineMatcher = NAME_EXPRESSION.matcher(line); if (!lineMatcher.matches()) throw new IllegalArgumentException(String.format( "Error at line %d: Lines of a unit file must consist of a unit name, then spaces or tabs, then a unit expression.", lineCounter)); - final String name = lineMatcher.group(1); + final var name = lineMatcher.group(1); - final String expression = lineMatcher.group(2); + final var expression = lineMatcher.group(2); // this code should never occur // if (name.endsWith(" ")) { @@ -1453,18 +1420,15 @@ public final class UnitDatabase { if (!this.containsUnitName(name)) throw new IllegalArgumentException(String .format("! used but no unit found (line %d).", lineCounter)); + } else if (name.endsWith("-")) { + final var prefixName = name.substring(0, name.length() - 1); + this.addPrefix(prefixName, this.getPrefixFromExpression(expression)); + } else if (expression.contains(";")) { + // it's a multi-unit + this.addUnitSet(name, this.getUnitSetFromExpression(expression)); } else { - if (name.endsWith("-")) { - final String prefixName = name.substring(0, name.length() - 1); - this.addPrefix(prefixName, - this.getPrefixFromExpression(expression)); - } else if (expression.contains(";")) { - // it's a multi-unit - this.addUnitSet(name, this.getUnitSetFromExpression(expression)); - } else { - // it's a unit, get the unit - this.addUnit(name, this.getUnitFromExpression(expression)); - } + // it's a unit, get the unit + this.addUnit(name, this.getUnitFromExpression(expression)); } } @@ -1491,7 +1455,7 @@ public final class UnitDatabase { /** * Removes all units, unit sets, prefixes and dimensions from this database. - * + * * @since 2022-02-26 * @since v0.4.0 */ @@ -1504,7 +1468,7 @@ public final class UnitDatabase { /** * Tests if the database has a unit dimension with this name. - * + * * @param name name to test * @return if database contains name * @since 2019-03-14 @@ -1516,7 +1480,7 @@ public final class UnitDatabase { /** * Tests if the database has a unit prefix with this name. - * + * * @param name name to test * @return if database contains name * @since 2019-01-13 @@ -1529,7 +1493,7 @@ public final class UnitDatabase { /** * Tests if the database has a unit with this name, taking prefixes into * consideration - * + * * @param name name to test * @return if database contains name * @since 2019-01-13 @@ -1541,7 +1505,7 @@ public final class UnitDatabase { /** * Returns true iff there is a unit set with this name. - * + * * @param name name to check for * @return true iff there is a unit set with this name * @@ -1564,7 +1528,7 @@ public final class UnitDatabase { /** * Evaluates a unit expression, following the same rules as * {@link #getUnitFromExpression}. - * + * * @param expression expression to parse * @return {@code LinearUnitValue} representing value of expression * @since 2020-08-04 @@ -1583,7 +1547,7 @@ public final class UnitDatabase { /** * Gets a unit dimension from the database using its name. - * + * * @param name dimension's name * @return dimension * @since 2019-03-14 @@ -1591,12 +1555,11 @@ public final class UnitDatabase { */ public ObjectProduct<BaseDimension> getDimension(final String name) { Objects.requireNonNull(name, "name must not be null."); - final ObjectProduct<BaseDimension> dimension = this.dimensions.get(name); + final var dimension = this.dimensions.get(name); if (dimension == null) throw new NoSuchElementException( "No dimension with name \"" + name + "\"."); - else - return dimension; + return dimension; } /** @@ -1611,7 +1574,7 @@ public final class UnitDatabase { * multiplication)</li> * <li>The operator '^' which exponentiates. Exponents must be integers.</li> * </ul> - * + * * @param expression expression to parse * @return parsed unit dimension * @throws IllegalArgumentException if the expression cannot be parsed @@ -1627,13 +1590,14 @@ public final class UnitDatabase { if (this.containsDimensionName(expression)) return this.getDimension(expression); - return this.unitDimensionParser.parseExpression(formatExpression(expression)); + return this.unitDimensionParser + .parseExpression(formatExpression(expression)); } /** * Gets a unit. If it is linear, cast it to a LinearUnit and return it. * Otherwise, throw an {@code IllegalArgumentException}. - * + * * @param name unit's name * @return unit * @since 2019-03-22 @@ -1650,26 +1614,25 @@ public final class UnitDatabase { "Format nonlinear units like: unit(value)."); // solve the function - final Unit unit = this.getUnit(parts.get(0)); - final double value = Double.parseDouble( + final var unit = this.getUnit(parts.get(0)); + final var value = Double.parseDouble( parts.get(1).substring(0, parts.get(1).length() - 1)); return LinearUnit.fromUnitValue(unit, value); - } else { - // get a linear unit - final Unit unit = this.getUnit(name); - - if (unit instanceof LinearUnit) - return (LinearUnit) unit; - else - throw new IllegalArgumentException( - String.format("%s is not a linear unit.", name)); } + // get a linear unit + final var unit = this.getUnit(name); + + if (unit instanceof LinearUnit) + return (LinearUnit) unit; + else + throw new IllegalArgumentException( + String.format("%s is not a linear unit.", name)); } /** * Gets a {@code LinearUnitValue} from a unit name. Nonlinear units will be * converted to their base units. - * + * * @param name name of unit * @return {@code LinearUnitValue} instance * @since 2020-08-04 @@ -1687,7 +1650,7 @@ public final class UnitDatabase { /** * Gets a unit prefix from the database from its name - * + * * @param name prefix's name * @return prefix * @since 2019-01-10 @@ -1697,18 +1660,17 @@ public final class UnitDatabase { try { return UnitPrefix.valueOf(Double.parseDouble(name)); } catch (final NumberFormatException e) { - final UnitPrefix prefix = this.prefixes.get(name); + final var prefix = this.prefixes.get(name); if (prefix == null) throw new NoSuchElementException( "No prefix with name \"" + name + "\"."); - else - return prefix; + return prefix; } } /** * Gets all of the prefixes that are on a unit name, in application order. - * + * * @param unitName name of unit * @return prefixes * @since 2020-08-26 @@ -1716,12 +1678,12 @@ public final class UnitDatabase { */ List<UnitPrefix> getPrefixesFromName(final String unitName) { final List<UnitPrefix> prefixes = new ArrayList<>(); - String name = unitName; + var name = unitName; while (!this.prefixlessUnits.containsKey(name)) { // find the longest prefix String longestPrefixName = null; - int longestLength = name.length(); + var longestLength = name.length(); while (longestPrefixName == null) { longestLength--; @@ -1734,7 +1696,7 @@ public final class UnitDatabase { } // longest prefix found! - final UnitPrefix prefix = this.getPrefix(longestPrefixName); + final var prefix = this.getPrefix(longestPrefixName); prefixes.add(0, prefix); name = name.substring(longestLength); } @@ -1747,7 +1709,7 @@ public final class UnitDatabase { * Currently, prefix expressions are much simpler than unit expressions: They * are either a number or the name of another prefix * </p> - * + * * @param expression expression to input * @return prefix * @throws IllegalArgumentException if expression cannot be parsed @@ -1762,7 +1724,8 @@ public final class UnitDatabase { if (this.containsUnitName(expression)) return this.getPrefix(expression); - return this.prefixExpressionParser.parseExpression(formatExpression(expression)); + return this.prefixExpressionParser + .parseExpression(formatExpression(expression)); } /** @@ -1770,13 +1733,13 @@ public final class UnitDatabase { * @since 2020-08-26 * @since v0.3.0 */ - public final Predicate<List<UnitPrefix>> getPrefixRepetitionRule() { + public Predicate<List<UnitPrefix>> getPrefixRepetitionRule() { return this.prefixRepetitionRule; } /** * Gets a unit from the database from its name, looking for prefixes. - * + * * @param name unit's name * @return unit * @since 2019-01-10 @@ -1784,27 +1747,28 @@ public final class UnitDatabase { */ public Unit getUnit(final String name) { try { - final double value = Double.parseDouble(name); + final var value = Double.parseDouble(name); return Metric.ONE.times(value); } catch (final NumberFormatException e) { - final Unit unit = this.units.get(name); + final var unit = this.units.get(name); if (unit == null) throw new NoSuchElementException("No unit " + name); - else if (unit.getPrimaryName().isEmpty()) + if (unit.getPrimaryName().isEmpty()) return unit.withName(NameSymbol.ofName(name)); - else if (!unit.getPrimaryName().get().equals(name)) { + if (!unit.getPrimaryName().get().equals(name)) { final Set<String> otherNames = new HashSet<>(unit.getOtherNames()); otherNames.add(unit.getPrimaryName().get()); return unit.withName(NameSymbol.ofNullable(name, unit.getSymbol().orElse(null), otherNames)); - } else if (!unit.getOtherNames().contains(name)) { + } + if (!unit.getOtherNames().contains(name)) { final Set<String> otherNames = new HashSet<>(unit.getOtherNames()); otherNames.add(name); return unit.withName( NameSymbol.ofNullable(unit.getPrimaryName().orElse(null), unit.getSymbol().orElse(null), otherNames)); - } else - return unit; + } + return unit; } } @@ -1823,7 +1787,7 @@ public final class UnitDatabase { * <li>A number which is multiplied or divided</li> * </ul> * This method only works with linear units. - * + * * @param expression expression to parse * @return parsed unit * @throws IllegalArgumentException if the expression cannot be parsed @@ -1845,7 +1809,7 @@ public final class UnitDatabase { /** * Get a unit set from its name, throwing a {@link NoSuchElementException} if * there is none. - * + * * @param name name of unit set * @return unit set with that name * @@ -1853,7 +1817,7 @@ public final class UnitDatabase { * @since v1.0.0 */ public List<LinearUnit> getUnitSet(String name) { - final List<LinearUnit> unitSet = this.unitSets.get(name); + final var unitSet = this.unitSets.get(name); if (unitSet == null) throw new NoSuchElementException("No unit set with name " + name); return unitSet; @@ -1866,20 +1830,19 @@ public final class UnitDatabase { * @since v1.0.0 */ List<LinearUnit> getUnitSetFromExpression(String expression) { - final String[] parts = expression.split(";"); + final var parts = expression.split(";"); final List<LinearUnit> units = new ArrayList<>(parts.length); for (final String unitName : parts) { - final Unit unit = this.getUnitFromExpression(unitName.trim()); + final var unit = this.getUnitFromExpression(unitName.trim()); - if (!(unit instanceof LinearUnit)) { + if (!(unit instanceof LinearUnit)) throw new IllegalArgumentException(String.format( "Unit '%s' is in a unit-set expression, but is not linear.", unitName)); - } else if (units.size() > 0 && !unit.canConvertTo(units.get(0))) { + if (units.size() > 0 && !unit.canConvertTo(units.get(0))) throw new IllegalArgumentException(String.format( "Units in expression '%s' have different dimensions.", expression)); - } units.add((LinearUnit) unit); } @@ -1904,7 +1867,7 @@ public final class UnitDatabase { * no unit is found, an IllegalArgumentException is thrown. This is used to * define initial units and ensure that the database contains them.</li> * </ul> - * + * * @param file file to read * @throws NullPointerException if file is null * @return list of errors that happened when loading file @@ -1915,7 +1878,7 @@ public final class UnitDatabase { Objects.requireNonNull(file, "file must not be null."); final List<LoadingException> errors = new ArrayList<>(); try { - long lineCounter = 0; + var lineCounter = 0L; for (final String line : Files.readAllLines(file)) { try { this.addDimensionFromLine(line, ++lineCounter); @@ -1944,10 +1907,10 @@ public final class UnitDatabase { public List<LoadingException> loadDimensionsFromStream( final InputStream stream) { final List<LoadingException> errors = new ArrayList<>(); - try (final Scanner scanner = new Scanner(stream)) { - long lineCounter = 0; + try (final var scanner = new Scanner(stream)) { + var lineCounter = 0L; while (scanner.hasNextLine()) { - final String line = scanner.nextLine(); + final var line = scanner.nextLine(); try { this.addDimensionFromLine(line, ++lineCounter); } catch (IllegalArgumentException | NoSuchElementException e) { @@ -1976,7 +1939,7 @@ public final class UnitDatabase { * no unit is found, an IllegalArgumentException is thrown. This is used to * define initial units and ensure that the database contains them.</li> * </ul> - * + * * @param file file to read * @throws NullPointerException if file is null * @return list of errors that happened when loading file @@ -1987,7 +1950,7 @@ public final class UnitDatabase { Objects.requireNonNull(file, "file must not be null."); final List<LoadingException> errors = new ArrayList<>(); try { - long lineCounter = 0; + var lineCounter = 0L; for (final String line : Files.readAllLines(file)) { try { this.addUnitOrPrefixFromLine(line, ++lineCounter); @@ -2015,10 +1978,10 @@ public final class UnitDatabase { */ public List<LoadingException> loadUnitsFromStream(InputStream stream) { final List<LoadingException> errors = new ArrayList<>(); - try (final Scanner scanner = new Scanner(stream)) { - long lineCounter = 0; + try (final var scanner = new Scanner(stream)) { + var lineCounter = 0L; while (scanner.hasNextLine()) { - final String line = scanner.nextLine(); + final var line = scanner.nextLine(); try { this.addUnitOrPrefixFromLine(line, ++lineCounter); } catch (IllegalArgumentException | NoSuchElementException e) { @@ -2039,10 +2002,9 @@ public final class UnitDatabase { public Map<String, UnitPrefix> prefixMap(boolean includeDuplicates) { if (includeDuplicates) return Collections.unmodifiableMap(this.prefixes); - else - return Collections.unmodifiableMap(ConditionalExistenceCollections - .conditionalExistenceMap(this.prefixes, - entry -> !isRemovableDuplicate(this.prefixes, entry))); + return Collections.unmodifiableMap(ConditionalExistenceCollections + .conditionalExistenceMap(this.prefixes, + entry -> !isRemovableDuplicate(this.prefixes, entry))); } /** @@ -2050,7 +2012,7 @@ public final class UnitDatabase { * @since 2020-08-26 * @since v0.3.0 */ - public final void setPrefixRepetitionRule( + public void setPrefixRepetitionRule( Predicate<List<UnitPrefix>> prefixRepetitionRule) { this.prefixRepetitionRule = prefixRepetitionRule; } @@ -2089,7 +2051,7 @@ public final class UnitDatabase { * {@link PrefixedUnitMap#values() values()} methods currently ignore * prefixes. * </p> - * + * * @return a map mapping unit names to units, including prefixed names * @since 2019-04-13 * @since v0.2.0 @@ -2110,11 +2072,9 @@ public final class UnitDatabase { public Map<String, Unit> unitMapPrefixless(boolean includeDuplicates) { if (includeDuplicates) return Collections.unmodifiableMap(this.prefixlessUnits); - else - return Collections.unmodifiableMap(ConditionalExistenceCollections - .conditionalExistenceMap(this.prefixlessUnits, - entry -> !isRemovableDuplicate(this.prefixlessUnits, - entry))); + return Collections.unmodifiableMap(ConditionalExistenceCollections + .conditionalExistenceMap(this.prefixlessUnits, + entry -> !isRemovableDuplicate(this.prefixlessUnits, entry))); } /** diff --git a/src/main/java/sevenUnits/unit/UnitPrefix.java b/src/main/java/sevenUnits/unit/UnitPrefix.java index 0fd3421..af106b9 100644 --- a/src/main/java/sevenUnits/unit/UnitPrefix.java +++ b/src/main/java/sevenUnits/unit/UnitPrefix.java @@ -25,7 +25,7 @@ import sevenUnits.utils.Nameable; /** * A prefix that can be applied to a {@code LinearUnit} to multiply it by some * value - * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.3.0 @@ -33,7 +33,7 @@ import sevenUnits.utils.Nameable; public final class UnitPrefix implements Nameable { /** * Gets a {@code UnitPrefix} from a multiplier - * + * * @param multiplier multiplier of prefix * @return prefix * @since 2019-10-16 @@ -45,7 +45,7 @@ public final class UnitPrefix implements Nameable { /** * Gets a {@code UnitPrefix} from a multiplier and a name - * + * * @param multiplier multiplier of prefix * @param ns name(s) and symbol of prefix * @return prefix @@ -61,7 +61,7 @@ public final class UnitPrefix implements Nameable { /** * This prefix's name(s) and symbol. - * + * * @since 2022-04-16 * @since v0.4.0 */ @@ -69,7 +69,7 @@ public final class UnitPrefix implements Nameable { /** * The number that this prefix multiplies units by - * + * * @since 2019-10-16 * @since v0.3.0 */ @@ -77,7 +77,7 @@ public final class UnitPrefix implements Nameable { /** * Creates the {@code DefaultUnitPrefix}. - * + * * @param multiplier * @since 2019-01-14 * @since v0.2.0 @@ -89,7 +89,7 @@ public final class UnitPrefix implements Nameable { /** * Divides this prefix by a scalar - * + * * @param divisor number to divide by * @return quotient of prefix and scalar * @since 2019-10-16 @@ -101,7 +101,7 @@ public final class UnitPrefix implements Nameable { /** * Divides this prefix by {@code other}. - * + * * @param other prefix to divide by * @return quotient of prefixes * @since 2019-04-13 @@ -113,29 +113,26 @@ public final class UnitPrefix implements Nameable { /** * {@inheritDoc} - * + * * Uses the prefix's multiplier to determine equality. */ @Override public boolean equals(final Object obj) { if (this == obj) return true; - if (obj == null) - return false; - if (!(obj instanceof UnitPrefix)) + if ((obj == null) || !(obj instanceof UnitPrefix)) return false; - final UnitPrefix other = (UnitPrefix) obj; - return Double.compare(this.getMultiplier(), - other.getMultiplier()) == 0; + final var other = (UnitPrefix) obj; + return Double.compare(this.getMultiplier(), other.getMultiplier()) == 0; } /** * @param other prefix to compare to - * @return true iff this prefix and other are equal, - * ignoring small differences caused by floating-point error. - * - * @apiNote This method is not transitive, - * so it cannot be used as an equals method. + * @return true iff this prefix and other are equal, ignoring small + * differences caused by floating-point error. + * + * @apiNote This method is not transitive, so it cannot be used as an equals + * method. */ public boolean equalsApproximately(final UnitPrefix other) { if (this == other) @@ -162,7 +159,7 @@ public final class UnitPrefix implements Nameable { /** * {@inheritDoc} - * + * * Uses the prefix's multiplier to determine a hash code. */ @Override @@ -171,22 +168,24 @@ public final class UnitPrefix implements Nameable { } /** - * Multiplies this prefix by a scalar - * - * @param multiplicand number to multiply by - * @return product of prefix and scalar - * @since 2019-10-16 - * @since v0.3.0 + * Subtracts {@code other} from this prefix and returns the result. + * + * @param other prefix to subtract + * @return difference of prefixes + * + * @since 2024-03-03 + * @since v0.5.0 */ - public UnitPrefix times(final double multiplicand) { - return valueOf(this.getMultiplier() * multiplicand); + public UnitPrefix minus(final UnitPrefix other) { + return valueOf(this.getMultiplier() - other.getMultiplier()); } /** * Adds {@code other} to this prefix and returns the result. + * * @param other prefix to add * @return sum of prefixes - * + * * @since 2024-03-03 * @since v0.5.0 */ @@ -195,20 +194,20 @@ public final class UnitPrefix implements Nameable { } /** - * Subtracts {@code other} from this prefix and returns the result. - * @param other prefix to subtract - * @return difference of prefixes - * - * @since 2024-03-03 - * @since v0.5.0 + * Multiplies this prefix by a scalar + * + * @param multiplicand number to multiply by + * @return product of prefix and scalar + * @since 2019-10-16 + * @since v0.3.0 */ - public UnitPrefix minus(final UnitPrefix other) { - return valueOf(this.getMultiplier() - other.getMultiplier()); + public UnitPrefix times(final double multiplicand) { + return valueOf(this.getMultiplier() * multiplicand); } /** * Multiplies this prefix by {@code other}. - * + * * @param other prefix to multiply by * @return product of prefixes * @since 2019-04-13 @@ -220,7 +219,7 @@ public final class UnitPrefix implements Nameable { /** * Raises this prefix to an exponent. - * + * * @param exponent exponent to raise to * @return result of exponentiation. * @since 2019-04-13 @@ -230,19 +229,16 @@ public final class UnitPrefix implements Nameable { return valueOf(Math.pow(this.getMultiplier(), exponent)); } - /** - * @return a string describing the prefix and its multiplier - */ + /** @return a string describing the prefix and its multiplier */ @Override public String toString() { if (this.getPrimaryName().isPresent()) return String.format("%s (\u00D7 %s)", this.getPrimaryName().get(), this.multiplier); - else if (this.getSymbol().isPresent()) + if (this.getSymbol().isPresent()) return String.format("%s (\u00D7 %s)", this.getSymbol().get(), this.multiplier); - else - return String.format("Unit Prefix (\u00D7 %s)", this.multiplier); + return String.format("Unit Prefix (\u00D7 %s)", this.multiplier); } /** diff --git a/src/main/java/sevenUnits/unit/UnitType.java b/src/main/java/sevenUnits/unit/UnitType.java index a331d3d..b195f13 100644 --- a/src/main/java/sevenUnits/unit/UnitType.java +++ b/src/main/java/sevenUnits/unit/UnitType.java @@ -57,9 +57,8 @@ public enum UnitType { public static final UnitType getType(Unit u, Predicate<Unit> isSemiMetric) { if (isSemiMetric.test(u)) return SEMI_METRIC; - else if (u.isMetric()) + if (u.isMetric()) return METRIC; - else - return NON_METRIC; + return NON_METRIC; } } diff --git a/src/main/java/sevenUnits/unit/UnitValue.java b/src/main/java/sevenUnits/unit/UnitValue.java index 4003c17..e24b6e2 100644 --- a/src/main/java/sevenUnits/unit/UnitValue.java +++ b/src/main/java/sevenUnits/unit/UnitValue.java @@ -17,16 +17,15 @@ package sevenUnits.unit; import java.util.Objects; -import java.util.Optional; import sevenUnits.utils.NameSymbol; /** * 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 * @since v0.3.0 @@ -34,7 +33,7 @@ import sevenUnits.utils.NameSymbol; public final class UnitValue { /** * Creates a {@code UnitValue} from a unit and the associated value. - * + * * @param unit unit to use * @param value value to use * @return {@code UnitValue} instance @@ -62,18 +61,18 @@ public final class UnitValue { * @since 2020-10-01 * @since v0.3.0 */ - public final boolean canConvertTo(Unit other) { + public 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) { + public UnitValue convertTo(Unit other) { return UnitValue.of(other, this.getUnit().convertTo(other, this.getValue())); } @@ -88,8 +87,8 @@ public final class UnitValue { * @since 2020-09-29 * @since v0.3.0 */ - public final LinearUnitValue convertToBase(NameSymbol ns) { - final LinearUnit base = LinearUnit.getBase(this.unit).withName(ns); + public LinearUnitValue convertToBase(NameSymbol ns) { + final var base = LinearUnit.getBase(this.unit).withName(ns); return this.convertToLinear(base); } @@ -100,7 +99,7 @@ public final class UnitValue { * @since 2020-09-29 * @since v0.3.0 */ - public final LinearUnitValue convertToLinear(LinearUnit newUnit) { + public LinearUnitValue convertToLinear(LinearUnit newUnit) { return LinearUnitValue.getExact(newUnit, this.getUnit().convertTo(newUnit, this.getValue())); } @@ -114,7 +113,7 @@ public final class UnitValue { public boolean equals(Object obj) { if (!(obj instanceof UnitValue)) return false; - final UnitValue other = (UnitValue) obj; + final var other = (UnitValue) obj; return Objects.equals(this.getUnit().getBase(), other.getUnit().getBase()) && Double.doubleToLongBits( this.getUnit().convertToBase(this.getValue())) == Double @@ -127,7 +126,7 @@ public final class UnitValue { * @since 2020-09-29 * @since v0.3.0 */ - public final Unit getUnit() { + public Unit getUnit() { return this.unit; } @@ -136,7 +135,7 @@ public final class UnitValue { * @since 2020-09-29 * @since v0.3.0 */ - public final double getValue() { + public double getValue() { return this.value; } @@ -148,16 +147,15 @@ public final class UnitValue { @Override public String toString() { - final Optional<String> primaryName = this.getUnit().getPrimaryName(); - final Optional<String> symbol = this.getUnit().getSymbol(); + final var primaryName = this.getUnit().getPrimaryName(); + final var symbol = this.getUnit().getSymbol(); if (primaryName.isEmpty() && symbol.isEmpty()) { - final double baseValue = this.getUnit().convertToBase(this.getValue()); + final var baseValue = this.getUnit().convertToBase(this.getValue()); return String.format("%s unnamed unit (= %s %s)", this.getValue(), baseValue, this.getUnit().getBase() .toString(unit -> unit.getSymbol().orElseThrow())); - } else { - final String unitName = symbol.orElse(primaryName.get()); - return this.getValue() + " " + unitName; } + final var unitName = symbol.orElse(primaryName.get()); + return this.getValue() + " " + unitName; } } diff --git a/src/main/java/sevenUnits/unit/package-info.java b/src/main/java/sevenUnits/unit/package-info.java index 6d867d3..c650b58 100644 --- a/src/main/java/sevenUnits/unit/package-info.java +++ b/src/main/java/sevenUnits/unit/package-info.java @@ -16,7 +16,7 @@ */ /** * Everything to do with the units that make up Unit Converter. - * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.1.0 diff --git a/src/main/java/sevenUnits/utils/ConditionalExistenceCollections.java b/src/main/java/sevenUnits/utils/ConditionalExistenceCollections.java index dd21a22..6244ee6 100644 --- a/src/main/java/sevenUnits/utils/ConditionalExistenceCollections.java +++ b/src/main/java/sevenUnits/utils/ConditionalExistenceCollections.java @@ -49,8 +49,8 @@ import java.util.function.Predicate; * Other than that, <i>the only difference between the provided collections and * the returned collections are that elements don't exist if they don't pass the * provided condition</i>. - * - * + * + * * @author Adrien Hopkins * @since 2019-10-17 * @since v0.3.0 @@ -58,7 +58,7 @@ import java.util.function.Predicate; public final class ConditionalExistenceCollections { /** * Elements in this collection only exist if they meet a condition. - * + * * @author Adrien Hopkins * @since 2019-10-17 * @since v0.3.0 @@ -71,7 +71,7 @@ public final class ConditionalExistenceCollections { /** * Creates the {@code ConditionalExistenceCollection}. - * + * * @param collection * @param existenceCondition * @since 2019-10-17 @@ -103,7 +103,7 @@ public final class ConditionalExistenceCollections { // instance of E // therefore this cast will always work @SuppressWarnings("unchecked") - final E e = (E) o; + final var e = (E) o; return this.existenceCondition.test(e); } @@ -118,7 +118,7 @@ public final class ConditionalExistenceCollections { public boolean remove(final Object o) { // remove() must be first in the && statement, otherwise it may not // execute - final boolean containedObject = this.contains(o); + final var containedObject = this.contains(o); return this.collection.remove(o) && containedObject; } @@ -149,7 +149,7 @@ public final class ConditionalExistenceCollections { /** * Elements in this wrapper iterator only exist if they pass a condition. - * + * * @author Adrien Hopkins * @since 2019-10-17 * @since v0.3.0 @@ -163,7 +163,7 @@ public final class ConditionalExistenceCollections { /** * Creates the {@code ConditionalExistenceIterator}. - * + * * @param iterator * @param condition * @since 2019-10-17 @@ -178,7 +178,7 @@ public final class ConditionalExistenceCollections { /** * Gets the next element, and sets nextElement and hasNext accordingly. - * + * * @since 2019-10-17 * @since v0.3.0 */ @@ -202,11 +202,11 @@ public final class ConditionalExistenceCollections { @Override public E next() { if (this.hasNext()) { - final E next = this.nextElement; + final var next = this.nextElement; this.getAndSetNextElement(); return next; - } else - throw new NoSuchElementException(); + } + throw new NoSuchElementException(); } @Override @@ -217,7 +217,7 @@ public final class ConditionalExistenceCollections { /** * Mappings in this map only exist if the entry passes some condition. - * + * * @author Adrien Hopkins * @since 2019-10-17 * @since v0.3.0 @@ -230,7 +230,7 @@ public final class ConditionalExistenceCollections { /** * Creates the {@code ConditionalExistenceMap}. - * + * * @param map * @param entryExistenceCondition * @since 2019-10-17 @@ -250,10 +250,10 @@ public final class ConditionalExistenceCollections { // only instances of K have mappings in the backing map // since we know that key is a valid key, it must be an instance of K @SuppressWarnings("unchecked") - final K keyAsK = (K) key; + final var keyAsK = (K) key; // get and test entry - final V value = this.map.get(key); + final var value = this.map.get(key); final Entry<K, V> entry = new SimpleEntry<>(keyAsK, value); return this.entryExistenceCondition.test(entry); } @@ -269,7 +269,7 @@ public final class ConditionalExistenceCollections { return this.containsKey(key) ? this.map.get(key) : null; } - private final Entry<K, V> getEntry(K key) { + private Entry<K, V> getEntry(K key) { return new Entry<>() { @Override public K getKey() { @@ -296,7 +296,7 @@ public final class ConditionalExistenceCollections { @Override public V put(final K key, final V value) { - final V oldValue = this.map.put(key, value); + final var oldValue = this.map.put(key, value); // get and test entry final Entry<K, V> entry = new SimpleEntry<>(key, oldValue); @@ -305,7 +305,7 @@ public final class ConditionalExistenceCollections { @Override public V remove(final Object key) { - final V oldValue = this.map.remove(key); + final var oldValue = this.map.remove(key); return this.containsKey(key) ? oldValue : null; } @@ -318,7 +318,7 @@ public final class ConditionalExistenceCollections { /** * Elements in this set only exist if a certain condition is true. - * + * * @author Adrien Hopkins * @since 2019-10-17 * @since v0.3.0 @@ -330,7 +330,7 @@ public final class ConditionalExistenceCollections { /** * Creates the {@code ConditionalNonexistenceSet}. - * + * * @param set set to use * @param existenceCondition condition where element exists * @since 2019-10-17 @@ -368,7 +368,7 @@ public final class ConditionalExistenceCollections { // of E // therefore this cast will always work @SuppressWarnings("unchecked") - final E e = (E) o; + final var e = (E) o; return this.existenceCondition.test(e); } @@ -383,7 +383,7 @@ public final class ConditionalExistenceCollections { public boolean remove(final Object o) { // remove() must be first in the && statement, otherwise it may not // execute - final boolean containedObject = this.contains(o); + final var containedObject = this.contains(o); return this.set.remove(o) && containedObject; } @@ -414,7 +414,7 @@ public final class ConditionalExistenceCollections { /** * Elements in the returned wrapper collection are ignored if they don't pass * a condition. - * + * * @param <E> type of elements in collection * @param collection collection to wrap * @param existenceCondition elements only exist if this returns true @@ -422,7 +422,7 @@ public final class ConditionalExistenceCollections { * @since 2019-10-17 * @since v0.3.0 */ - public static final <E> Collection<E> conditionalExistenceCollection( + public static <E> Collection<E> conditionalExistenceCollection( final Collection<E> collection, final Predicate<E> existenceCondition) { return new ConditionalExistenceCollection<>(collection, @@ -432,7 +432,7 @@ public final class ConditionalExistenceCollections { /** * Elements in the returned wrapper iterator are ignored if they don't pass a * condition. - * + * * @param <E> type of elements in iterator * @param iterator iterator to wrap * @param existenceCondition elements only exist if this returns true @@ -440,7 +440,7 @@ public final class ConditionalExistenceCollections { * @since 2019-10-17 * @since v0.3.0 */ - public static final <E> Iterator<E> conditionalExistenceIterator( + public static <E> Iterator<E> conditionalExistenceIterator( final Iterator<E> iterator, final Predicate<E> existenceCondition) { return new ConditionalExistenceIterator<>(iterator, existenceCondition); } @@ -448,7 +448,7 @@ public final class ConditionalExistenceCollections { /** * Mappings in the returned wrapper map are ignored if the corresponding * entry doesn't pass a condition - * + * * @param <K> type of key in map * @param <V> type of value in map * @param map map to wrap @@ -457,8 +457,7 @@ public final class ConditionalExistenceCollections { * @since 2019-10-17 * @since v0.3.0 */ - public static final <K, V> Map<K, V> conditionalExistenceMap( - final Map<K, V> map, + public static <K, V> Map<K, V> conditionalExistenceMap(final Map<K, V> map, final Predicate<Entry<K, V>> entryExistenceCondition) { return new ConditionalExistenceMap<>(map, entryExistenceCondition); } @@ -466,7 +465,7 @@ public final class ConditionalExistenceCollections { /** * Elements in the returned wrapper set are ignored if they don't pass a * condition. - * + * * @param <E> type of elements in set * @param set set to wrap * @param existenceCondition elements only exist if this returns true @@ -474,7 +473,7 @@ public final class ConditionalExistenceCollections { * @since 2019-10-17 * @since v0.3.0 */ - public static final <E> Set<E> conditionalExistenceSet(final Set<E> set, + public static <E> Set<E> conditionalExistenceSet(final Set<E> set, final Predicate<E> existenceCondition) { return new ConditionalExistenceSet<>(set, existenceCondition); } diff --git a/src/main/java/sevenUnits/utils/DecimalComparison.java b/src/main/java/sevenUnits/utils/DecimalComparison.java index c7564c4..1366fd3 100644 --- a/src/main/java/sevenUnits/utils/DecimalComparison.java +++ b/src/main/java/sevenUnits/utils/DecimalComparison.java @@ -20,7 +20,7 @@ import java.math.BigDecimal; /** * A class that contains methods to compare float and double values. - * + * * @author Adrien Hopkins * @since 2019-03-18 * @since v0.2.0 @@ -29,7 +29,7 @@ public final class DecimalComparison { /** * The value used for double comparison. If two double values are within this * value multiplied by the larger value, they are considered equal. - * + * * @since 2019-03-18 * @since v0.2.0 */ @@ -38,7 +38,7 @@ public final class DecimalComparison { /** * The value used for float comparison. If two float values are within this * value multiplied by the larger value, they are considered equal. - * + * * @since 2019-03-18 * @since v0.2.0 */ @@ -63,20 +63,20 @@ public final class DecimalComparison { * <li>Use {@link BigDecimal} instead of {@code double} (this will make a * violation of transitivity 100% impossible) * </ol> - * + * * @param a first value to test * @param b second value to test * @return whether they are equal * @since 2019-03-18 * @since v0.2.0 */ - public static final boolean equals(final double a, final double b) { + public static boolean equals(final double a, final double b) { return DecimalComparison.equals(a, b, DOUBLE_EPSILON); } /** * Tests for double equality using a custom epsilon value. - * + * * <p> * <strong>WARNING: </strong>this method is not technically transitive. If a * and b are off by slightly less than {@code epsilon * max(abs(a), abs(b))}, @@ -93,7 +93,7 @@ public final class DecimalComparison { * <li>Use {@link BigDecimal} instead of {@code double} (this will make a * violation of transitivity 100% impossible) * </ol> - * + * * @param a first value to test * @param b second value to test * @param epsilon allowed difference @@ -101,14 +101,14 @@ public final class DecimalComparison { * @since 2019-03-18 * @since v0.2.0 */ - public static final boolean equals(final double a, final double b, + public static boolean equals(final double a, final double b, final double epsilon) { return Math.abs(a - b) <= epsilon * Math.max(Math.abs(a), Math.abs(b)); } /** * Tests for equality of float values using {@link #FLOAT_EPSILON}. - * + * * <p> * <strong>WARNING: </strong>this method is not technically transitive. If a * and b are off by slightly less than {@code epsilon * max(abs(a), abs(b))}, @@ -125,20 +125,20 @@ public final class DecimalComparison { * <li>Use {@link BigDecimal} instead of {@code float} (this will make a * violation of transitivity 100% impossible) * </ol> - * + * * @param a first value to test * @param b second value to test * @return whether they are equal * @since 2019-03-18 * @since v0.2.0 */ - public static final boolean equals(final float a, final float b) { + public static boolean equals(final float a, final float b) { return DecimalComparison.equals(a, b, FLOAT_EPSILON); } /** * Tests for float equality using a custom epsilon value. - * + * * <p> * <strong>WARNING: </strong>this method is not technically transitive. If a * and b are off by slightly less than {@code epsilon * max(abs(a), abs(b))}, @@ -155,7 +155,7 @@ public final class DecimalComparison { * <li>Use {@link BigDecimal} instead of {@code float} (this will make a * violation of transitivity 100% impossible) * </ol> - * + * * @param a first value to test * @param b second value to test * @param epsilon allowed difference @@ -163,7 +163,7 @@ public final class DecimalComparison { * @since 2019-03-18 * @since v0.2.0 */ - public static final boolean equals(final float a, final float b, + public static boolean equals(final float a, final float b, final float epsilon) { return Math.abs(a - b) <= epsilon * Math.max(Math.abs(a), Math.abs(b)); } @@ -188,14 +188,14 @@ public final class DecimalComparison { * <li>Use {@link BigDecimal} instead of {@code double} (this will make a * violation of transitivity 100% impossible) * </ol> - * + * * @param a first value to test * @param b second value to test * @return whether they are equal * @since 2020-09-07 * @since v0.3.0 */ - public static final boolean equals(final UncertainDouble a, + public static boolean equals(final UncertainDouble a, final UncertainDouble b) { return DecimalComparison.equals(a.value(), b.value()) && DecimalComparison.equals(a.uncertainty(), b.uncertainty()); @@ -203,7 +203,7 @@ public final class DecimalComparison { /** * Tests for {@code UncertainDouble} equality using a custom epsilon value. - * + * * <p> * <strong>WARNING: </strong>this method is not technically transitive. If a * and b are off by slightly less than {@code epsilon * max(abs(a), abs(b))}, @@ -220,7 +220,7 @@ public final class DecimalComparison { * <li>Use {@link BigDecimal} instead of {@code double} (this will make a * violation of transitivity 100% impossible) * </ol> - * + * * @param a first value to test * @param b second value to test * @param epsilon allowed difference @@ -228,7 +228,7 @@ public final class DecimalComparison { * @since 2019-03-18 * @since v0.2.0 */ - public static final boolean equals(final UncertainDouble a, + public static boolean equals(final UncertainDouble a, final UncertainDouble b, final double epsilon) { return DecimalComparison.equals(a.value(), b.value(), epsilon) && DecimalComparison.equals(a.uncertainty(), b.uncertainty(), diff --git a/src/main/java/sevenUnits/utils/ExpressionParser.java b/src/main/java/sevenUnits/utils/ExpressionParser.java index 783a135..03c763c 100644 --- a/src/main/java/sevenUnits/utils/ExpressionParser.java +++ b/src/main/java/sevenUnits/utils/ExpressionParser.java @@ -31,7 +31,7 @@ import java.util.function.UnaryOperator; /** * An object that can parse expressions with unary or binary operators. - * + * * @author Adrien Hopkins * @param <T> type of object that exists in parsed expressions * @since 2019-03-14 @@ -40,7 +40,7 @@ import java.util.function.UnaryOperator; public final class ExpressionParser<T> { /** * A builder that can create {@code ExpressionParser<T>} instances. - * + * * @author Adrien Hopkins * @param <T> type of object that exists in parsed expressions * @since 2019-03-17 @@ -51,49 +51,49 @@ public final class ExpressionParser<T> { * A function that obtains a parseable object from a string. For example, * an integer {@code ExpressionParser} would use * {@code Integer::parseInt}. - * + * * @since 2019-03-14 * @since v0.2.0 */ private final Function<String, ? extends T> objectObtainer; - + /** * The function of the space as an operator (like 3 x y) - * + * * @since 2019-03-22 * @since v0.2.0 */ private String spaceFunction = null; - + /** * A map mapping operator strings to operator functions, for unary * operators. - * + * * @since 2019-03-14 * @since v0.2.0 */ private final Map<String, PriorityUnaryOperator<T>> unaryOperators; - + /** * A map mapping operator strings to operator functions, for binary * operators. - * + * * @since 2019-03-14 * @since v0.2.0 */ private final Map<String, PriorityBinaryOperator<T>> binaryOperators; - + /** * A map mapping operator strings to numeric functions. - * + * * @since 2024-03-23 * @since v0.5.0 */ private final Map<String, PriorityBiFunction<T, UncertainDouble, T>> numericOperators; - + /** * Creates the {@code Builder}. - * + * * @param objectObtainer a function that can turn strings into objects of * the type handled by the parser. * @throws NullPointerException if {@code objectObtainer} is null @@ -107,10 +107,10 @@ public final class ExpressionParser<T> { this.binaryOperators = new HashMap<>(); this.numericOperators = new HashMap<>(); } - + /** * Adds a binary operator to the builder. - * + * * @param text text used to reference the operator, like '+' * @param operator operator to add * @param priority operator's priority, which determines which operators @@ -125,7 +125,7 @@ public final class ExpressionParser<T> { final BinaryOperator<T> operator, final int priority) { Objects.requireNonNull(text, "text must not be null."); Objects.requireNonNull(operator, "operator must not be null."); - + // Unfortunately, I cannot use a lambda because the // PriorityBinaryOperator requires arguments. final PriorityBinaryOperator<T> priorityOperator = new PriorityBinaryOperator<>( @@ -134,16 +134,16 @@ public final class ExpressionParser<T> { public T apply(final T t, final T u) { return operator.apply(t, u); } - + }; this.binaryOperators.put(text, priorityOperator); return this; } - + /** * Adds a two-argument operator where the second operator is a number. * This is used for operations like vector scaling and exponentation. - * + * * @param text text used to reference the operator, like '^' * @param operator operator to add * @param priority operator's priority, which determines which operators @@ -155,7 +155,7 @@ public final class ExpressionParser<T> { final int priority) { Objects.requireNonNull(text, "text must not be null."); Objects.requireNonNull(operator, "operator must not be null."); - + // Unfortunately, I cannot use a lambda because the // PriorityBinaryOperator requires arguments. final PriorityBiFunction<T, UncertainDouble, T> priorityOperator = new PriorityBiFunction<>( @@ -164,16 +164,16 @@ public final class ExpressionParser<T> { public T apply(final T t, final UncertainDouble u) { return operator.apply(t, u); } - + }; this.numericOperators.put(text, priorityOperator); return this; } - + /** * Adds a function for spaces. You must use the text of an existing binary * operator. - * + * * @param operator text of operator to use * @return this builder * @since 2019-03-22 @@ -181,18 +181,18 @@ public final class ExpressionParser<T> { */ public Builder<T> addSpaceFunction(final String operator) { Objects.requireNonNull(operator, "operator must not be null."); - + if (!this.binaryOperators.containsKey(operator)) throw new IllegalArgumentException(String .format("Could not find binary operator '%s'", operator)); - + this.spaceFunction = operator; return this; } - + /** * Adds a unary operator to the builder. - * + * * @param text text used to reference the operator, like '-' * @param operator operator to add * @param priority operator's priority, which determines which operators @@ -207,7 +207,7 @@ public final class ExpressionParser<T> { final UnaryOperator<T> operator, final int priority) { Objects.requireNonNull(text, "text must not be null."); Objects.requireNonNull(operator, "operator must not be null."); - + // Unfortunately, I cannot use a lambda because the // PriorityUnaryOperator requires arguments. final PriorityUnaryOperator<T> priorityOperator = new PriorityUnaryOperator<>( @@ -220,7 +220,7 @@ public final class ExpressionParser<T> { this.unaryOperators.put(text, priorityOperator); return this; } - + /** * @return an {@code ExpressionParser<T>} instance with the properties * given to this builder @@ -232,11 +232,11 @@ public final class ExpressionParser<T> { this.binaryOperators, this.numericOperators, this.spaceFunction); } } - + /** * A binary operator with a priority field that determines which operators * apply first. - * + * * @author Adrien Hopkins * @param <T> type of operand and result * @since 2019-03-17 @@ -247,15 +247,15 @@ public final class ExpressionParser<T> { /** * The operator's priority. Higher-priority operators are applied before * lower-priority operators - * + * * @since 2019-03-17 * @since v0.2.0 */ private final int priority; - + /** * Creates the {@code PriorityBinaryOperator}. - * + * * @param priority operator's priority * @since 2019-03-17 * @since v0.2.0 @@ -263,14 +263,14 @@ public final class ExpressionParser<T> { public PriorityBiFunction(final int priority) { this.priority = priority; } - + /** * Compares this object to another by priority. - * + * * <p> * {@inheritDoc} * </p> - * + * * @since 2019-03-17 * @since v0.2.0 */ @@ -278,12 +278,11 @@ public final class ExpressionParser<T> { public int compareTo(final PriorityBiFunction<T, U, R> o) { if (this.priority < o.priority) return -1; - else if (this.priority > o.priority) + if (this.priority > o.priority) return 1; - else - return 0; + return 0; } - + /** * @return priority * @since 2019-03-22 @@ -293,11 +292,11 @@ public final class ExpressionParser<T> { return this.priority; } } - + /** * A binary operator with a priority field that determines which operators * apply first. - * + * * @author Adrien Hopkins * @param <T> type of operand and result * @since 2019-03-17 @@ -308,15 +307,15 @@ public final class ExpressionParser<T> { /** * The operator's priority. Higher-priority operators are applied before * lower-priority operators - * + * * @since 2019-03-17 * @since v0.2.0 */ private final int priority; - + /** * Creates the {@code PriorityBinaryOperator}. - * + * * @param priority operator's priority * @since 2019-03-17 * @since v0.2.0 @@ -324,14 +323,14 @@ public final class ExpressionParser<T> { public PriorityBinaryOperator(final int priority) { this.priority = priority; } - + /** * Compares this object to another by priority. - * + * * <p> * {@inheritDoc} * </p> - * + * * @since 2019-03-17 * @since v0.2.0 */ @@ -339,12 +338,11 @@ public final class ExpressionParser<T> { public int compareTo(final PriorityBinaryOperator<T> o) { if (this.priority < o.priority) return -1; - else if (this.priority > o.priority) + if (this.priority > o.priority) return 1; - else - return 0; + return 0; } - + /** * @return priority * @since 2019-03-22 @@ -354,11 +352,11 @@ public final class ExpressionParser<T> { return this.priority; } } - + /** * A unary operator with a priority field that determines which operators * apply first. - * + * * @author Adrien Hopkins * @param <T> type of operand and result * @since 2019-03-17 @@ -369,15 +367,15 @@ public final class ExpressionParser<T> { /** * The operator's priority. Higher-priority operators are applied before * lower-priority operators - * + * * @since 2019-03-17 * @since v0.2.0 */ private final int priority; - + /** * Creates the {@code PriorityUnaryOperator}. - * + * * @param priority operator's priority * @since 2019-03-17 * @since v0.2.0 @@ -385,14 +383,14 @@ public final class ExpressionParser<T> { public PriorityUnaryOperator(final int priority) { this.priority = priority; } - + /** * Compares this object to another by priority. - * + * * <p> * {@inheritDoc} * </p> - * + * * @since 2019-03-17 * @since v0.2.0 */ @@ -400,12 +398,11 @@ public final class ExpressionParser<T> { public int compareTo(final PriorityUnaryOperator<T> o) { if (this.priority < o.priority) return -1; - else if (this.priority > o.priority) + if (this.priority > o.priority) return 1; - else - return 0; + return 0; } - + /** * @return priority * @since 2019-03-22 @@ -415,37 +412,37 @@ public final class ExpressionParser<T> { return this.priority; } } - + /** * The types of tokens that are available. - * + * * @author Adrien Hopkins * @since 2019-03-14 * @since v0.2.0 */ - private static enum TokenType { + private enum TokenType { OBJECT, UNARY_OPERATOR, BINARY_OPERATOR, NUMERIC_OPERATOR; } - + /** * The opening bracket. - * + * * @since 2019-03-22 * @since v0.2.0 */ public static final char OPENING_BRACKET = '('; - + /** * The closing bracket. - * + * * @since 2019-03-22 * @since v0.2.0 */ public static final char CLOSING_BRACKET = ')'; - + /** * Finds the other bracket in a pair of brackets, given the position of one. - * + * * @param string string that contains brackets * @param bracketPosition position of first bracket * @return position of matching bracket @@ -456,9 +453,9 @@ public final class ExpressionParser<T> { private static int findBracketPair(final String string, final int bracketPosition) { Objects.requireNonNull(string, "string must not be null."); - - final char openingBracket = string.charAt(bracketPosition); - + + final var openingBracket = string.charAt(bracketPosition); + // figure out what closing bracket to look for final char closingBracket; switch (openingBracket) { @@ -475,16 +472,16 @@ public final class ExpressionParser<T> { throw new IllegalArgumentException( String.format("Invalid bracket '%s'", openingBracket)); } - + // level of brackets. every opening bracket increments this; every closing // bracket decrements it - int bracketLevel = 0; - + var bracketLevel = 0; + // iterate over the string to find the closing bracket - for (int currentPosition = bracketPosition; currentPosition < string + for (var currentPosition = bracketPosition; currentPosition < string .length(); currentPosition++) { - final char currentCharacter = string.charAt(currentPosition); - + final var currentCharacter = string.charAt(currentPosition); + if (currentCharacter == openingBracket) { bracketLevel++; } else if (currentCharacter == closingBracket) { @@ -493,55 +490,55 @@ public final class ExpressionParser<T> { return currentPosition; } } - + throw new IllegalArgumentException("No matching bracket found."); } - + /** * A function that obtains a parseable object from a string. For example, an * integer {@code ExpressionParser} would use {@code Integer::parseInt}. - * + * * @since 2019-03-14 * @since v0.2.0 */ private final Function<String, ? extends T> objectObtainer; - + /** * A map mapping operator strings to operator functions, for unary operators. - * + * * @since 2019-03-14 * @since v0.2.0 */ private final Map<String, PriorityUnaryOperator<T>> unaryOperators; - + /** * A map mapping operator strings to operator functions, for binary * operators. - * + * * @since 2019-03-14 * @since v0.2.0 */ private final Map<String, PriorityBinaryOperator<T>> binaryOperators; - + /** * A map mapping operator strings to numeric functions. - * + * * @since 2024-03-23 * @since v0.5.0 */ private final Map<String, PriorityBiFunction<T, UncertainDouble, T>> numericOperators; - + /** * The operator for space, or null if spaces have no function. - * + * * @since 2019-03-22 * @since v0.2.0 */ private final String spaceOperator; - + /** * Creates the {@code ExpressionParser}. - * + * * @param objectObtainer function to get objects from strings * @param unaryOperators unary operators available to the parser * @param binaryOperators binary operators available to the parser @@ -561,7 +558,7 @@ public final class ExpressionParser<T> { this.numericOperators = numericOperators; this.spaceOperator = spaceOperator; } - + /** * Converts a given mathematical expression to reverse Polish notation * (operators after operands). @@ -570,7 +567,7 @@ public final class ExpressionParser<T> { * {@code 2 * (3 + 4)}<br> * becomes<br> * {@code 2 3 4 + *}. - * + * * @param expression expression * @return expression in RPN * @throws IllegalArgumentException if expression is invalid (e.g. @@ -580,25 +577,25 @@ public final class ExpressionParser<T> { */ String convertExpressionToReversePolish(final String expression) { Objects.requireNonNull(expression, "expression must not be null."); - + final List<String> components = new ArrayList<>(); - + // the part of the expression remaining to parse - String partialExpression = expression; - + var partialExpression = expression; + // find and deal with brackets while (partialExpression.indexOf(OPENING_BRACKET) != -1) { - final int openingBracketPosition = partialExpression + final var openingBracketPosition = partialExpression .indexOf(OPENING_BRACKET); - final int closingBracketPosition = findBracketPair(partialExpression, + final var closingBracketPosition = findBracketPair(partialExpression, openingBracketPosition); - + // check for function if (openingBracketPosition > 0 && partialExpression.charAt(openingBracketPosition - 1) != ' ') { // function like sin(2) or tempF(32) // find the position of the last space - int spacePosition = openingBracketPosition; + var spacePosition = openingBracketPosition; while (spacePosition >= 0 && partialExpression.charAt(spacePosition) != ' ') { spacePosition--; @@ -609,8 +606,6 @@ public final class ExpressionParser<T> { .substring(0, spacePosition + 1).split(" "))); components.add(partialExpression.substring(spacePosition + 1, closingBracketPosition + 1)); - partialExpression = partialExpression - .substring(closingBracketPosition + 1); } else { // normal brackets like (1 + 2) * (3 / 5) components.addAll(Arrays.asList(partialExpression @@ -618,37 +613,37 @@ public final class ExpressionParser<T> { components.add(this.convertExpressionToReversePolish( partialExpression.substring(openingBracketPosition + 1, closingBracketPosition))); - partialExpression = partialExpression - .substring(closingBracketPosition + 1); } + partialExpression = partialExpression + .substring(closingBracketPosition + 1); } - + // add everything else components.addAll(Arrays.asList(partialExpression.split(" "))); - + // remove empty entries while (components.contains("")) { components.remove(""); } - + // deal with space multiplication (x y) if (this.spaceOperator != null) { - for (int i = 0; i < components.size() - 1; i++) { + for (var i = 0; i < components.size() - 1; i++) { if (this.getTokenType(components.get(i)) == TokenType.OBJECT && this .getTokenType(components.get(i + 1)) == TokenType.OBJECT) { components.add(++i, this.spaceOperator); } } } - + // turn the expression into reverse Polish while (true) { - final int highestPriorityOperatorPosition = this + final var highestPriorityOperatorPosition = this .findHighestPriorityOperatorPosition(components); if (highestPriorityOperatorPosition == -1) { break; } - + // swap components based on what kind of operator there is // 1 + 2 becomes 2 1 + // - 1 becomes 1 - @@ -658,9 +653,9 @@ public final class ExpressionParser<T> { if (components.size() < 2) throw new IllegalArgumentException( "Invalid expression \"" + expression + "\""); - final String unaryOperator = components + final var unaryOperator = components .remove(highestPriorityOperatorPosition); - final String operand = components + final var operand = components .remove(highestPriorityOperatorPosition); components.add(highestPriorityOperatorPosition, operand + " " + unaryOperator); @@ -670,11 +665,11 @@ public final class ExpressionParser<T> { if (components.size() < 3) throw new IllegalArgumentException( "Invalid expression \"" + expression + "\""); - final String binaryOperator = components + final var binaryOperator = components .remove(highestPriorityOperatorPosition); - final String operand1 = components + final var operand1 = components .remove(highestPriorityOperatorPosition - 1); - final String operand2 = components + final var operand2 = components .remove(highestPriorityOperatorPosition - 1); components.add(highestPriorityOperatorPosition - 1, operand1 + " " + operand2 + " " + binaryOperator); @@ -683,7 +678,7 @@ public final class ExpressionParser<T> { throw new AssertionError("Expected operator, found non-operator."); } } - + // join all of the components together, then ensure there is only one // space in a row if (components.size() != 1) @@ -691,10 +686,10 @@ public final class ExpressionParser<T> { "Invalid expression \"" + expression + "\"."); return components.get(0).replaceAll(" +", " ").trim(); } - + /** * Finds the position of the highest-priority operator in a list - * + * * @param components components to test * @param blacklist positions of operators that should be ignored * @return position of highest priority, or -1 if the list contains no @@ -707,40 +702,40 @@ public final class ExpressionParser<T> { final List<String> components) { Objects.requireNonNull(components, "components must not be null."); // find highest priority - int maxPriority = Integer.MIN_VALUE; - int maxPriorityPosition = -1; - + var maxPriority = Integer.MIN_VALUE; + var maxPriorityPosition = -1; + // go over components one by one // if it is an operator, test its priority to see if it's max // if it is, update maxPriority and maxPriorityPosition - for (int i = 0; i < components.size(); i++) { - + for (var i = 0; i < components.size(); i++) { + switch (this.getTokenType(components.get(i))) { case UNARY_OPERATOR: - final PriorityUnaryOperator<T> unaryOperator = this.unaryOperators + final var unaryOperator = this.unaryOperators .get(components.get(i)); - final int unaryPriority = unaryOperator.getPriority(); - + final var unaryPriority = unaryOperator.getPriority(); + if (unaryPriority > maxPriority) { maxPriority = unaryPriority; maxPriorityPosition = i; } break; case BINARY_OPERATOR: - final PriorityBinaryOperator<T> binaryOperator = this.binaryOperators + final var binaryOperator = this.binaryOperators .get(components.get(i)); - final int binaryPriority = binaryOperator.getPriority(); - + final var binaryPriority = binaryOperator.getPriority(); + if (binaryPriority > maxPriority) { maxPriority = binaryPriority; maxPriorityPosition = i; } break; case NUMERIC_OPERATOR: - final PriorityBiFunction<T, UncertainDouble, T> numericOperator = this.numericOperators + final var numericOperator = this.numericOperators .get(components.get(i)); - final int numericPriority = numericOperator.getPriority(); - + final var numericPriority = numericOperator.getPriority(); + if (numericPriority > maxPriority) { maxPriority = numericPriority; maxPriorityPosition = i; @@ -750,14 +745,14 @@ public final class ExpressionParser<T> { break; } } - + // max priority position found return maxPriorityPosition; } - + /** * Determines whether an inputted string is an object or an operator - * + * * @param token string to input * @return type of token it is * @throws NullPointerException if {@code expression} is null @@ -766,20 +761,19 @@ public final class ExpressionParser<T> { */ private TokenType getTokenType(final String token) { Objects.requireNonNull(token, "token must not be null."); - + if (this.unaryOperators.containsKey(token)) return TokenType.UNARY_OPERATOR; - else if (this.binaryOperators.containsKey(token)) + if (this.binaryOperators.containsKey(token)) return TokenType.BINARY_OPERATOR; - else if (this.numericOperators.containsKey(token)) + if (this.numericOperators.containsKey(token)) return TokenType.NUMERIC_OPERATOR; - else - return TokenType.OBJECT; + return TokenType.OBJECT; } - + /** * Parses an expression. - * + * * @param expression expression to parse * @return result * @throws NullPointerException if {@code expression} is null @@ -790,10 +784,10 @@ public final class ExpressionParser<T> { return this.parseReversePolishExpression( this.convertExpressionToReversePolish(expression)); } - + /** * Parses an expression expressed in reverse Polish notation. - * + * * @param expression expression to parse * @return result * @throws NullPointerException if {@code expression} is null @@ -802,43 +796,43 @@ public final class ExpressionParser<T> { */ T parseReversePolishExpression(final String expression) { Objects.requireNonNull(expression, "expression must not be null."); - + final Deque<T> stack = new ArrayDeque<>(); final Deque<UncertainDouble> doubleStack = new ArrayDeque<>(); - + // iterate over every item in the expression, then for (final String item : expression.split(" ")) { // choose a path based on what kind of thing was just read switch (this.getTokenType(item)) { - + case BINARY_OPERATOR: if (stack.size() < 2) throw new IllegalStateException(String.format( "Attempted to call binary operator %s with only %d arguments.", item, stack.size())); - + // get two arguments and operator, then apply! - final T o1 = stack.pop(); - final T o2 = stack.pop(); + final var o1 = stack.pop(); + final var o2 = stack.pop(); final BinaryOperator<T> binaryOperator = this.binaryOperators .get(item); - + stack.push(binaryOperator.apply(o2, o1)); break; - + case NUMERIC_OPERATOR: if (stack.size() < 1 || doubleStack.size() < 1) throw new IllegalStateException(String.format( "Attempted to call binary operator %s with insufficient arguments.", item)); - - final T ot = stack.pop(); - final UncertainDouble on = doubleStack.pop(); + + final var ot = stack.pop(); + final var on = doubleStack.pop(); final BiFunction<T, UncertainDouble, T> op = this.numericOperators .get(item); stack.push(op.apply(ot, on)); break; - + case OBJECT: // just add it to the stack // these try-catch statements are necessary @@ -860,33 +854,33 @@ public final class ExpressionParser<T> { } } break; - + case UNARY_OPERATOR: if (stack.size() < 1) throw new IllegalStateException(String.format( "Attempted to call unary operator %s with only %d arguments.", item, stack.size())); - + // get one argument and operator, then apply! - final T o = stack.pop(); + final var o = stack.pop(); final UnaryOperator<T> unaryOperator = this.unaryOperators .get(item); - + stack.push(unaryOperator.apply(o)); break; default: throw new AssertionError( String.format("Internal error: Invalid token type %s.", this.getTokenType(item))); - + } } - + // return answer, or throw an exception if I can't if (stack.size() > 1) throw new IllegalStateException( "Computation ended up with more than one answer."); - else if (stack.size() == 0) + if (stack.size() == 0) throw new IllegalStateException( "Computation ended up without an answer."); return stack.pop(); diff --git a/src/main/java/sevenUnits/utils/NameSymbol.java b/src/main/java/sevenUnits/utils/NameSymbol.java index ebb1e8b..089978b 100644 --- a/src/main/java/sevenUnits/utils/NameSymbol.java +++ b/src/main/java/sevenUnits/utils/NameSymbol.java @@ -19,14 +19,13 @@ package sevenUnits.utils; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; -import java.util.Iterator; import java.util.Objects; import java.util.Optional; import java.util.Set; /** * A class that can be used to specify names and a symbol for a unit. - * + * * @author Adrien Hopkins * @since 2019-10-21 * @since v0.3.0 @@ -39,16 +38,16 @@ public final class NameSymbol { /** * Creates a {@code NameSymbol}, ensuring that if primaryName is null and * otherNames is not empty, one name is moved from otherNames to primaryName - * + * * Ensure that otherNames is not a copy of the inputted argument. */ - private static final NameSymbol create(final String name, - final String symbol, final Set<String> otherNames) { + private static NameSymbol create(final String name, final String symbol, + final Set<String> otherNames) { final Optional<String> primaryName; if (name == null && !otherNames.isEmpty()) { // get primary name and remove it from savedNames - final Iterator<String> it = otherNames.iterator(); + final var it = otherNames.iterator(); assert it.hasNext(); primaryName = Optional.of(it.next()); otherNames.remove(primaryName.get()); @@ -63,7 +62,7 @@ public final class NameSymbol { /** * Gets a {@code NameSymbol} with a primary name, a symbol and no other * names. - * + * * @param name name to use * @param symbol symbol to use * @return NameSymbol instance @@ -71,7 +70,7 @@ public final class NameSymbol { * @since v0.3.0 * @throws NullPointerException if name or symbol is null */ - public static final NameSymbol of(final String name, final String symbol) { + public static NameSymbol of(final String name, final String symbol) { return new NameSymbol(Optional.of(name), Optional.of(symbol), new HashSet<>()); } @@ -79,7 +78,7 @@ public final class NameSymbol { /** * Gets a {@code NameSymbol} with a primary name, a symbol and additional * names. - * + * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use @@ -88,7 +87,7 @@ public final class NameSymbol { * @since v0.3.0 * @throws NullPointerException if any argument is null */ - public static final NameSymbol of(final String name, final String symbol, + public static NameSymbol of(final String name, final String symbol, final Set<String> otherNames) { return new NameSymbol(Optional.of(name), Optional.of(symbol), new HashSet<>(Objects.requireNonNull(otherNames, @@ -98,7 +97,7 @@ public final class NameSymbol { /** * h * Gets a {@code NameSymbol} with a primary name, a symbol and additional * names. - * + * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use @@ -117,14 +116,14 @@ public final class NameSymbol { /** * Gets a {@code NameSymbol} with a primary name, no symbol, and no other * names. - * + * * @param name name to use * @return NameSymbol instance * @since 2019-10-21 * @since v0.3.0 * @throws NullPointerException if name is null */ - public static final NameSymbol ofName(final String name) { + public static NameSymbol ofName(final String name) { return new NameSymbol(Optional.of(name), Optional.empty(), new HashSet<>()); } @@ -139,7 +138,7 @@ public final class NameSymbol { * If {@code name} is null and {@code otherNames} is not empty, a primary * name will be picked from {@code otherNames}. This name will not appear in * getOtherNames(). - * + * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use @@ -147,8 +146,8 @@ public final class NameSymbol { * @since 2019-11-26 * @since v0.3.0 */ - public static final NameSymbol ofNullable(final String name, - final String symbol, final Set<String> otherNames) { + public static NameSymbol ofNullable(final String name, final String symbol, + final Set<String> otherNames) { return NameSymbol.create(name, symbol, otherNames == null ? new HashSet<>() : new HashSet<>(otherNames)); } @@ -163,7 +162,7 @@ public final class NameSymbol { * If {@code name} is null and {@code otherNames} is not empty, a primary * name will be picked from {@code otherNames}. This name will not appear in * getOtherNames(). - * + * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use @@ -179,14 +178,14 @@ public final class NameSymbol { /** * Gets a {@code NameSymbol} with a symbol and no names. - * + * * @param symbol symbol to use * @return NameSymbol instance * @since 2019-10-21 * @since v0.3.0 * @throws NullPointerException if symbol is null */ - public static final NameSymbol ofSymbol(final String symbol) { + public static NameSymbol ofSymbol(final String symbol) { return new NameSymbol(Optional.empty(), Optional.of(symbol), new HashSet<>()); } @@ -198,7 +197,7 @@ public final class NameSymbol { /** * Creates the {@code NameSymbol}. - * + * * @param primaryName primary name of unit * @param symbol symbol used to represent unit * @param otherNames other names and/or spellings, should be a mutable copy @@ -206,8 +205,8 @@ public final class NameSymbol { * @since 2019-10-21 * @since v0.3.0 */ - NameSymbol(final Optional<String> primaryName, - final Optional<String> symbol, final Set<String> otherNames) { + NameSymbol(final Optional<String> primaryName, final Optional<String> symbol, + final Set<String> otherNames) { this.primaryName = primaryName; this.symbol = symbol; if (otherNames != null) { @@ -228,7 +227,7 @@ public final class NameSymbol { return true; if (!(obj instanceof NameSymbol)) return false; - final NameSymbol other = (NameSymbol) obj; + final var other = (NameSymbol) obj; if (this.otherNames == null) { if (other.otherNames != null) return false; @@ -252,7 +251,7 @@ public final class NameSymbol { * @since 2019-10-21 * @since v0.3.0 */ - public final Set<String> getOtherNames() { + public Set<String> getOtherNames() { return this.otherNames; } @@ -261,7 +260,7 @@ public final class NameSymbol { * @since 2019-10-21 * @since v0.3.0 */ - public final Optional<String> getPrimaryName() { + public Optional<String> getPrimaryName() { return this.primaryName; } @@ -270,14 +269,14 @@ public final class NameSymbol { * @since 2019-10-21 * @since v0.3.0 */ - public final Optional<String> getSymbol() { + public Optional<String> getSymbol() { return this.symbol; } @Override public int hashCode() { - final int prime = 31; - int result = 1; + final var prime = 31; + var result = 1; result = prime * result + (this.otherNames == null ? 0 : this.otherNames.hashCode()); result = prime * result @@ -287,10 +286,8 @@ public final class NameSymbol { return result; } - /** - * @return true iff this {@code NameSymbol} contains no names or symbols. - */ - public final boolean isEmpty() { + /** @return true iff this {@code NameSymbol} contains no names or symbols. */ + public boolean isEmpty() { // if primaryName is empty, otherNames must also be empty return this.primaryName.isEmpty() && this.symbol.isEmpty(); } @@ -299,31 +296,30 @@ public final class NameSymbol { public String toString() { if (this.isEmpty()) return "NameSymbol.EMPTY"; - else if (this.primaryName.isPresent() && this.symbol.isPresent()) + if (this.primaryName.isPresent() && this.symbol.isPresent()) return this.primaryName.orElseThrow() + " (" + this.symbol.orElseThrow() + ")"; - else - return this.primaryName.orElseGet(this.symbol::orElseThrow); + return this.primaryName.orElseGet(this.symbol::orElseThrow); } /** * Creates and returns a copy of this {@code NameSymbol} with the provided * extra name. If this {@code NameSymbol} has a primary name, the provided * name will become an other name, otherwise it will become the primary name. - * + * * @param name additional name to add * @return copy of this NameSymbol with the additional name * * @since 2022-04-19 * @since v0.4.0 */ - public final NameSymbol withExtraName(String name) { + public NameSymbol withExtraName(String name) { if (this.primaryName.isPresent()) { final var otherNames = new HashSet<>(this.otherNames); otherNames.add(name); return NameSymbol.ofNullable(this.primaryName.orElse(null), this.symbol.orElse(null), otherNames); - } else - return NameSymbol.ofNullable(name, this.symbol.orElse(null)); + } + return NameSymbol.ofNullable(name, this.symbol.orElse(null)); } }
\ No newline at end of file diff --git a/src/main/java/sevenUnits/utils/Nameable.java b/src/main/java/sevenUnits/utils/Nameable.java index efd1ab8..166de55 100644 --- a/src/main/java/sevenUnits/utils/Nameable.java +++ b/src/main/java/sevenUnits/utils/Nameable.java @@ -34,7 +34,7 @@ public interface Nameable { * @since v0.4.0 */ default String getName() { - final NameSymbol ns = this.getNameSymbol(); + final var ns = this.getNameSymbol(); return ns.getPrimaryName().or(ns::getSymbol).orElse("Unnamed"); } @@ -71,7 +71,7 @@ public interface Nameable { * @since v0.4.0 */ default String getShortName() { - final NameSymbol ns = this.getNameSymbol(); + final var ns = this.getNameSymbol(); return ns.getSymbol().or(ns::getPrimaryName).orElse("Unnamed"); } diff --git a/src/main/java/sevenUnits/utils/ObjectProduct.java b/src/main/java/sevenUnits/utils/ObjectProduct.java index 1b8832e..23fe41c 100644 --- a/src/main/java/sevenUnits/utils/ObjectProduct.java +++ b/src/main/java/sevenUnits/utils/ObjectProduct.java @@ -29,7 +29,7 @@ import java.util.function.Function; /** * An immutable product of multiple objects of a type, such as base units. The * objects can be multiplied and exponentiated. - * + * * @author Adrien Hopkins * @param <T> type of object that is being multiplied * @since 2019-10-16 @@ -41,10 +41,10 @@ public class ObjectProduct<T> implements Nameable { * this value, a warning will be printed to standard error. */ private static final double ROUND_WARN_THRESHOLD = 1e-12; - + /** * Returns an empty ObjectProduct of a certain type - * + * * @param <T> type of objects that can be multiplied * @return empty product * @since 2019-10-16 @@ -53,10 +53,10 @@ public class ObjectProduct<T> implements Nameable { public static final <T> ObjectProduct<T> empty() { return new ObjectProduct<>(new HashMap<>()); } - + /** * Gets an {@code ObjectProduct} from an object-to-integer mapping - * + * * @param <T> type of object in product * @param map map mapping objects to exponents * @return object product @@ -67,13 +67,13 @@ public class ObjectProduct<T> implements Nameable { final Map<T, Integer> map) { return new ObjectProduct<>(new HashMap<>(map)); } - + /** * Gets an ObjectProduct that has one of the inputted argument, and nothing * else. - * + * * @param object object that will be in the product - * @param <T> type of object contained in returned ObjectProduct + * @param <T> type of object contained in returned ObjectProduct * @return product * @since 2019-10-16 * @since v0.3.0 @@ -85,24 +85,22 @@ public class ObjectProduct<T> implements Nameable { map.put(object, 1); return new ObjectProduct<>(map); } - + /** * The objects that make up the product, mapped to their exponents. This map * treats zero as null, and is immutable. - * + * * @since 2019-10-16 * @since v0.3.0 */ final Map<T, Integer> exponents; - - /** - * The object's name and symbol - */ + + /** The object's name and symbol */ private final NameSymbol nameSymbol; - + /** * Creates a {@code ObjectProduct} without a name/symbol. - * + * * @param exponents objects that make up this product * @since 2019-10-16 * @since v0.3.0 @@ -110,10 +108,10 @@ public class ObjectProduct<T> implements Nameable { ObjectProduct(final Map<T, Integer> exponents) { this(exponents, NameSymbol.EMPTY); } - + /** * Creates the {@code ObjectProduct}. - * + * * @param exponents objects that make up this product * @param nameSymbol name and symbol of object product * @since 2019-10-16 @@ -125,7 +123,7 @@ public class ObjectProduct<T> implements Nameable { e -> !Integer.valueOf(0).equals(e.getValue()))); this.nameSymbol = nameSymbol; } - + /** * Calculates the quotient of two products * @@ -141,17 +139,17 @@ public class ObjectProduct<T> implements Nameable { final Set<T> objects = new HashSet<>(); objects.addAll(this.getBaseSet()); objects.addAll(other.getBaseSet()); - + // get a list of all exponents final Map<T, Integer> map = new HashMap<>(objects.size()); for (final T key : objects) { map.put(key, this.getExponent(key) - other.getExponent(key)); } - + // create the product return new ObjectProduct<>(map); } - + // this method relies on the use of ZeroIsNullMap @Override public boolean equals(final Object obj) { @@ -162,7 +160,7 @@ public class ObjectProduct<T> implements Nameable { final ObjectProduct<?> other = (ObjectProduct<?>) obj; return Objects.equals(this.exponents, other.exponents); } - + /** * @return immutable map mapping objects to exponents * @since 2019-10-16 @@ -171,7 +169,7 @@ public class ObjectProduct<T> implements Nameable { public Map<T, Integer> exponentMap() { return this.exponents; } - + /** * @return a set of all of the base objects with non-zero exponents that make * up this dimension. @@ -180,7 +178,7 @@ public class ObjectProduct<T> implements Nameable { */ public final Set<T> getBaseSet() { final Set<T> dimensions = new HashSet<>(); - + // add all dimensions with a nonzero exponent - zero exponents shouldn't // be there in the first place for (final T dimension : this.exponents.keySet()) { @@ -188,13 +186,13 @@ public class ObjectProduct<T> implements Nameable { dimensions.add(dimension); } } - + return dimensions; } - + /** * Gets the exponent for a specific dimension. - * + * * @param dimension dimension to check * @return exponent for that dimension * @since 2018-12-12 @@ -203,17 +201,17 @@ public class ObjectProduct<T> implements Nameable { public int getExponent(final T dimension) { return this.exponents.getOrDefault(dimension, 0); } - + @Override public NameSymbol getNameSymbol() { return this.nameSymbol; } - + @Override public int hashCode() { return Objects.hash(this.exponents); } - + /** * @return true if this product is a single object, i.e. it has one exponent * of one and no other nonzero exponents @@ -221,8 +219,8 @@ public class ObjectProduct<T> implements Nameable { * @since v0.3.0 */ public boolean isSingleObject() { - int oneCount = 0; - boolean twoOrMore = false; // has exponents of 2 or more + var oneCount = 0; + var twoOrMore = false; // has exponents of 2 or more for (final T b : this.getBaseSet()) { if (this.getExponent(b) == 1) { oneCount++; @@ -232,7 +230,7 @@ public class ObjectProduct<T> implements Nameable { } return oneCount == 1 && !twoOrMore; } - + /** * Multiplies this product by another * @@ -248,20 +246,20 @@ public class ObjectProduct<T> implements Nameable { final Set<T> objects = new HashSet<>(); objects.addAll(this.getBaseSet()); objects.addAll(other.getBaseSet()); - + // get a list of all exponents final Map<T, Integer> map = new HashMap<>(objects.size()); for (final T key : objects) { map.put(key, this.getExponent(key) + other.getExponent(key)); } - + // create the product return new ObjectProduct<>(map); } - + /** * Returns this product, but to an exponent - * + * * @param exponent exponent * @return result of exponentiation * @since 2019-10-16 @@ -274,14 +272,14 @@ public class ObjectProduct<T> implements Nameable { } return new ObjectProduct<>(map); } - + /** * Returns this product to an exponent, where every dimension is rounded to * the nearest integer. - * + * * This function will send a warning (via standard error) if the rounding * significantly changes the value. - * + * * @param exponent exponent to raise this product to * @return result of exponentiation * @@ -291,7 +289,7 @@ public class ObjectProduct<T> implements Nameable { public ObjectProduct<T> toExponentRounded(final double exponent) { final Map<T, Integer> map = new HashMap<>(this.exponents); for (final T key : this.exponents.keySet()) { - final double newExponent = this.getExponent(key) * exponent; + final var newExponent = this.getExponent(key) * exponent; if (Math.abs( newExponent - Math.round(newExponent)) > ROUND_WARN_THRESHOLD) { System.err.printf( @@ -303,14 +301,14 @@ public class ObjectProduct<T> implements Nameable { } return new ObjectProduct<>(map); } - + /** * Converts this product to a string using the objects' * {@link Object#toString()} method (or {@link Nameable#getShortName} if * available). If objects have a long toString representation, it is * recommended to use {@link #toString(Function)} instead to shorten the * returned string. - * + * * <p> * {@inheritDoc} */ @@ -320,11 +318,11 @@ public class ObjectProduct<T> implements Nameable { .toString(o -> o instanceof Nameable ? ((Nameable) o).getShortName() : o.toString()); } - + /** * Converts this product to a string. The objects that make up this product * are represented by {@code objectToString} - * + * * @param objectToString function to convert objects to strings * @return string representation of product * @since 2019-10-16 @@ -333,7 +331,7 @@ public class ObjectProduct<T> implements Nameable { public String toString(final Function<T, String> objectToString) { final List<String> positiveStringComponents = new ArrayList<>(); final List<String> negativeStringComponents = new ArrayList<>(); - + // for each base object that makes up this object, add it and its exponent for (final T object : this.getBaseSet()) { final int exponent = this.exponents.get(object); @@ -347,15 +345,15 @@ public class ObjectProduct<T> implements Nameable { objectToString.apply(object), -exponent)); } } - - final String positiveString = positiveStringComponents.isEmpty() ? "1" + + final var positiveString = positiveStringComponents.isEmpty() ? "1" : String.join(" * ", positiveStringComponents); - final String negativeString = negativeStringComponents.isEmpty() ? "" + final var negativeString = negativeStringComponents.isEmpty() ? "" : " / " + String.join(" * ", negativeStringComponents); - + return positiveString + negativeString; } - + /** * @param nameSymbol name to add to this product * @return named version of this {@code ObjectProduct}, using data from diff --git a/src/main/java/sevenUnits/utils/SemanticVersionNumber.java b/src/main/java/sevenUnits/utils/SemanticVersionNumber.java index cde3d37..c081a25 100644 --- a/src/main/java/sevenUnits/utils/SemanticVersionNumber.java +++ b/src/main/java/sevenUnits/utils/SemanticVersionNumber.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -136,7 +135,7 @@ public final class SemanticVersionNumber return true; if (!(obj instanceof Builder)) return false; - final Builder other = (Builder) obj; + final var other = (Builder) obj; return Objects.equals(this.buildMetadata, other.buildMetadata) && this.major == other.major && this.minor == other.minor && this.patch == other.patch && Objects.equals( @@ -249,12 +248,11 @@ public final class SemanticVersionNumber public int compare(SemanticVersionNumber o1, SemanticVersionNumber o2) { Objects.requireNonNull(o1, "o1 may not be null"); Objects.requireNonNull(o2, "o2 may not be null"); - final int naturalComparison = o1.compareTo(o2); + final var naturalComparison = o1.compareTo(o2); if (naturalComparison == 0) return SemanticVersionNumber.compareIdentifiers(o1.buildMetadata, o2.buildMetadata); - else - return naturalComparison; + return naturalComparison; }; }; @@ -283,8 +281,8 @@ public final class SemanticVersionNumber * @since 2022-02-19 * @since v0.4.0 */ - public static final SemanticVersionNumber.Builder builder(int major, - int minor, int patch) { + public static SemanticVersionNumber.Builder builder(int major, int minor, + int patch) { if (major < 0) throw new IllegalArgumentException( "Major version must be non-negative."); @@ -307,57 +305,54 @@ public final class SemanticVersionNumber * @since 2022-02-20 * @since v0.4.0 */ - private static final int compareIdentifiers(List<String> a, List<String> b) { + private static int compareIdentifiers(List<String> a, List<String> b) { // test pre-release size - final int aSize = a.size(); - final int bSize = b.size(); + final var aSize = a.size(); + final var bSize = b.size(); // no identifiers is greater than any identifiers if (aSize != 0 && bSize == 0) return -1; - else if (aSize == 0 && bSize != 0) + if (aSize == 0 && bSize != 0) return 1; // test identifiers one by one - for (int i = 0; i < Math.min(aSize, bSize); i++) { - final String aElement = a.get(i); - final String bElement = b.get(i); + for (var i = 0; i < Math.min(aSize, bSize); i++) { + final var aElement = a.get(i); + final var bElement = b.get(i); if (NUMERIC_IDENTIFER.matcher(aElement).matches()) { - if (NUMERIC_IDENTIFER.matcher(bElement).matches()) { - // both are numbers, compare them - final int aNumber = Integer.parseInt(aElement); - final int bNumber = Integer.parseInt(bElement); - - if (aNumber < bNumber) - return -1; - else if (aNumber > bNumber) - return 1; - } else + if (!NUMERIC_IDENTIFER.matcher(bElement).matches()) // aElement is a number and bElement is not a number // by the rules, a goes before b return -1; - } else { - if (NUMERIC_IDENTIFER.matcher(bElement).matches()) - // aElement is not a number but bElement is - // by the rules, a goes after b + // both are numbers, compare them + final var aNumber = Integer.parseInt(aElement); + final var bNumber = Integer.parseInt(bElement); + + if (aNumber < bNumber) + return -1; + else if (aNumber > bNumber) return 1; - else { - // both are not numbers, compare them - final int comparison = aElement.compareTo(bElement); - if (comparison != 0) - return comparison; - } + } else if (NUMERIC_IDENTIFER.matcher(bElement).matches()) + // aElement is not a number but bElement is + // by the rules, a goes after b + return 1; + else { + // both are not numbers, compare them + final var comparison = aElement.compareTo(bElement); + if (comparison != 0) + return comparison; } } - - // we just tested the stuff that's in common, maybe someone has more if (aSize < bSize) return -1; - else if (aSize > bSize) + if (aSize > bSize) return 1; - else - return 0; + return 0; + + // we just tested the stuff that's in common, maybe someone has more + } /** @@ -369,19 +364,19 @@ public final class SemanticVersionNumber * @since v0.4.0 * @see #toString */ - public static final SemanticVersionNumber fromString(String versionString) { + public static SemanticVersionNumber fromString(String versionString) { // parse & validate version string Objects.requireNonNull(versionString, "versionString may not be null"); - final Matcher m = VERSION_NUMBER.matcher(versionString); + final var m = VERSION_NUMBER.matcher(versionString); if (!m.matches()) throw new IllegalArgumentException( String.format("Provided string \"%s\" is not a version number", versionString)); // main parts - final int major = Integer.parseInt(m.group(1)); - final int minor = Integer.parseInt(m.group(2)); - final int patch = Integer.parseInt(m.group(3)); + final var major = Integer.parseInt(m.group(1)); + final var minor = Integer.parseInt(m.group(2)); + final var patch = Integer.parseInt(m.group(3)); // pre release final List<String> preRelease; @@ -406,13 +401,13 @@ public final class SemanticVersionNumber /** * Tests whether a string is a valid Semantic Version string - * + * * @param versionString string to test * @return true iff string is valid * @since 2022-02-19 * @since v0.4.0 */ - public static final boolean isValidVersionString(String versionString) { + public static boolean isValidVersionString(String versionString) { return VERSION_NUMBER.matcher(versionString).matches(); } @@ -432,7 +427,7 @@ public final class SemanticVersionNumber * @since 2022-02-19 * @since v0.4.0 */ - public static final SemanticVersionNumber preRelease(int major, int minor, + public static SemanticVersionNumber preRelease(int major, int minor, int patch, String preReleaseType, int preReleaseNumber) { if (major < 0) throw new IllegalArgumentException( @@ -470,7 +465,7 @@ public final class SemanticVersionNumber * @since 2022-02-19 * @since v0.4.0 */ - public static final SemanticVersionNumber stableVersion(int major, int minor, + public static SemanticVersionNumber stableVersion(int major, int minor, int patch) { if (major < 0) throw new IllegalArgumentException( @@ -536,17 +531,17 @@ public final class SemanticVersionNumber // test the three big numbers in order first if (this.major < o.major) return -1; - else if (this.major > o.major) + if (this.major > o.major) return 1; if (this.minor < o.minor) return -1; - else if (this.minor > o.minor) + if (this.minor > o.minor) return 1; if (this.patch < o.patch) return -1; - else if (this.patch > o.patch) + if (this.patch > o.patch) return 1; // now we just compare pre-release identifiers @@ -569,7 +564,7 @@ public final class SemanticVersionNumber * </ul> * If this function returns <b>false</b>, you may have to change your code to * upgrade it to {@code other} - * + * * <p> * Two version numbers that are identical (ignoring build metadata) are * always compatible. Different version numbers are compatible as long as: @@ -601,17 +596,13 @@ public final class SemanticVersionNumber return true; if (!(obj instanceof SemanticVersionNumber)) return false; - final SemanticVersionNumber other = (SemanticVersionNumber) obj; + final var other = (SemanticVersionNumber) obj; if (this.buildMetadata == null) { if (other.buildMetadata != null) return false; } else if (!this.buildMetadata.equals(other.buildMetadata)) return false; - if (this.major != other.major) - return false; - if (this.minor != other.minor) - return false; - if (this.patch != other.patch) + if ((this.major != other.major) || (this.minor != other.minor) || (this.patch != other.patch)) return false; if (this.preReleaseIdentifiers == null) { if (other.preReleaseIdentifiers != null) @@ -624,8 +615,8 @@ public final class SemanticVersionNumber @Override public int hashCode() { - final int prime = 31; - int result = 1; + final var prime = 31; + var result = 1; result = prime * result + (this.buildMetadata == null ? 0 : this.buildMetadata.hashCode()); result = prime * result + this.major; @@ -697,13 +688,13 @@ public final class SemanticVersionNumber * For example, the version with major number 3, minor number 2, patch number * 1, pre-release identifiers "alpha" and "1" and build metadata "2022-02-19" * has a string representation "3.2.1-alpha.1+2022-02-19". - * + * * @since v0.4.0 * @see <a href="https://semver.org">The official SemVer specification</a> */ @Override public String toString() { - String versionString = String.format("%d.%d.%d", this.major, this.minor, + var versionString = String.format("%d.%d.%d", this.major, this.minor, this.patch); if (!this.preReleaseIdentifiers.isEmpty()) { versionString += "-" + String.join(".", this.preReleaseIdentifiers); diff --git a/src/main/java/sevenUnits/utils/UncertainDouble.java b/src/main/java/sevenUnits/utils/UncertainDouble.java index f700454..ecee586 100644 --- a/src/main/java/sevenUnits/utils/UncertainDouble.java +++ b/src/main/java/sevenUnits/utils/UncertainDouble.java @@ -19,7 +19,6 @@ package sevenUnits.utils; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Objects; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -32,16 +31,12 @@ import java.util.regex.Pattern; * @since v0.3.0 */ public final class UncertainDouble implements Comparable<UncertainDouble> { - /** - * The exact value 0 - */ + /** The exact value 0 */ public static final UncertainDouble ZERO = UncertainDouble.of(0, 0); static final String NUMBER_REGEX = "(\\d+(?:[\\.,]\\d+))"; - /** - * A regular expression that can recognize toString forms - */ + /** A regular expression that can recognize toString forms */ static final Pattern TO_STRING = Pattern.compile(NUMBER_REGEX // optional "± [number]" + "(?:\\s*(?:±|\\+-)\\s*" + NUMBER_REGEX + ")?"); @@ -50,18 +45,18 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * Gets an UncertainDouble from a double string. The uncertainty of the * double will be one of the lowest decimal place of the number. For example, * "12345.678" will become 12345.678 ± 0.001. - * + * * @param s string to parse * @return parsed {@code UncertainDouble} - * + * * @throws NumberFormatException if the argument is not a number * * @since 2022-04-18 * @since v0.4.0 */ - public static final UncertainDouble fromRoundedString(String s) { - final BigDecimal value = new BigDecimal(s); - final double uncertainty = Math.pow(10, -value.scale()); + public static UncertainDouble fromRoundedString(String s) { + final var value = new BigDecimal(s); + final var uncertainty = Math.pow(10, -value.scale()); return UncertainDouble.of(value.doubleValue(), uncertainty); } @@ -72,16 +67,16 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * <p> * This method allows some alternative forms of the string representation, * such as using "+-" instead of "±". - * + * * @param s string to parse * @return {@code UncertainDouble} instance * @throws IllegalArgumentException if the string is invalid * @since 2020-09-07 * @since v0.3.0 */ - public static final UncertainDouble fromString(String s) { + public static UncertainDouble fromString(String s) { Objects.requireNonNull(s, "s may not be null"); - final Matcher matcher = TO_STRING.matcher(s); + final var matcher = TO_STRING.matcher(s); if (!matcher.matches()) throw new IllegalArgumentException( @@ -95,7 +90,7 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { "String " + s + " not in correct format."); } - final String uncertaintyString = matcher.group(2); + final var uncertaintyString = matcher.group(2); if (uncertaintyString == null) { uncertainty = 0; } else { @@ -113,32 +108,32 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * Gets an {@code UncertainDouble} from its value and <b>absolute</b> * uncertainty. - * + * * @param value double's value * @param uncertainty double's uncertainty (non-negative) * @return {@code UncertainDouble} instance with these parameters - * + * * @since 2020-09-07 * @since v0.3.0 */ - public static final UncertainDouble of(double value, double uncertainty) { + public static UncertainDouble of(double value, double uncertainty) { return new UncertainDouble(value, uncertainty); } /** * Gets an {@code UncertainDouble} from its value and <b>relative</b> * uncertainty. - * + * * @param value double's value * @param relativeUncertainty double's uncertainty (non-negative); the * absolute uncertainty is equal to this value * multiplied by {@code relativeUncertainty} * @return {@code UncertainDouble} instance with these parameters - * + * * @since 2020-09-07 * @since v0.3.0 */ - public static final UncertainDouble ofRelative(double value, + public static UncertainDouble ofRelative(double value, double relativeUncertainty) { return new UncertainDouble(value, value * relativeUncertainty); } @@ -173,20 +168,20 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * {@code false}. */ @Override - public final int compareTo(UncertainDouble o) { + public int compareTo(UncertainDouble o) { return Double.compare(this.value, o.value); } /** * Returns the quotient of {@code this} and {@code other}. - * + * * @param other number to divide by * @return quotient - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble dividedBy(UncertainDouble other) { + public UncertainDouble dividedBy(UncertainDouble other) { Objects.requireNonNull(other, "other may not be null"); return UncertainDouble.ofRelative(this.value / other.value, Math .hypot(this.relativeUncertainty(), other.relativeUncertainty())); @@ -194,27 +189,25 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * Returns the quotient of {@code this} and the exact value {@code other}. - * + * * @param other number to divide by * @return quotient - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble dividedByExact(double other) { + public UncertainDouble dividedByExact(double other) { return UncertainDouble.of(this.value / other, this.uncertainty / other); } @Override - public final boolean equals(Object obj) { + public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof UncertainDouble)) return false; - final UncertainDouble other = (UncertainDouble) obj; - if (Double.compare(this.value, other.value) != 0) - return false; - if (Double.compare(this.uncertainty, other.uncertainty) != 0) + final var other = (UncertainDouble) obj; + if ((Double.compare(this.value, other.value) != 0) || (Double.compare(this.uncertainty, other.uncertainty) != 0)) return false; return true; } @@ -226,7 +219,7 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * @since 2020-09-07 * @since v0.3.0 */ - public final boolean equivalent(UncertainDouble other) { + public boolean equivalent(UncertainDouble other) { Objects.requireNonNull(other, "other may not be null"); return Math.abs(this.value - other.value) <= Math.min(this.uncertainty, other.uncertainty); @@ -234,11 +227,11 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * Gets the preferred scale for rounding a value for toString. - * + * * @since 2020-09-07 * @since v0.3.0 */ - private final int getDisplayScale() { + private int getDisplayScale() { // round based on uncertainty // if uncertainty starts with 1 (ignoring zeroes and the decimal // point), rounds @@ -246,24 +239,23 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { // otherwise, rounds so that uncertainty has 1 significant digits. // the value is rounded to the same number of decimal places as the // uncertainty. - final BigDecimal bigUncertainty = BigDecimal.valueOf(this.uncertainty); + final var bigUncertainty = BigDecimal.valueOf(this.uncertainty); // the scale that will give the uncertainty two decimal places - final int twoDecimalPlacesScale = bigUncertainty.scale() + final var twoDecimalPlacesScale = bigUncertainty.scale() - bigUncertainty.precision() + 2; - final BigDecimal roundedUncertainty = bigUncertainty + final var roundedUncertainty = bigUncertainty .setScale(twoDecimalPlacesScale, RoundingMode.HALF_EVEN); if (roundedUncertainty.unscaledValue().intValue() >= 20) return twoDecimalPlacesScale - 1; // one decimal place - else - return twoDecimalPlacesScale; + return twoDecimalPlacesScale; } @Override - public final int hashCode() { - final int prime = 31; - int result = 1; + public int hashCode() { + final var prime = 31; + var result = 1; result = prime * result + Double.hashCode(this.value); result = prime * result + Double.hashCode(this.uncertainty); return result; @@ -271,24 +263,24 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * @return true iff the value has no uncertainty - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final boolean isExact() { + public boolean isExact() { return this.uncertainty == 0; } /** * Returns the difference of {@code this} and {@code other}. - * + * * @param other number to subtract * @return result of subtraction - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble minus(UncertainDouble other) { + public UncertainDouble minus(UncertainDouble other) { Objects.requireNonNull(other, "other may not be null"); return UncertainDouble.of(this.value - other.value, Math.hypot(this.uncertainty, other.uncertainty)); @@ -296,27 +288,27 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * Returns the difference of {@code this} and the exact value {@code other}. - * + * * @param other number to subtract * @return result of subtraction - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble minusExact(double other) { + public UncertainDouble minusExact(double other) { return UncertainDouble.of(this.value - other, this.uncertainty); } /** * Returns the sum of {@code this} and {@code other}. - * + * * @param other number to add * @return result of addition - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble plus(UncertainDouble other) { + public UncertainDouble plus(UncertainDouble other) { Objects.requireNonNull(other, "other may not be null"); return UncertainDouble.of(this.value + other.value, Math.hypot(this.uncertainty, other.uncertainty)); @@ -324,14 +316,14 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * Returns the sum of {@code this} and the exact value {@code other}. - * + * * @param other number to add * @return result of addition - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble plusExact(double other) { + public UncertainDouble plusExact(double other) { return UncertainDouble.of(this.value + other, this.uncertainty); } @@ -340,20 +332,20 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * @since 2020-09-07 * @since v0.3.0 */ - public final double relativeUncertainty() { + public double relativeUncertainty() { return this.uncertainty / this.value; } /** * Returns the product of {@code this} and {@code other}. - * + * * @param other number to multiply * @return product - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble times(UncertainDouble other) { + public UncertainDouble times(UncertainDouble other) { Objects.requireNonNull(other, "other may not be null"); return UncertainDouble.ofRelative(this.value * other.value, Math .hypot(this.relativeUncertainty(), other.relativeUncertainty())); @@ -361,31 +353,31 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * Returns the product of {@code this} and the exact value {@code other}. - * + * * @param other number to multiply * @return product - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble timesExact(double other) { + public UncertainDouble timesExact(double other) { return UncertainDouble.of(this.value * other, this.uncertainty * other); } /** * Returns the result of {@code this} raised to the exponent {@code other}. - * + * * @param other exponent * @return result of exponentation - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble toExponent(UncertainDouble other) { + public UncertainDouble toExponent(UncertainDouble other) { Objects.requireNonNull(other, "other may not be null"); - final double result = Math.pow(this.value, other.value); - final double relativeUncertainty = Math.hypot( + final var result = Math.pow(this.value, other.value); + final var relativeUncertainty = Math.hypot( other.value * this.relativeUncertainty(), Math.log(this.value) * other.uncertainty); @@ -395,14 +387,14 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { /** * Returns the result of {@code this} raised the exact exponent * {@code other}. - * + * * @param other exponent * @return result of exponentation - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final UncertainDouble toExponentExact(double other) { + public UncertainDouble toExponentExact(double other) { return UncertainDouble.ofRelative(Math.pow(this.value, other), this.relativeUncertainty() * other); } @@ -413,21 +405,21 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * This method returns the same value as * {@link #toString(boolean, RoundingMode)}, but {@code showUncertainty} is * true if and only if the uncertainty is non-zero. - * + * * <p> * Examples: - * + * * <pre> * UncertainDouble.of(3.27, 0.22).toString() = "3.3 � 0.2" * UncertainDouble.of(3.27, 0.13).toString() = "3.27 � 0.13" * UncertainDouble.of(-5.01, 0).toString() = "-5.01" * </pre> - * + * * @since 2020-09-07 * @since v0.3.0 */ @Override - public final String toString() { + public String toString() { return this.toString(!this.isExact(), RoundingMode.HALF_EVEN); } @@ -447,7 +439,7 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * digits otherwise it will be rounded to one significant digit. * <p> * Examples: - * + * * <pre> * UncertainDouble.of(3.27, 0.22).toString(false) = "3.3" * UncertainDouble.of(3.27, 0.22).toString(true) = "3.3 ± 0.2" @@ -456,16 +448,15 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * UncertainDouble.of(-5.01, 0).toString(false) = "-5.01" * UncertainDouble.of(-5.01, 0).toString(true) = "-5.01 ± 0.0" * </pre> - * + * * @param showUncertainty uncertainty is only shown if this parameter is true - * @param roundingMode how to round values + * @param roundingMode how to round values * @return string representation of this {@code UncertainDouble} - * + * * @since 2020-09-07 * @since v0.3.0 */ - public final String toString(boolean showUncertainty, - RoundingMode roundingMode) { + public String toString(boolean showUncertainty, RoundingMode roundingMode) { String valueString, uncertaintyString; // generate the string representation of value and uncertainty @@ -475,13 +466,13 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { } else { // round the value and uncertainty according to getDisplayScale() - final BigDecimal bigValue = BigDecimal.valueOf(this.value); - final BigDecimal bigUncertainty = BigDecimal.valueOf(this.uncertainty); + final var bigValue = BigDecimal.valueOf(this.value); + final var bigUncertainty = BigDecimal.valueOf(this.uncertainty); - final int displayScale = this.getDisplayScale(); - final BigDecimal roundedUncertainty = bigUncertainty + final var displayScale = this.getDisplayScale(); + final var roundedUncertainty = bigUncertainty .setScale(displayScale, roundingMode); - final BigDecimal roundedValue = bigValue.setScale(displayScale, + final var roundedValue = bigValue.setScale(displayScale, roundingMode); valueString = roundedValue.toString(); @@ -497,7 +488,7 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * @since 2020-09-07 * @since v0.3.0 */ - public final double uncertainty() { + public double uncertainty() { return this.uncertainty; } @@ -506,7 +497,7 @@ public final class UncertainDouble implements Comparable<UncertainDouble> { * @since 2020-09-07 * @since v0.3.0 */ - public final double value() { + public double value() { return this.value; } } diff --git a/src/main/java/sevenUnits/utils/package-info.java b/src/main/java/sevenUnits/utils/package-info.java index 6cae117..b600c17 100644 --- a/src/main/java/sevenUnits/utils/package-info.java +++ b/src/main/java/sevenUnits/utils/package-info.java @@ -17,7 +17,7 @@ /** * Supplementary classes that are not related to units, but are necessary for * their function. - * + * * @author Adrien Hopkins * @since 2019-03-14 * @since v0.2.0 diff --git a/src/main/java/sevenUnitsGUI/DefaultPrefixRepetitionRule.java b/src/main/java/sevenUnitsGUI/DefaultPrefixRepetitionRule.java index 97df107..a441911 100644 --- a/src/main/java/sevenUnitsGUI/DefaultPrefixRepetitionRule.java +++ b/src/main/java/sevenUnitsGUI/DefaultPrefixRepetitionRule.java @@ -56,7 +56,7 @@ public enum DefaultPrefixRepetitionRule implements Predicate<List<UnitPrefix>> { final boolean magnifying; if (prefixes.isEmpty()) return true; - else if (prefixes.get(0).getMultiplier() > 1) { + if (prefixes.get(0).getMultiplier() > 1) { magnifying = true; } else { magnifying = false; @@ -68,15 +68,13 @@ public enum DefaultPrefixRepetitionRule implements Predicate<List<UnitPrefix>> { if (!Metric.DECIMAL_PREFIXES.contains(prefixes.get(0))) return NO_REPETITION.test(prefixes); - int part = 0; // 0=yotta/yoctos, 1=kilo-zetta/milli-zepto, + var part = 0; // 0=yotta/yoctos, 1=kilo-zetta/milli-zepto, // 2=deka,hecto,deci,centi for (final UnitPrefix prefix : prefixes) { // check that the current prefix is metric and appropriately // magnifying/reducing - if (!Metric.DECIMAL_PREFIXES.contains(prefix)) - return false; - if (magnifying != prefix.getMultiplier() > 1) + if (!Metric.DECIMAL_PREFIXES.contains(prefix) || (magnifying != prefix.getMultiplier() > 1)) return false; // check if the current prefix is correct diff --git a/src/main/java/sevenUnitsGUI/DelegateListModel.java b/src/main/java/sevenUnitsGUI/DelegateListModel.java index 200eee2..da4f978 100644 --- a/src/main/java/sevenUnitsGUI/DelegateListModel.java +++ b/src/main/java/sevenUnitsGUI/DelegateListModel.java @@ -31,7 +31,7 @@ import javax.swing.AbstractListModel; * the delegated list's methods because the delegate methods handle updating the * list. * </p> - * + * * @author Adrien Hopkins * @since 2019-01-14 * @since v0.1.0 @@ -46,7 +46,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> /** * The list that this model is a delegate to. - * + * * @since 2019-01-14 * @since v0.1.0 */ @@ -54,7 +54,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> /** * Creates an empty {@code DelegateListModel}. - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -64,7 +64,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> /** * Creates the {@code DelegateListModel}. - * + * * @param delegate list to delegate * @since 2019-01-14 * @since v0.1.0 @@ -75,8 +75,8 @@ final class DelegateListModel<E> extends AbstractListModel<E> @Override public boolean add(final E element) { - final int index = this.delegate.size(); - final boolean success = this.delegate.add(element); + final var index = this.delegate.size(); + final var success = this.delegate.add(element); this.fireIntervalAdded(this, index, index); return success; } @@ -89,7 +89,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> @Override public boolean addAll(final Collection<? extends E> c) { - boolean changed = false; + var changed = false; for (final E e : c) { if (this.add(e)) { changed = true; @@ -109,7 +109,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> @Override public void clear() { - final int oldSize = this.delegate.size(); + final var oldSize = this.delegate.size(); this.delegate.clear(); if (oldSize >= 1) { this.fireIntervalRemoved(this, 0, oldSize - 1); @@ -177,7 +177,7 @@ final class DelegateListModel<E> extends AbstractListModel<E> @Override public E remove(final int index) { - final E returnValue = this.delegate.get(index); + final var returnValue = this.delegate.get(index); this.delegate.remove(index); this.fireIntervalRemoved(this, index, index); return returnValue; @@ -185,15 +185,15 @@ final class DelegateListModel<E> extends AbstractListModel<E> @Override public boolean remove(final Object o) { - final int index = this.delegate.indexOf(o); - final boolean returnValue = this.delegate.remove(o); + final var index = this.delegate.indexOf(o); + final var returnValue = this.delegate.remove(o); this.fireIntervalRemoved(this, index, index); return returnValue; } @Override public boolean removeAll(final Collection<?> c) { - boolean changed = false; + var changed = false; for (final Object e : c) { if (this.remove(e)) { changed = true; @@ -204,15 +204,15 @@ final class DelegateListModel<E> extends AbstractListModel<E> @Override public boolean retainAll(final Collection<?> c) { - final int oldSize = this.size(); - final boolean returnValue = this.delegate.retainAll(c); + final var oldSize = this.size(); + final var returnValue = this.delegate.retainAll(c); this.fireIntervalRemoved(this, this.size(), oldSize - 1); return returnValue; } @Override public E set(final int index, final E element) { - final E returnValue = this.delegate.get(index); + final var returnValue = this.delegate.get(index); this.delegate.set(index, element); this.fireContentsChanged(this, index, index); return returnValue; diff --git a/src/main/java/sevenUnitsGUI/ExpressionConversionView.java b/src/main/java/sevenUnitsGUI/ExpressionConversionView.java index 20eb23c..ce69365 100644 --- a/src/main/java/sevenUnitsGUI/ExpressionConversionView.java +++ b/src/main/java/sevenUnitsGUI/ExpressionConversionView.java @@ -18,7 +18,7 @@ package sevenUnitsGUI; /** * A View that can convert unit expressions - * + * * @author Adrien Hopkins * @since 2021-12-15 * @since v0.4.0 @@ -40,7 +40,7 @@ public interface ExpressionConversionView extends View { /** * Shows the output of an expression conversion to the user. - * + * * @param uc unit conversion to show * @since 2021-12-15 * @since v0.4.0 diff --git a/src/main/java/sevenUnitsGUI/FilterComparator.java b/src/main/java/sevenUnitsGUI/FilterComparator.java index d7a59c4..ff942fb 100644 --- a/src/main/java/sevenUnitsGUI/FilterComparator.java +++ b/src/main/java/sevenUnitsGUI/FilterComparator.java @@ -21,9 +21,9 @@ import java.util.Objects; /** * A comparator that compares strings using a filter. - * + * * @param <T> type of element being compared - * + * * @author Adrien Hopkins * @since 2019-01-15 * @since v0.1.0 @@ -31,21 +31,21 @@ import java.util.Objects; final class FilterComparator<T> implements Comparator<T> { /** * The filter that the comparator is filtered by. - * + * * @since 2019-01-15 * @since v0.1.0 */ private final String filter; /** * The comparator to use if the arguments are otherwise equal. - * + * * @since 2019-01-15 * @since v0.1.0 */ private final Comparator<T> comparator; /** * Whether or not the comparison is case-sensitive. - * + * * @since 2019-04-14 * @since v0.2.0 */ @@ -53,7 +53,7 @@ final class FilterComparator<T> implements Comparator<T> { /** * Creates the {@code FilterComparator}. - * + * * @param filter * @since 2019-01-15 * @since v0.1.0 @@ -64,7 +64,7 @@ final class FilterComparator<T> implements Comparator<T> { /** * Creates the {@code FilterComparator}. - * + * * @param filter string to filter by * @param comparator comparator to fall back to if all else fails, null is * compareTo. @@ -79,7 +79,7 @@ final class FilterComparator<T> implements Comparator<T> { /** * Creates the {@code FilterComparator}. - * + * * @param filter string to filter by * @param comparator comparator to fall back to if all else fails, null is * compareTo. @@ -118,19 +118,18 @@ final class FilterComparator<T> implements Comparator<T> { // elements that start with the filter always go first if (str0.startsWith(this.filter) && !str1.startsWith(this.filter)) return -1; - else if (!str0.startsWith(this.filter) && str1.startsWith(this.filter)) + if (!str0.startsWith(this.filter) && str1.startsWith(this.filter)) return 1; // elements that contain the filter but don't start with them go next if (str0.contains(this.filter) && !str1.contains(this.filter)) return -1; - else if (!str0.contains(this.filter) && !str1.contains(this.filter)) + if (!str0.contains(this.filter) && !str1.contains(this.filter)) return 1; // other elements go last if (this.comparator == null) return str0.compareTo(str1); - else - return this.comparator.compare(arg0, arg1); + return this.comparator.compare(arg0, arg1); } } diff --git a/src/main/java/sevenUnitsGUI/GridBagBuilder.java b/src/main/java/sevenUnitsGUI/GridBagBuilder.java index 81d1e79..a9fede3 100644 --- a/src/main/java/sevenUnitsGUI/GridBagBuilder.java +++ b/src/main/java/sevenUnitsGUI/GridBagBuilder.java @@ -21,7 +21,7 @@ import java.awt.Insets; /** * A builder for Java's {@link java.awt.GridBagConstraints} class. - * + * * @author Adrien Hopkins * @since 2018-11-30 * @since v0.1.0 @@ -40,7 +40,7 @@ final class GridBagBuilder { * <p> * The default value is <code>RELATIVE</code>. <code>gridx</code> should be a * non-negative value. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#gridy @@ -58,7 +58,7 @@ final class GridBagBuilder { * <p> * The default value is <code>RELATIVE</code>. <code>gridy</code> should be a * non-negative value. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#gridx @@ -76,7 +76,7 @@ final class GridBagBuilder { * from <code>gridx</code> to the next to the last one in its row. * <p> * <code>gridwidth</code> should be non-negative and the default value is 1. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#gridheight @@ -96,7 +96,7 @@ final class GridBagBuilder { * <p> * <code>gridheight</code> should be a non-negative value and the default * value is 1. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#gridwidth @@ -119,7 +119,7 @@ final class GridBagBuilder { * <p> * The default value of this field is <code>0</code>. <code>weightx</code> * should be a non-negative value. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#weighty @@ -142,7 +142,7 @@ final class GridBagBuilder { * <p> * The default value of this field is <code>0</code>. <code>weighty</code> * should be a non-negative value. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#weightx @@ -173,7 +173,7 @@ final class GridBagBuilder { * <code>BELOW_BASELINE</code>, <code>BELOW_BASELINE_LEADING</code>, and * <code>BELOW_BASELINE_TRAILING</code>. The default value is * <code>CENTER</code>. - * + * * @serial * @see #clone() * @see java.awt.ComponentOrientation @@ -199,7 +199,7 @@ final class GridBagBuilder { * </ul> * <p> * The default value is <code>NONE</code>. - * + * * @serial * @see #clone() */ @@ -212,7 +212,7 @@ final class GridBagBuilder { * amount of space between the component and the edges of its display area. * <p> * The default value is <code>new Insets(0, 0, 0, 0)</code>. - * + * * @serial * @see #clone() */ @@ -226,7 +226,7 @@ final class GridBagBuilder { * is at least its minimum width plus <code>ipadx</code> pixels. * <p> * The default value is <code>0</code>. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#ipady @@ -241,7 +241,7 @@ final class GridBagBuilder { * least its minimum height plus <code>ipady</code> pixels. * <p> * The default value is 0. - * + * * @serial * @see #clone() * @see java.awt.GridBagConstraints#ipadx @@ -292,7 +292,6 @@ final class GridBagBuilder { final int gridheight, final double weightx, final double weighty, final int anchor, final int fill, final Insets insets, final int ipadx, final int ipady) { - super(); this.gridx = gridx; this.gridy = gridy; this.gridwidth = gridwidth; diff --git a/src/main/java/sevenUnitsGUI/PrefixSearchRule.java b/src/main/java/sevenUnitsGUI/PrefixSearchRule.java index 2ea0923..73d12bc 100644 --- a/src/main/java/sevenUnitsGUI/PrefixSearchRule.java +++ b/src/main/java/sevenUnitsGUI/PrefixSearchRule.java @@ -73,7 +73,7 @@ public final class PrefixSearchRule implements * @since 2022-07-06 * @since v0.4.0 */ - public static final PrefixSearchRule getCoherentOnlyRule( + public static PrefixSearchRule getCoherentOnlyRule( Set<UnitPrefix> prefixes) { return new PrefixSearchRule(prefixes, u -> u.isCoherent() && !u.getName().equals("kilogram")); @@ -87,19 +87,14 @@ public final class PrefixSearchRule implements * @since 2022-07-06 * @since v0.4.0 */ - public static final PrefixSearchRule getUniversalRule( - Set<UnitPrefix> prefixes) { + public static PrefixSearchRule getUniversalRule(Set<UnitPrefix> prefixes) { return new PrefixSearchRule(prefixes, u -> true); } - /** - * The set of prefixes that will be applied to the unit. - */ + /** The set of prefixes that will be applied to the unit. */ private final Set<UnitPrefix> prefixes; - /** - * Determines which units are given prefixes. - */ + /** Determines which units are given prefixes. */ private final Predicate<LinearUnit> prefixableUnitRule; /** @@ -118,8 +113,8 @@ public final class PrefixSearchRule implements @Override public Map<String, LinearUnit> apply(Entry<String, LinearUnit> t) { final Map<String, LinearUnit> outputUnits = new HashMap<>(); - final String originalName = t.getKey(); - final LinearUnit originalUnit = t.getValue(); + final var originalName = t.getKey(); + final var originalUnit = t.getValue(); outputUnits.put(originalName, originalUnit); if (this.prefixableUnitRule.test(originalUnit)) { for (final UnitPrefix prefix : this.prefixes) { @@ -136,7 +131,7 @@ public final class PrefixSearchRule implements return true; if (!(obj instanceof PrefixSearchRule)) return false; - final PrefixSearchRule other = (PrefixSearchRule) obj; + final var other = (PrefixSearchRule) obj; return Objects.equals(this.prefixableUnitRule, other.prefixableUnitRule) && Objects.equals(this.prefixes, other.prefixes); } diff --git a/src/main/java/sevenUnitsGUI/Presenter.java b/src/main/java/sevenUnitsGUI/Presenter.java index 9913e89..7fd979a 100644 --- a/src/main/java/sevenUnitsGUI/Presenter.java +++ b/src/main/java/sevenUnitsGUI/Presenter.java @@ -86,11 +86,11 @@ public final class Presenter { * </ul> */ static final String DEFAULT_LOCALE = "en"; - + private static final List<String> LOCAL_LOCALES = List.of("en", "fr"); private static final Path USER_LOCALES_DIR = userConfigDir() .resolve("SevenUnits").resolve("locales"); - + /** * Adds default units and dimensions to a database. * @@ -112,14 +112,14 @@ public final class Presenter { // nonlinear units - must be loaded manually database.addUnit("tempCelsius", Metric.CELSIUS); database.addUnit("tempFahrenheit", BritishImperial.FAHRENHEIT); - + // load initial dimensions database.addDimension("Length", Metric.Dimensions.LENGTH); database.addDimension("Mass", Metric.Dimensions.MASS); database.addDimension("Time", Metric.Dimensions.TIME); database.addDimension("Temperature", Metric.Dimensions.TEMPERATURE); } - + private static String displayRuleToString( Function<UncertainDouble, String> numberDisplayRule) { if (numberDisplayRule instanceof FixedDecimals) @@ -128,12 +128,11 @@ public final class Presenter { if (numberDisplayRule instanceof FixedPrecision) return String.format("FIXED_PRECISION %d", ((FixedPrecision) numberDisplayRule).significantFigures()); - else if (numberDisplayRule instanceof UncertaintyBased) + if (numberDisplayRule instanceof UncertaintyBased) return "UNCERTAINTY_BASED"; - else - return numberDisplayRule.toString(); + return numberDisplayRule.toString(); } - + /** * Determines where to wrap {@code toWrap} with a max line length of * {@code maxLineLength}. If no good spot is found, returns -1. @@ -148,7 +147,7 @@ public final class Presenter { } return -1; } - + /** * Gets the text of a resource file as a set of strings (each one is one line * of the text). @@ -160,7 +159,7 @@ public final class Presenter { */ private static List<String> getLinesFromResource(String filename) { final List<String> lines = new ArrayList<>(); - + try (var stream = inputStream(filename); var scanner = new Scanner(stream)) { while (scanner.hasNextLine()) { @@ -170,10 +169,10 @@ public final class Presenter { throw new AssertionError( "Error occurred while loading file " + filename, e); } - + return lines; } - + /** * Gets an input stream for a resource file. * @@ -185,7 +184,7 @@ public final class Presenter { private static InputStream inputStream(String filepath) { return Presenter.class.getResourceAsStream(filepath); } - + /** * Convert a linear unit value to a string, where the number is rounded to * the nearest integer. @@ -196,38 +195,37 @@ public final class Presenter { private static String linearUnitValueIntToString(LinearUnitValue uv) { return Long.toString(Math.round(uv.getValueExact())) + " " + uv.getUnit(); } - + private static Map.Entry<String, String> parseSettingLine(String line) { final var equalsIndex = line.indexOf('='); if (equalsIndex == -1) throw new IllegalStateException( "Settings file is malformed at line: " + line); - + final var param = line.substring(0, equalsIndex); final var value = line.substring(equalsIndex + 1); - + return Map.entry(param, value); } - + /** Gets a Path from a pathname in the config file. */ private static Path pathFromConfig(String pathname) { return CONFIG_FILE.getParent().resolve(pathname); } - + // ====== SETTINGS ====== - + private static String searchRuleToString( Function<Map.Entry<String, LinearUnit>, Map<String, LinearUnit>> searchRule) { if (PrefixSearchRule.NO_PREFIXES.equals(searchRule)) return "NO_PREFIXES"; if (PrefixSearchRule.COMMON_PREFIXES.equals(searchRule)) return "COMMON_PREFIXES"; - else if (PrefixSearchRule.ALL_METRIC_PREFIXES.equals(searchRule)) + if (PrefixSearchRule.ALL_METRIC_PREFIXES.equals(searchRule)) return "ALL_METRIC_PREFIXES"; - else - return searchRule.toString(); + return searchRule.toString(); } - + /** * @return true iff a and b have any elements in common * @since 2022-04-19 @@ -240,22 +238,20 @@ public final class Presenter { } return false; } - + private static Path userConfigDir() { if (System.getProperty("os.name").startsWith("Windows")) { final var envFolder = System.getenv("LOCALAPPDATA"); if (envFolder == null || "".equals(envFolder)) return Path.of(System.getenv("USERPROFILE"), "AppData", "Local"); - else - return Path.of(envFolder); + return Path.of(envFolder); } final var envFolder = System.getenv("XDG_CONFIG_HOME"); if (envFolder == null || "".equals(envFolder)) return Path.of(System.getenv("HOME"), ".config"); - else - return Path.of(envFolder); + return Path.of(envFolder); } - + /** * @return {@code line} with any comments removed. * @since 2021-03-13 @@ -265,7 +261,7 @@ public final class Presenter { final var index = line.indexOf('#'); return index == -1 ? line : line.substring(0, index); } - + /** * Wraps a string, ensuring no line is longer than {@code maxLineLength}. * @@ -290,23 +286,21 @@ public final class Presenter { wrapped.append(remaining); return wrapped.toString(); } - - /** - * The view that this presenter communicates with - */ + + /** The view that this presenter communicates with */ private final View view; - + /** * The database that this presenter communicates with (effectively the model) */ final UnitDatabase database; - + /** * The rule used for parsing input numbers. Any number-string inputted into * this program will be parsed using this method. <b>Not implemented yet.</b> */ private Function<String, UncertainDouble> numberParsingRule; - + /** * The rule used for displaying the results of unit conversions. The result * of unit conversions will be put into this function, and the resulting @@ -314,60 +308,60 @@ public final class Presenter { */ private Function<UncertainDouble, String> numberDisplayRule = StandardDisplayRules .uncertaintyBased(); - + /** * A predicate that determines whether or not a certain combination of * prefixes is allowed. If it returns false, a combination of prefixes will * not be allowed. Prefixes are put in the list from right to left. */ private Predicate<List<UnitPrefix>> prefixRepetitionRule = DefaultPrefixRepetitionRule.NO_RESTRICTION; - + /** * A rule that accepts a prefixless name-unit pair and returns a map mapping * names to prefixed versions of that unit (including the unit itself) that * should be searchable. */ private Function<Map.Entry<String, LinearUnit>, Map<String, LinearUnit>> searchRule = PrefixSearchRule.NO_PREFIXES; - + /** * The set of units that is considered neither metric nor nonmetric for the * purposes of the metric-imperial one-way conversion. These units are * included in both From and To, even if One Way Conversion is enabled. */ private final Set<String> metricExceptions; - + /** maps locale names (e.g. 'en') to key-text maps */ final Map<String, Map<String, String>> locales; - + /** name of locale in locales to use */ String userLocale; - + /** * If this is true, views that show units as a list will have metric units * removed from the From unit list and imperial/USC units removed from the To * unit list. */ private boolean oneWayConversionEnabled = false; - + /** * If this is false, duplicate units and prefixes will be removed from the * unit view in views that show units as a list to choose from. */ private boolean showDuplicates = false; - + /** * The default unit, prefix, dimension and exception data will only be loaded * if this variable is true. */ private boolean useDefaultDatafiles = true; - + /** Custom unit datafiles that will be loaded by {@link #reloadData} */ private final Set<Path> customUnitFiles = new HashSet<>(); /** Custom dimension datafiles that will be loaded by {@link #reloadData} */ private final Set<Path> customDimensionFiles = new HashSet<>(); /** Custom exception datafiles that will be loaded by {@link #reloadData} */ private final Set<Path> customExceptionFiles = new HashSet<>(); - + /** * Creates a Presenter * @@ -379,40 +373,40 @@ public final class Presenter { this.view = view; this.database = new UnitDatabase(); this.metricExceptions = new HashSet<>(); - + this.locales = this.loadLocales(); this.userLocale = DEFAULT_LOCALE; - + // set default settings temporarily if (Files.exists(CONFIG_FILE)) { this.loadSettings(CONFIG_FILE); } - + this.reloadData(); - + // print out unit counts System.out.println(this.loadStatMsg()); } - + private void addLocaleFile(Map<String, Map<String, String>> locales, Path file) throws IOException { final Map<String, String> locale = new HashMap<>(); - final String fileName = file.getName(file.getNameCount() - 1).toString(); - final String localeName = fileName.substring(0, fileName.length() - 4); - try (Stream<String> lines = Files.lines(file)) { + final var fileName = file.getName(file.getNameCount() - 1).toString(); + final var localeName = fileName.substring(0, fileName.length() - 4); + try (var lines = Files.lines(file)) { lines.forEach(line -> this.addLocaleLine(locale, line)); } locales.put(localeName, locale); } - + private void addLocaleLine(Map<String, String> locale, String line) { - final String[] parts = line.split("=", 2); + final var parts = line.split("=", 2); if (parts.length < 2) return; - + locale.put(parts[0], parts[1]); } - + /** * Applies a search rule to an entry in a name-unit map. * @@ -433,7 +427,7 @@ public final class Presenter { } return Stream.of(e); } - + /** * Converts from the view's input expression to its output expression. * Displays an error message if any of the required fields are invalid. @@ -450,10 +444,10 @@ public final class Presenter { throw new UnsupportedOperationException( "This function can only be called when the view is an ExpressionConversionView"); final var xcview = (ExpressionConversionView) this.view; - + final var fromExpression = xcview.getFromExpression(); final var toExpression = xcview.getToExpression(); - + // expressions must not be empty if (fromExpression.isEmpty()) { this.view.showErrorMessage("Parse Error", @@ -465,7 +459,7 @@ public final class Presenter { "Please enter a unit expression in the To: box."); return; } - + final Optional<UnitConversionRecord> uc; if (this.database.containsUnitSetName(toExpression)) { uc = this.convertExpressionToNamedMultiUnit(fromExpression, @@ -476,10 +470,10 @@ public final class Presenter { } else { uc = this.convertExpressionToExpression(fromExpression, toExpression); } - + uc.ifPresent(xcview::showExpressionConversionOutput); } - + /** * Converts a unit expression to another expression. * @@ -508,7 +502,7 @@ public final class Presenter { "Could not recognize text in To entry: " + e.getMessage()); return Optional.empty(); } - + // convert and show output if (!from.getUnit().canConvertTo(to)) { this.view.showErrorMessage("Conversion Error", @@ -517,7 +511,7 @@ public final class Presenter { return Optional.empty(); } final UncertainDouble uncertainValue; - + // uncertainty is meaningless for non-linear units, so we will have // to erase uncertainty information for them if (to instanceof LinearUnit) { @@ -527,13 +521,13 @@ public final class Presenter { final var value = from.asUnitValue().convertTo(to).getValue(); uncertainValue = UncertainDouble.of(value, 0); } - + final var uc = UnitConversionRecord.valueOf(fromExpression, toExpression, "", this.numberDisplayRule.apply(uncertainValue)); return Optional.of(uc); - + } - + /** * Convert an expression to a MultiUnit. If an error happened, it is shown to * the view and Optional.empty() is returned. @@ -551,7 +545,7 @@ public final class Presenter { "Could not recognize text in From entry: " + e.getMessage()); return Optional.empty(); } - + final List<LinearUnit> toUnits = new ArrayList<>(toExpressions.length); for (final String toExpression : toExpressions) { try { @@ -570,7 +564,7 @@ public final class Presenter { return Optional.empty(); } } - + final List<LinearUnitValue> toValues; try { toValues = from.convertToMultiple(toUnits); @@ -579,12 +573,12 @@ public final class Presenter { "Invalid units separated by ';': " + e.getMessage()); return Optional.empty(); } - + final var toExpression = this.linearUnitValueSumToString(toValues); return Optional.of( UnitConversionRecord.valueOf(fromExpression, toExpression, "", "")); } - + /** * Convert an expression to a MultiUnit with a name from the database. If an * error happened, it is shown to the view and Optional.empty() is returned. @@ -602,7 +596,7 @@ public final class Presenter { "Could not recognize text in From entry: " + e.getMessage()); return Optional.empty(); } - + final var toUnits = this.database.getUnitSet(toName); final List<LinearUnitValue> toValues; try { @@ -612,12 +606,12 @@ public final class Presenter { "Invalid units separated by ';': " + e.getMessage()); return Optional.empty(); } - + final var toExpression = this.linearUnitValueSumToString(toValues); return Optional.of( UnitConversionRecord.valueOf(fromExpression, toExpression, "", "")); } - + /** * Converts from the view's input unit to its output unit. Displays an error * message if any of the required fields are invalid. @@ -634,36 +628,33 @@ public final class Presenter { throw new UnsupportedOperationException( "This function can only be called when the view is a UnitConversionView."); final var ucview = (UnitConversionView) this.view; - + final var fromUnitOptional = ucview.getFromSelection(); final var toUnitOptional = ucview.getToSelection(); final var inputValueString = ucview.getInputValue(); - + // extract values from optionals final String fromUnitString, toUnitString; - if (fromUnitOptional.isPresent()) { - fromUnitString = fromUnitOptional.orElseThrow(); - } else { + if (!fromUnitOptional.isPresent()) { this.view.showErrorMessage("Unit Selection Error", "Please specify a From unit"); return; } - if (toUnitOptional.isPresent()) { - toUnitString = toUnitOptional.orElseThrow(); - } else { + fromUnitString = fromUnitOptional.orElseThrow(); + if (!toUnitOptional.isPresent()) { this.view.showErrorMessage("Unit Selection Error", "Please specify a To unit"); return; } - + toUnitString = toUnitOptional.orElseThrow(); + // convert strings to data, checking if anything is invalid final Unit fromUnit; final UncertainDouble uncertainValue; - - if (this.database.containsUnitName(fromUnitString)) { - fromUnit = this.database.getUnit(fromUnitString); - } else + + if (!this.database.containsUnitName(fromUnitString)) throw this.viewError("Nonexistent From unit: %s", fromUnitString); + fromUnit = this.database.getUnit(fromUnitString); try { uncertainValue = UncertainDouble.fromRoundedString(inputValueString); } catch (final NumberFormatException e) { @@ -683,7 +674,7 @@ public final class Presenter { } else throw this.viewError("Nonexistent To unit: %s", toUnitString); } - + private UnitConversionRecord convertUnitToMulti(String fromUnitString, String inputValueString, Unit fromUnit, List<LinearUnit> toMulti, UncertainDouble uncertainValue) { @@ -692,7 +683,7 @@ public final class Presenter { throw this.viewError("Could not convert between %s and %s", fromUnit, toUnit); } - + final LinearUnitValue initValue; if (fromUnit instanceof LinearUnit) { final var fromLinear = (LinearUnit) fromUnit; @@ -701,21 +692,21 @@ public final class Presenter { initValue = UnitValue.of(fromUnit, uncertainValue.value()) .convertToBase(NameSymbol.EMPTY); } - + final var converted = initValue.convertToMultiple(toMulti); final var toExpression = this.linearUnitValueSumToString(converted); return UnitConversionRecord.valueOf(fromUnitString, toExpression, inputValueString, ""); - + } - + private UnitConversionRecord convertUnitToUnit(String fromUnitString, String toUnitString, String inputValueString, Unit fromUnit, Unit toUnit, UncertainDouble uncertainValue) { if (!fromUnit.canConvertTo(toUnit)) throw this.viewError("Could not convert between %s and %s", fromUnit, toUnit); - + // convert - we will need to erase uncertainty for non-linear units, so // we need to treat linear and non-linear units differently final String outputValueString; @@ -725,21 +716,21 @@ public final class Presenter { final var initialValue = LinearUnitValue.of(fromLinear, uncertainValue); final var converted = initialValue.convertTo(toLinear); - + outputValueString = this.numberDisplayRule.apply(converted.getValue()); } else { final var initialValue = UnitValue.of(fromUnit, uncertainValue.value()); final var converted = initialValue.convertTo(toUnit); - + outputValueString = this.numberDisplayRule .apply(UncertainDouble.of(converted.getValue(), 0)); } - + return UnitConversionRecord.valueOf(fromUnitString, toUnitString, inputValueString, outputValueString); } - + /** * @return true iff duplicate units are shown in unit lists * @since 2022-03-30 @@ -748,44 +739,44 @@ public final class Presenter { public boolean duplicatesShown() { return this.showDuplicates; } - + private String formatAboutText(Stream<String> rawLines) { return rawLines.map(Presenter::withoutComments) .collect(Collectors.joining("\n")) .replaceAll("\\[VERSION\\]", ProgramInfo.VERSION.toString()) .replaceAll("\\[LOADSTATS\\]", wrapString(this.loadStatMsg(), 72)); } - + /** * @return text in About file * @since 2022-02-19 * @since v0.4.0 */ public String getAboutText() { - final Path customFilepath = Presenter + final var customFilepath = Presenter .pathFromConfig("about/" + this.userLocale + ".txt"); if (Files.exists(customFilepath)) { - try (Stream<String> lines = Files.lines(customFilepath)) { + try (var lines = Files.lines(customFilepath)) { return this.formatAboutText(lines); } catch (final IOException e) { - final String filename = String.format("/about/%s.txt", + final var filename = String.format("/about/%s.txt", this.userLocale); return this.formatAboutText( Presenter.getLinesFromResource(filename).stream()); } - } else if (LOCAL_LOCALES.contains(this.userLocale)) { - final String filename = String.format("/about/%s.txt", + } + if (LOCAL_LOCALES.contains(this.userLocale)) { + final var filename = String.format("/about/%s.txt", this.userLocale); return this.formatAboutText( Presenter.getLinesFromResource(filename).stream()); - } else { - final String filename = String.format("/about/%s.txt", DEFAULT_LOCALE); - return this.formatAboutText( - Presenter.getLinesFromResource(filename).stream()); } - + final var filename = String.format("/about/%s.txt", DEFAULT_LOCALE); + return this + .formatAboutText(Presenter.getLinesFromResource(filename).stream()); + } - + /** * @return set of all locales available to select * @since 2025-02-21 @@ -794,7 +785,7 @@ public final class Presenter { public Set<String> getAvailableLocales() { return this.locales.keySet(); } - + /** * Gets a name for this dimension using the database * @@ -810,7 +801,7 @@ public final class Presenter { .filter(d -> d.equals(dimension)).findAny().map(Nameable::getName) .orElse(dimension.toString(Nameable::getName)); } - + /** * Gets the correct text for a provided ID. If this text is available in the * user's locale, that text is provided. Otherwise, text is taken from the @@ -824,7 +815,7 @@ public final class Presenter { final var defaultLocale = this.locales.get(DEFAULT_LOCALE); return userLocale.getOrDefault(textID, defaultLocale.get(textID)); } - + /** * @return the rule that is used by this presenter to convert numbers into * strings @@ -834,7 +825,7 @@ public final class Presenter { public Function<UncertainDouble, String> getNumberDisplayRule() { return this.numberDisplayRule; } - + /** * @return the rule that is used by this presenter to convert strings into * numbers @@ -845,7 +836,7 @@ public final class Presenter { private Function<String, UncertainDouble> getNumberParsingRule() { return this.numberParsingRule; } - + /** * @return the rule that determines whether a set of prefixes is valid * @since 2022-04-19 @@ -854,7 +845,7 @@ public final class Presenter { public Predicate<List<UnitPrefix>> getPrefixRepetitionRule() { return this.prefixRepetitionRule; } - + /** * @return the rule that determines which units are prefixed * @since 2022-07-08 @@ -863,7 +854,7 @@ public final class Presenter { public Function<Map.Entry<String, LinearUnit>, Map<String, LinearUnit>> getSearchRule() { return this.searchRule; } - + /** * @return a search rule that shows all single prefixes * @since 2022-07-08 @@ -873,7 +864,7 @@ public final class Presenter { return PrefixSearchRule.getCoherentOnlyRule( new HashSet<>(this.database.prefixMap(true).values())); } - + /** * @return user's selected locale * @since 2025-02-21 @@ -882,7 +873,7 @@ public final class Presenter { public String getUserLocale() { return this.userLocale; } - + /** * @return the view associated with this presenter * @since 2022-04-19 @@ -891,7 +882,7 @@ public final class Presenter { public View getView() { return this.view; } - + /** * Accepts a list of errors. If that list is non-empty, prints an error * message and alerts the user. @@ -910,7 +901,7 @@ public final class Presenter { errorMessage); } } - + /** * @return whether or not the provided unit is semi-metric (i.e. an * exception) @@ -927,7 +918,7 @@ public final class Presenter { && this.metricExceptions.contains(symbol.orElseThrow()) || sharesAnyElements(this.metricExceptions, u.getOtherNames()); } - + /** * Convert a list of LinearUnitValues that you would get from a unit-set * conversion to a string. All but the last have their numbers rendered as @@ -945,10 +936,8 @@ public final class Presenter { return integerPart + " + " + this.numberDisplayRule.apply(last.getValue()) + " " + last.getUnit(); } - - /** - * Load units, prefixes and dimensions from the default files. - */ + + /** Load units, prefixes and dimensions from the default files. */ private void loadDefaultData() { // load units and prefixes try (final var units = inputStream(DEFAULT_UNITS_FILEPATH)) { @@ -956,7 +945,7 @@ public final class Presenter { } catch (final IOException e) { throw new AssertionError("Loading of unitsfile.txt failed.", e); } - + // load dimensions try (final var dimensions = inputStream(DEFAULT_DIMENSIONS_FILEPATH)) { this.handleLoadErrors( @@ -964,7 +953,7 @@ public final class Presenter { } catch (final IOException e) { throw new AssertionError("Loading of dimensionfile.txt failed.", e); } - + // load metric exceptions try { try (var exceptions = inputStream(DEFAULT_EXCEPTIONS_FILEPATH); @@ -981,7 +970,7 @@ public final class Presenter { e); } } - + private void loadExceptionFile(Path exceptionFile) { try (var lines = Files.lines(exceptionFile)) { lines.map(Presenter::withoutComments) @@ -992,7 +981,7 @@ public final class Presenter { + exceptionFile + "\": " + e.getLocalizedMessage()); } } - + /** * Loads all available locales, including custom ones, into a map. * @@ -1002,14 +991,14 @@ public final class Presenter { final Map<String, Map<String, String>> locales = new HashMap<>(); for (final String localeName : LOCAL_LOCALES) { final Map<String, String> locale = new HashMap<>(); - final String filename = "/locales/" + localeName + ".txt"; + final var filename = "/locales/" + localeName + ".txt"; getLinesFromResource(filename) .forEach(line -> this.addLocaleLine(locale, line)); locales.put(localeName, locale); } - + if (Files.exists(USER_LOCALES_DIR)) { - try (Stream<Path> files = Files.list(USER_LOCALES_DIR)) { + try (var files = Files.list(USER_LOCALES_DIR)) { files.forEach(localeFile -> { try { this.addLocaleFile(locales, localeFile); @@ -1023,7 +1012,7 @@ public final class Presenter { } return locales; } - + /** * Loads settings from the user's settings file and applies them to the * presenter. @@ -1036,11 +1025,11 @@ public final class Presenter { this.customDimensionFiles.clear(); this.customExceptionFiles.clear(); this.customUnitFiles.clear(); - + for (final Map.Entry<String, String> setting : this .settingsFromFile(settingsFile)) { final var value = setting.getValue(); - + switch (setting.getKey()) { // set manually to avoid the unnecessary saving of the non-manual // methods @@ -1090,12 +1079,12 @@ public final class Presenter { break; } } - + if (this.view.getPresenter() != null) { this.updateView(); } } - + /** * @return a message showing how much stuff has been loaded * @since 2024-08-22 @@ -1120,19 +1109,19 @@ public final class Presenter { .replace("[d]", Integer.toString(this.database.dimensionMap().size())); } - + /** * @return true iff the One-Way Conversion feature is available (views that * show units as a list will have metric units removed from the From * unit list and imperial/USC units removed from the To unit list) - * + * * @since 2022-03-30 * @since v0.4.0 */ public boolean oneWayConversionEnabled() { return this.oneWayConversionEnabled; } - + /** * Completes creation of the presenter. This part of the initialization * depends on the view's functions, so it cannot be run if the components @@ -1147,11 +1136,11 @@ public final class Presenter { final var ucview = (UnitConversionView) this.view; ucview.setDimensionNames(this.database.dimensionMap().keySet()); } - + this.updateView(); this.view.updateText(); } - + void prefixSelected() { final var selectedPrefixName = this.view.getViewedPrefixName(); final Optional<UnitPrefix> selectedPrefix = selectedPrefixName @@ -1162,26 +1151,24 @@ public final class Presenter { .ifPresent(prefix -> this.view.showPrefix(prefix.getNameSymbol(), String.valueOf(prefix.getMultiplier()))); } - - /** - * Clears then reloads all unit, prefix, dimension and exception data. - */ + + /** Clears then reloads all unit, prefix, dimension and exception data. */ public void reloadData() { this.database.clear(); this.metricExceptions.clear(); addDefaults(this.database); - + if (this.useDefaultDatafiles) { this.loadDefaultData(); } - + this.customUnitFiles.forEach( path -> this.handleLoadErrors(this.database.loadUnitsFile(path))); this.customDimensionFiles.forEach(path -> this .handleLoadErrors(this.database.loadDimensionFile(path))); this.customExceptionFiles.forEach(this::loadExceptionFile); } - + /** * Saves the presenter's current settings to the config file, creating it if * it doesn't exist. @@ -1199,10 +1186,10 @@ public final class Presenter { return false; } } - + return this.writeSettings(CONFIG_FILE); } - + private void setDisplayRuleFromString(String ruleString) { final var tokens = ruleString.split(" "); switch (tokens[0]) { @@ -1223,7 +1210,7 @@ public final class Presenter { break; } } - + /** * @param numberDisplayRule the new rule that will be used by this presenter * to convert numbers into strings @@ -1234,7 +1221,7 @@ public final class Presenter { Function<UncertainDouble, String> numberDisplayRule) { this.numberDisplayRule = numberDisplayRule; } - + /** * @param numberParsingRule the new rule that will be used by this presenter * to convert strings into numbers @@ -1246,7 +1233,7 @@ public final class Presenter { Function<String, UncertainDouble> numberParsingRule) { this.numberParsingRule = numberParsingRule; } - + /** * @param oneWayConversionEnabled whether not one-way conversion should be * enabled @@ -1258,7 +1245,7 @@ public final class Presenter { this.oneWayConversionEnabled = oneWayConversionEnabled; this.updateView(); } - + /** * @param prefixRepetitionRule the rule that determines whether a set of * prefixes is valid @@ -1270,7 +1257,7 @@ public final class Presenter { this.prefixRepetitionRule = prefixRepetitionRule; this.database.setPrefixRepetitionRule(prefixRepetitionRule); } - + /** * @param searchRule A rule that accepts a prefixless name-unit pair and * returns a map mapping names to prefixed versions of that @@ -1283,7 +1270,7 @@ public final class Presenter { Function<Map.Entry<String, LinearUnit>, Map<String, LinearUnit>> searchRule) { this.searchRule = searchRule; } - + private void setSearchRuleFromString(String ruleString) { switch (ruleString) { case "NO_PREFIXES": @@ -1301,7 +1288,7 @@ public final class Presenter { ruleString); } } - + /** * @param showDuplicateUnits whether or not duplicate units should be shown * @since 2022-03-30 @@ -1311,7 +1298,7 @@ public final class Presenter { this.showDuplicates = showDuplicateUnits; this.updateView(); } - + private List<Map.Entry<String, String>> settingsFromFile(Path settingsFile) { try (var lines = Files.lines(settingsFile)) { return lines.map(Presenter::withoutComments) @@ -1323,11 +1310,11 @@ public final class Presenter { return null; } } - + /** * Sets whether or not the default datafiles will be loaded. This method * automatically updates the view's units. - * + * * @param useDefaultDatafiles whether or not default datafiles should be * loaded */ @@ -1336,7 +1323,7 @@ public final class Presenter { this.reloadData(); this.updateView(); } - + /** * Sets the user's locale, updating the view. * @@ -1346,7 +1333,7 @@ public final class Presenter { this.userLocale = userLocale; this.view.updateText(); } - + /** * Shows a unit in the unit viewer * @@ -1363,7 +1350,7 @@ public final class Presenter { final var unitType = UnitType.getType(u, this::isSemiMetric); this.view.showUnit(nameSymbol, definition, dimensionString, unitType); } - + /** * Runs whenever a unit name is selected in the unit viewer. Gets the * description of a unit and displays it. @@ -1380,7 +1367,7 @@ public final class Presenter { : null); selectedUnit.ifPresent(this::showUnit); } - + /** * Updates the view's From and To units, if it has some * @@ -1391,20 +1378,20 @@ public final class Presenter { if (this.view instanceof UnitConversionView) { final var ucview = (UnitConversionView) this.view; final var selectedDimensionName = ucview.getSelectedDimensionName(); - + // load units & prefixes into viewers this.view.setViewableUnitNames( this.database.unitMapPrefixless(this.showDuplicates).keySet()); this.view.setViewablePrefixNames( this.database.prefixMap(this.showDuplicates).keySet()); - + // get From and To units var fromUnits = this.database.unitMapPrefixless(this.showDuplicates) .entrySet().stream(); var toUnits = this.database.unitMapPrefixless(this.showDuplicates) .entrySet().stream(); var unitSets = this.database.unitSetMap().entrySet().stream(); - + // filter by dimension, if one is selected if (selectedDimensionName.isPresent()) { final var viewDimension = this.database @@ -1416,7 +1403,7 @@ public final class Presenter { unitSets = unitSets.filter(us -> viewDimension .equals(us.getValue().get(0).getDimension())); } - + // filter by unit type, if desired if (this.oneWayConversionEnabled) { fromUnits = fromUnits.filter(u -> UnitType.getType(u.getValue(), @@ -1427,7 +1414,7 @@ public final class Presenter { unitSets = unitSets .filter(us -> this.metricExceptions.contains(us.getKey())); } - + // set unit names ucview.setFromUnitNames(fromUnits.flatMap(this::applySearchRule) .map(Map.Entry::getKey).collect(Collectors.toSet())); @@ -1439,14 +1426,12 @@ public final class Presenter { ucview.setToUnitNames(toNames); } } - - /** - * @return true iff the default datafiles are being used - */ + + /** @return true iff the default datafiles are being used */ public boolean usingDefaultDatafiles() { return this.useDefaultDatafiles; } - + /** * @param message message to add * @param args string formatting arguments for message @@ -1459,7 +1444,7 @@ public final class Presenter { return new AssertionError("View Programming Error (from " + this.view + "): " + String.format(message, args)); } - + /** * Saves the presenter's settings to the user settings file. * diff --git a/src/main/java/sevenUnitsGUI/SearchBoxList.java b/src/main/java/sevenUnitsGUI/SearchBoxList.java index 43a57ce..bddce04 100644 --- a/src/main/java/sevenUnitsGUI/SearchBoxList.java +++ b/src/main/java/sevenUnitsGUI/SearchBoxList.java @@ -49,7 +49,7 @@ final class SearchBoxList<E> extends JPanel { /** * The text to place in an empty search box. - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -57,7 +57,7 @@ final class SearchBoxList<E> extends JPanel { /** * The color to use for an empty foreground. - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -82,7 +82,7 @@ final class SearchBoxList<E> extends JPanel { /** * Creates an empty SearchBoxList - * + * * @since 2022-02-19 * @since v0.4.0 */ @@ -92,7 +92,7 @@ final class SearchBoxList<E> extends JPanel { /** * Creates the {@code SearchBoxList}. - * + * * @param itemsToFilter items to put in the list * @since 2019-04-14 * @since v0.2.0 @@ -103,12 +103,12 @@ final class SearchBoxList<E> extends JPanel { /** * Creates the {@code SearchBoxList}. - * + * * @param itemsToFilter items to put in the list * @param defaultOrdering default ordering of items after filtration * (null=Comparable) * @param caseSensitive whether or not the filtration is case-sensitive - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -149,7 +149,7 @@ final class SearchBoxList<E> extends JPanel { /** * Adds an additional filter for searching. - * + * * @param filter filter to add. * @since 2019-04-13 * @since v0.2.0 @@ -160,7 +160,7 @@ final class SearchBoxList<E> extends JPanel { /** * Resets the search filter. - * + * * @since 2019-04-13 * @since v0.2.0 */ @@ -183,7 +183,7 @@ final class SearchBoxList<E> extends JPanel { * @since 2019-04-14 * @since v0.2.0 */ - public final JTextField getSearchBox() { + public JTextField getSearchBox() { return this.searchBox; } @@ -197,9 +197,8 @@ final class SearchBoxList<E> extends JPanel { private Predicate<E> getSearchFilter(final String searchText) { if (this.caseSensitive) return item -> item.toString().contains(searchText); - else - return item -> item.toString().toLowerCase() - .contains(searchText.toLowerCase()); + return item -> item.toString().toLowerCase() + .contains(searchText.toLowerCase()); } /** @@ -207,7 +206,7 @@ final class SearchBoxList<E> extends JPanel { * @since 2019-04-14 * @since v0.2.0 */ - public final JList<E> getSearchList() { + public JList<E> getSearchList() { return this.searchItems; } @@ -231,16 +230,16 @@ final class SearchBoxList<E> extends JPanel { /** * Re-applies the filters. - * + * * @since 2019-04-13 * @since v0.2.0 */ public void reapplyFilter() { - final String searchText = this.searchBoxEmpty ? "" + final var searchText = this.searchBoxEmpty ? "" : this.searchBox.getText(); - final FilterComparator<E> comparator = new FilterComparator<>(searchText, + final var comparator = new FilterComparator<E>(searchText, this.defaultOrdering, this.caseSensitive); - final Predicate<E> searchFilter = this.getSearchFilter(searchText); + final var searchFilter = this.getSearchFilter(searchText); this.listModel.clear(); this.itemsToFilter.forEach(item -> { @@ -258,7 +257,7 @@ final class SearchBoxList<E> extends JPanel { /** * Runs whenever the search box gains focus. - * + * * @param e focus event * @since 2019-04-13 * @since v0.2.0 @@ -273,7 +272,7 @@ final class SearchBoxList<E> extends JPanel { /** * Runs whenever the search box loses focus. - * + * * @param e focus event * @since 2019-04-13 * @since v0.2.0 @@ -291,7 +290,7 @@ final class SearchBoxList<E> extends JPanel { * <p> * Reapplies the search filter, and custom filters. * </p> - * + * * @since 2019-04-14 * @since v0.2.0 */ @@ -299,11 +298,11 @@ final class SearchBoxList<E> extends JPanel { if (this.searchBoxFocused) { this.searchBoxEmpty = this.searchBox.getText().equals(""); } - final String searchText = this.searchBoxEmpty ? "" + final var searchText = this.searchBoxEmpty ? "" : this.searchBox.getText(); - final FilterComparator<E> comparator = new FilterComparator<>(searchText, + final var comparator = new FilterComparator<E>(searchText, this.defaultOrdering, this.caseSensitive); - final Predicate<E> searchFilter = this.getSearchFilter(searchText); + final var searchFilter = this.getSearchFilter(searchText); // initialize list with items that match the filter then sort this.listModel.clear(); @@ -336,7 +335,7 @@ final class SearchBoxList<E> extends JPanel { /** * Manually updates the search box's item list. - * + * * @since 2020-08-27 * @since v0.3.0 */ diff --git a/src/main/java/sevenUnitsGUI/StandardDisplayRules.java b/src/main/java/sevenUnitsGUI/StandardDisplayRules.java index d710117..16d31ae 100644 --- a/src/main/java/sevenUnitsGUI/StandardDisplayRules.java +++ b/src/main/java/sevenUnitsGUI/StandardDisplayRules.java @@ -43,9 +43,7 @@ public final class StandardDisplayRules { /** Regular expression used for converting this to a string. */ public static final Pattern TO_STRING_PATTERN = Pattern .compile("Round to (\\d+) decimal places"); - /** - * The number of places to round to. - */ + /** The number of places to round to. */ private final int decimalPlaces; /** @@ -79,7 +77,7 @@ public final class StandardDisplayRules { return true; if (!(obj instanceof FixedDecimals)) return false; - final FixedDecimals other = (FixedDecimals) obj; + final var other = (FixedDecimals) obj; if (this.decimalPlaces != other.decimalPlaces) return false; return true; @@ -108,9 +106,7 @@ public final class StandardDisplayRules { public static final Pattern TO_STRING_PATTERN = Pattern .compile("Round to (\\d+) significant figures"); - /** - * The number of significant figures to round to. - */ + /** The number of significant figures to round to. */ private final MathContext mathContext; /** @@ -135,7 +131,7 @@ public final class StandardDisplayRules { return true; if (!(obj instanceof FixedPrecision)) return false; - final FixedPrecision other = (FixedPrecision) obj; + final var other = (FixedPrecision) obj; if (this.mathContext == null) { if (other.mathContext != null) return false; @@ -202,7 +198,7 @@ public final class StandardDisplayRules { * @since 2022-04-18 * @since v0.4.0 */ - public static final FixedDecimals fixedDecimals(int decimalPlaces) { + public static FixedDecimals fixedDecimals(int decimalPlaces) { return new FixedDecimals(decimalPlaces); } @@ -213,7 +209,7 @@ public final class StandardDisplayRules { * @since 2022-04-18 * @since v0.4.0 */ - public static final FixedPrecision fixedPrecision(int significantFigures) { + public static FixedPrecision fixedPrecision(int significantFigures) { return new FixedPrecision(significantFigures); } @@ -227,7 +223,7 @@ public final class StandardDisplayRules { * @since 2021-12-24 * @since v0.4.0 */ - public static final Function<UncertainDouble, String> getStandardRule( + public static Function<UncertainDouble, String> getStandardRule( String ruleToString) { if (UNCERTAINTY_BASED_ROUNDING_RULE.toString().equals(ruleToString)) return UNCERTAINTY_BASED_ROUNDING_RULE; @@ -236,13 +232,13 @@ public final class StandardDisplayRules { final var placesMatch = FixedDecimals.TO_STRING_PATTERN .matcher(ruleToString); if (placesMatch.matches()) - return new FixedDecimals(Integer.valueOf(placesMatch.group(1))); + return new FixedDecimals(Integer.parseInt(placesMatch.group(1))); // test if it is a fixed-sig-fig rule final var sigFigMatch = FixedPrecision.TO_STRING_PATTERN .matcher(ruleToString); if (sigFigMatch.matches()) - return new FixedPrecision(Integer.valueOf(sigFigMatch.group(1))); + return new FixedPrecision(Integer.parseInt(sigFigMatch.group(1))); throw new IllegalArgumentException( "Provided string does not match any given rules."); @@ -253,7 +249,7 @@ public final class StandardDisplayRules { * @since 2022-04-18 * @since v0.4.0 */ - public static final UncertaintyBased uncertaintyBased() { + public static UncertaintyBased uncertaintyBased() { return UNCERTAINTY_BASED_ROUNDING_RULE; } diff --git a/src/main/java/sevenUnitsGUI/TabbedView.java b/src/main/java/sevenUnitsGUI/TabbedView.java index 1afaf33..8be58f5 100644 --- a/src/main/java/sevenUnitsGUI/TabbedView.java +++ b/src/main/java/sevenUnitsGUI/TabbedView.java @@ -81,7 +81,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { */ private static final class JComboBoxItemSet<E> extends AbstractSet<E> { private final JComboBox<E> comboBox; - + /** * @param comboBox combo box to get items from * @since 2022-02-19 @@ -90,35 +90,34 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { public JComboBoxItemSet(JComboBox<E> comboBox) { this.comboBox = comboBox; } - + @Override public Iterator<E> iterator() { return new Iterator<>() { private int index = 0; - + @Override public boolean hasNext() { return this.index < JComboBoxItemSet.this.size(); } - + @Override public E next() { if (this.hasNext()) return JComboBoxItemSet.this.comboBox.getItemAt(this.index++); - else - throw new NoSuchElementException( - "Iterator has finished iteration"); + throw new NoSuchElementException( + "Iterator has finished iteration"); } }; } - + @Override public int size() { return this.comboBox.getItemCount(); } - + } - + /** * The standard types of rounding, corresponding to the options on the * TabbedView's settings panel. @@ -126,7 +125,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { * @since 2022-04-18 * @since v0.4.0 */ - private static enum StandardRoundingType { + private enum StandardRoundingType { /** * Rounds to a fixed number of significant digits. Precision is used, * representing the number of significant digits to round to. @@ -143,7 +142,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { */ UNCERTAINTY; } - + /** * Creates a TabbedView. * @@ -157,14 +156,14 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { @SuppressWarnings("unused") final View view = new TabbedView(); } - + /** The Presenter that handles this View */ final Presenter presenter; /** The frame that this view lives on */ final JFrame frame; /** The tabbed pane that contains all of the components */ final JTabbedPane masterPane; - + // DIMENSION-BASED CONVERTER /** The combo box that selects dimensions */ final JComboBox<String> dimensionSelector; @@ -178,7 +177,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { final JButton convertUnitButton; /** The output area in the dimension-based converter */ final JTextArea unitOutput; - + // EXPRESSION-BASED CONVERTER /** The "From" entry in the conversion panel */ final JTextField fromEntry; @@ -188,7 +187,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { final JButton convertExpressionButton; /** The output area in the conversion panel */ final JTextArea expressionOutput; - + // UNIT AND PREFIX VIEWERS /** The searchable list of unit names in the unit viewer */ private final SearchBoxList<String> unitNameList; @@ -198,18 +197,18 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { private final JTextArea unitTextBox; /** The text box for prefix data in the prefix viewer */ private final JTextArea prefixTextBox; - + // INFO & SETTINGS STUFF final JTextArea infoTextArea; private final JComboBox<String> localeSelector; private StandardRoundingType roundingType; private int precision; - + private final Map<String, Consumer<String>> localizedTextSetters; - + /** * Creates the view and makes it visible to the user - * + * * @since 2022-02-19 * @since v0.4.0 */ @@ -223,180 +222,183 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { System.err.println("Failed to enable system look-and-feel."); e.printStackTrace(); } - + // initialize important components this.presenter = new Presenter(this); this.frame = new JFrame("7Units (Unlocalized)"); this.frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - + // master components (those that contain everything else within them) this.masterPane = new JTabbedPane(); this.frame.add(this.masterPane); - + this.localizedTextSetters = new HashMap<>(); - + // ============ UNIT CONVERSION TAB ============ - final JPanel convertUnitPanel = new JPanel(); + final var convertUnitPanel = new JPanel(); this.masterPane.addTab("Convert Units", convertUnitPanel); this.localizedTextSetters.put("tv.convert_units.title", txt -> this.masterPane.setTitleAt(0, txt)); this.masterPane.setMnemonicAt(0, KeyEvent.VK_U); convertUnitPanel.setLayout(new BorderLayout()); - + { // panel for input part - final JPanel inputPanel = new JPanel(); + final var inputPanel = new JPanel(); convertUnitPanel.add(inputPanel, BorderLayout.CENTER); inputPanel.setLayout(new GridLayout(1, 3)); inputPanel.setBorder(new EmptyBorder(6, 6, 3, 6)); - + this.fromSearch = new SearchBoxList<>(); inputPanel.add(this.fromSearch); - - final JPanel inBetweenPanel = new JPanel(); + + final var inBetweenPanel = new JPanel(); inputPanel.add(inBetweenPanel); inBetweenPanel.setLayout(new BorderLayout()); - + this.dimensionSelector = new JComboBox<>(); inBetweenPanel.add(this.dimensionSelector, BorderLayout.PAGE_START); this.dimensionSelector .addItemListener(e -> this.presenter.updateView()); - - final JLabel arrowLabel = new JLabel("-->"); + + final var arrowLabel = new JLabel("-->"); inBetweenPanel.add(arrowLabel, BorderLayout.CENTER); arrowLabel.setHorizontalAlignment(SwingConstants.CENTER); - + this.toSearch = new SearchBoxList<>(); inputPanel.add(this.toSearch); } - + { // panel for submit and output, and also value entry - final JPanel outputPanel = new JPanel(); + final var outputPanel = new JPanel(); convertUnitPanel.add(outputPanel, BorderLayout.PAGE_END); outputPanel.setLayout(new BorderLayout()); outputPanel.setBorder(new EmptyBorder(3, 6, 6, 6)); - - final JLabel valuePrompt = new JLabel(); - this.localizedTextSetters.put("tv.convert_units.value_prompt", + + final var valuePrompt = new JLabel(); + this.localizedTextSetters.put("tv.convert_units.value_prompt", valuePrompt::setText); outputPanel.add(valuePrompt, BorderLayout.LINE_START); - + this.valueInput = new JTextField(); outputPanel.add(this.valueInput, BorderLayout.CENTER); - + // conversion button this.convertUnitButton = new JButton("Convert"); - this.localizedTextSetters.put("tv.convert_units.convert_btn", + this.localizedTextSetters.put("tv.convert_units.convert_btn", this.convertUnitButton::setText); outputPanel.add(this.convertUnitButton, BorderLayout.LINE_END); this.convertUnitButton .addActionListener(e -> this.presenter.convertUnits()); this.convertUnitButton.setMnemonic(KeyEvent.VK_ENTER); - + // conversion output this.unitOutput = new JTextArea(2, 32); outputPanel.add(this.unitOutput, BorderLayout.PAGE_END); this.unitOutput.setEditable(false); } - + // ============ EXPRESSION CONVERSION TAB ============ - final JPanel convertExpressionPanel = new JPanel(); + final var convertExpressionPanel = new JPanel(); this.masterPane.addTab("Convert Unit Expressions", convertExpressionPanel); - this.localizedTextSetters.put("tv.convert_expressions.title", + this.localizedTextSetters.put("tv.convert_expressions.title", txt -> this.masterPane.setTitleAt(1, txt)); this.masterPane.setMnemonicAt(1, KeyEvent.VK_E); convertExpressionPanel.setLayout(new GridLayout(4, 1)); - + // from and to expressions this.fromEntry = new JTextField(); convertExpressionPanel.add(this.fromEntry); - this.localizedTextSetters.put("tv.convert_expressions.from", - txt -> this.fromEntry.setBorder(BorderFactory.createTitledBorder(txt))); - + this.localizedTextSetters.put("tv.convert_expressions.from", + txt -> this.fromEntry + .setBorder(BorderFactory.createTitledBorder(txt))); + this.toEntry = new JTextField(); convertExpressionPanel.add(this.toEntry); - this.localizedTextSetters.put("tv.convert_expressions.to", - txt -> this.toEntry.setBorder(BorderFactory.createTitledBorder(txt))); - + this.localizedTextSetters.put("tv.convert_expressions.to", + txt -> this.toEntry + .setBorder(BorderFactory.createTitledBorder(txt))); + // button to convert this.convertExpressionButton = new JButton(); this.localizedTextSetters.put("tv.convert_expressions.convert_btn", this.convertExpressionButton::setText); convertExpressionPanel.add(this.convertExpressionButton); - + this.convertExpressionButton .addActionListener(e -> this.presenter.convertExpressions()); this.convertExpressionButton.setMnemonic(KeyEvent.VK_ENTER); - + // output of conversion this.expressionOutput = new JTextArea(2, 32); convertExpressionPanel.add(this.expressionOutput); - this.localizedTextSetters.put("tv.convert_expressions.output", - txt -> this.expressionOutput.setBorder(BorderFactory.createTitledBorder(txt))); + this.localizedTextSetters.put("tv.convert_expressions.output", + txt -> this.expressionOutput + .setBorder(BorderFactory.createTitledBorder(txt))); this.expressionOutput.setEditable(false); - + // =========== UNIT VIEWER =========== - final JPanel unitLookupPanel = new JPanel(); + final var unitLookupPanel = new JPanel(); this.masterPane.addTab("Unit Viewer", unitLookupPanel); - this.localizedTextSetters.put("tv.unit_viewer.title", + this.localizedTextSetters.put("tv.unit_viewer.title", txt -> this.masterPane.setTitleAt(2, txt)); this.masterPane.setMnemonicAt(2, KeyEvent.VK_V); unitLookupPanel.setLayout(new GridLayout()); - + this.unitNameList = new SearchBoxList<>(); unitLookupPanel.add(this.unitNameList); this.unitNameList.getSearchList() .addListSelectionListener(e -> this.presenter.unitNameSelected()); - + // the text box for unit's toString this.unitTextBox = new JTextArea(); unitLookupPanel.add(this.unitTextBox); this.unitTextBox.setEditable(false); this.unitTextBox.setLineWrap(true); - + // ============ PREFIX VIEWER ============= - final JPanel prefixLookupPanel = new JPanel(); + final var prefixLookupPanel = new JPanel(); this.masterPane.addTab("Prefix Viewer", prefixLookupPanel); - this.localizedTextSetters.put("tv.prefix_viewer.title", + this.localizedTextSetters.put("tv.prefix_viewer.title", txt -> this.masterPane.setTitleAt(3, txt)); this.masterPane.setMnemonicAt(3, KeyEvent.VK_P); prefixLookupPanel.setLayout(new GridLayout(1, 2)); - + this.prefixNameList = new SearchBoxList<>(); prefixLookupPanel.add(this.prefixNameList); this.prefixNameList.getSearchList() .addListSelectionListener(e -> this.presenter.prefixSelected()); - + // the text box for prefix's toString this.prefixTextBox = new JTextArea(); prefixLookupPanel.add(this.prefixTextBox); this.prefixTextBox.setEditable(false); this.prefixTextBox.setLineWrap(true); - + // ============ INFO PANEL ============ - - final JPanel infoPanel = new JPanel(); + + final var infoPanel = new JPanel(); this.masterPane.addTab("\uD83D\uDEC8", // info (i) character new JScrollPane(infoPanel)); - + this.infoTextArea = new JTextArea(); this.infoTextArea.setEditable(false); this.infoTextArea.setOpaque(false); infoPanel.add(this.infoTextArea); - + // ============ SETTINGS PANEL ============ this.localeSelector = new JComboBox<>(); this.masterPane.addTab("\u2699", new JScrollPane(this.createSettingsPanel())); this.masterPane.setMnemonicAt(5, KeyEvent.VK_S); - + // ============ FINALIZE CREATION OF VIEW ============ this.presenter.postViewInitialize(); this.updateText(); this.frame.pack(); this.frame.setVisible(true); } - + /** * Creates and returns the settings panel (in its own function to make this * code more organized, as this function is massive!) @@ -405,64 +407,64 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { * @since v0.4.0 */ private JPanel createSettingsPanel() { - final JPanel settingsPanel = new JPanel(); - + final var settingsPanel = new JPanel(); + settingsPanel .setLayout(new BoxLayout(settingsPanel, BoxLayout.PAGE_AXIS)); - + // ============ ROUNDING SETTINGS ============ { - final JPanel roundingPanel = new JPanel(); + final var roundingPanel = new JPanel(); settingsPanel.add(roundingPanel); - this.localizedTextSetters.put("tv.settings.rounding.title", + this.localizedTextSetters.put("tv.settings.rounding.title", txt -> roundingPanel.setBorder(new TitledBorder(txt))); roundingPanel.setLayout(new GridBagLayout()); - + // rounding rule selection - final ButtonGroup roundingRuleButtons = new ButtonGroup(); + final var roundingRuleButtons = new ButtonGroup(); this.roundingType = this.getPresenterRoundingType() .orElseThrow(() -> new AssertionError( "Presenter loaded non-standard rounding rule")); this.precision = this.getPresenterPrecision().orElse(6); - - final JLabel roundingRuleLabel = new JLabel(); - this.localizedTextSetters.put("tv.settings.rounding.rule", + + final var roundingRuleLabel = new JLabel(); + this.localizedTextSetters.put("tv.settings.rounding.rule", roundingRuleLabel::setText); roundingPanel.add(roundingRuleLabel, new GridBagBuilder(0, 0) .setAnchor(GridBagConstraints.LINE_START).build()); - + // sigDigSlider needs to be first so that the rounding-type buttons can // show and hide it - final JLabel sliderLabel = new JLabel(); - this.localizedTextSetters.put("tv.settings.rounding.precision", + final var sliderLabel = new JLabel(); + this.localizedTextSetters.put("tv.settings.rounding.precision", sliderLabel::setText); sliderLabel.setVisible( this.roundingType != StandardRoundingType.UNCERTAINTY); roundingPanel.add(sliderLabel, new GridBagBuilder(0, 4) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JSlider sigDigSlider = new JSlider(0, 12); + + final var sigDigSlider = new JSlider(0, 12); roundingPanel.add(sigDigSlider, new GridBagBuilder(0, 5) .setAnchor(GridBagConstraints.LINE_START).build()); - + sigDigSlider.setMajorTickSpacing(4); sigDigSlider.setMinorTickSpacing(1); sigDigSlider.setSnapToTicks(true); sigDigSlider.setPaintTicks(true); sigDigSlider.setPaintLabels(true); - + sigDigSlider.setVisible( this.roundingType != StandardRoundingType.UNCERTAINTY); sigDigSlider.setValue(this.precision); - + sigDigSlider.addChangeListener(e -> { this.precision = sigDigSlider.getValue(); this.updatePresenterRoundingRule(); }); - + // significant digit rounding - final JRadioButton fixedPrecision = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.rounding.fixed_sigfig", + final var fixedPrecision = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.rounding.fixed_sigfig", fixedPrecision::setText); if (this.roundingType == StandardRoundingType.SIGNIFICANT_DIGITS) { fixedPrecision.setSelected(true); @@ -476,10 +478,10 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { roundingRuleButtons.add(fixedPrecision); roundingPanel.add(fixedPrecision, new GridBagBuilder(0, 1) .setAnchor(GridBagConstraints.LINE_START).build()); - + // decimal place rounding - final JRadioButton fixedDecimals = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.rounding.fixed_places", + final var fixedDecimals = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.rounding.fixed_places", fixedDecimals::setText); if (this.roundingType == StandardRoundingType.DECIMAL_PLACES) { fixedDecimals.setSelected(true); @@ -493,10 +495,10 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { roundingRuleButtons.add(fixedDecimals); roundingPanel.add(fixedDecimals, new GridBagBuilder(0, 2) .setAnchor(GridBagConstraints.LINE_START).build()); - + // scientific rounding - final JRadioButton relativePrecision = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.rounding.uncertainty", + final var relativePrecision = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.rounding.uncertainty", relativePrecision::setText); if (this.roundingType == StandardRoundingType.UNCERTAINTY) { relativePrecision.setSelected(true); @@ -511,24 +513,24 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { roundingPanel.add(relativePrecision, new GridBagBuilder(0, 3) .setAnchor(GridBagConstraints.LINE_START).build()); } - + // ============ PREFIX REPETITION SETTINGS ============ { - final JPanel prefixRepetitionPanel = new JPanel(); + final var prefixRepetitionPanel = new JPanel(); settingsPanel.add(prefixRepetitionPanel); - this.localizedTextSetters.put("tv.settings.repetition.title", + this.localizedTextSetters.put("tv.settings.repetition.title", txt -> prefixRepetitionPanel.setBorder(new TitledBorder(txt))); prefixRepetitionPanel.setLayout(new GridBagLayout()); - + final var prefixRule = this.getPresenterPrefixRule() .orElseThrow(() -> new AssertionError( "Presenter loaded non-standard prefix rule")); - + // prefix rules - final ButtonGroup prefixRuleButtons = new ButtonGroup(); - - final JRadioButton noRepetition = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.repetition.no", + final var prefixRuleButtons = new ButtonGroup(); + + final var noRepetition = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.repetition.no", noRepetition::setText); if (prefixRule == DefaultPrefixRepetitionRule.NO_REPETITION) { noRepetition.setSelected(true); @@ -541,9 +543,9 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { prefixRuleButtons.add(noRepetition); prefixRepetitionPanel.add(noRepetition, new GridBagBuilder(0, 0) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JRadioButton noRestriction = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.repetition.any", + + final var noRestriction = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.repetition.any", noRestriction::setText); if (prefixRule == DefaultPrefixRepetitionRule.NO_RESTRICTION) { noRestriction.setSelected(true); @@ -556,9 +558,9 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { prefixRuleButtons.add(noRestriction); prefixRepetitionPanel.add(noRestriction, new GridBagBuilder(0, 1) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JRadioButton customRepetition = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.repetition.complex", + + final var customRepetition = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.repetition.complex", customRepetition::setText); if (prefixRule == DefaultPrefixRepetitionRule.COMPLEX_REPETITION) { customRepetition.setSelected(true); @@ -572,22 +574,22 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { prefixRepetitionPanel.add(customRepetition, new GridBagBuilder(0, 2) .setAnchor(GridBagConstraints.LINE_START).build()); } - + // ============ SEARCH SETTINGS ============ { - final JPanel searchingPanel = new JPanel(); + final var searchingPanel = new JPanel(); settingsPanel.add(searchingPanel); - this.localizedTextSetters.put("tv.settings.search.title", + this.localizedTextSetters.put("tv.settings.search.title", txt -> searchingPanel.setBorder(new TitledBorder(txt))); searchingPanel.setLayout(new GridBagLayout()); - + // searching rules - final ButtonGroup searchRuleButtons = new ButtonGroup(); - + final var searchRuleButtons = new ButtonGroup(); + final var searchRule = this.presenter.getSearchRule(); - - final JRadioButton noPrefixes = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.search.no_prefixes", + + final var noPrefixes = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.search.no_prefixes", noPrefixes::setText); noPrefixes.addActionListener(e -> { this.presenter.setSearchRule(PrefixSearchRule.NO_PREFIXES); @@ -597,9 +599,9 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { searchRuleButtons.add(noPrefixes); searchingPanel.add(noPrefixes, new GridBagBuilder(0, 0) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JRadioButton commonPrefixes = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.search.common_prefixes", + + final var commonPrefixes = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.search.common_prefixes", commonPrefixes::setText); commonPrefixes.addActionListener(e -> { this.presenter.setSearchRule(PrefixSearchRule.COMMON_PREFIXES); @@ -609,9 +611,9 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { searchRuleButtons.add(commonPrefixes); searchingPanel.add(commonPrefixes, new GridBagBuilder(0, 1) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JRadioButton alwaysInclude = new JRadioButton(); - this.localizedTextSetters.put("tv.settings.search.all_prefixes", + + final var alwaysInclude = new JRadioButton(); + this.localizedTextSetters.put("tv.settings.search.all_prefixes", alwaysInclude::setText); alwaysInclude.addActionListener(e -> { this.presenter @@ -622,7 +624,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { searchRuleButtons.add(alwaysInclude); searchingPanel.add(alwaysInclude, new GridBagBuilder(0, 3) .setAnchor(GridBagConstraints.LINE_START).build()); - + if (PrefixSearchRule.NO_PREFIXES.equals(searchRule)) { noPrefixes.setSelected(true); } else if (PrefixSearchRule.COMMON_PREFIXES.equals(searchRule)) { @@ -634,14 +636,14 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { this.presenter.saveSettings(); } } - + // ============ OTHER SETTINGS ============ { - final JPanel miscPanel = new JPanel(); + final var miscPanel = new JPanel(); settingsPanel.add(miscPanel); miscPanel.setLayout(new GridBagLayout()); - - final JCheckBox oneWay = new JCheckBox(); + + final var oneWay = new JCheckBox(); this.localizedTextSetters.put("tv.settings.oneway", oneWay::setText); oneWay.setSelected(this.presenter.oneWayConversionEnabled()); oneWay.addItemListener(e -> { @@ -651,9 +653,9 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { }); miscPanel.add(oneWay, new GridBagBuilder(0, 0, 2, 1) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JCheckBox showAllVariations = new JCheckBox(); - this.localizedTextSetters.put("tv.settings.show_duplicate", + + final var showAllVariations = new JCheckBox(); + this.localizedTextSetters.put("tv.settings.show_duplicate", showAllVariations::setText); showAllVariations.setSelected(this.presenter.duplicatesShown()); showAllVariations.addItemListener(e -> { @@ -663,25 +665,25 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { }); miscPanel.add(showAllVariations, new GridBagBuilder(0, 1, 2, 1) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JCheckBox useDefaultFiles = new JCheckBox(); - this.localizedTextSetters.put("tv.settings.use_default_files", + + final var useDefaultFiles = new JCheckBox(); + this.localizedTextSetters.put("tv.settings.use_default_files", useDefaultFiles::setText); useDefaultFiles.setSelected(this.presenter.usingDefaultDatafiles()); useDefaultFiles.addItemListener(e -> { - this.presenter - .setUseDefaultDatafiles(e.getStateChange() == ItemEvent.SELECTED); + this.presenter.setUseDefaultDatafiles( + e.getStateChange() == ItemEvent.SELECTED); this.presenter.saveSettings(); }); miscPanel.add(useDefaultFiles, new GridBagBuilder(0, 2, 2, 1) .setAnchor(GridBagConstraints.LINE_START).build()); - - final JLabel localeLabel = new JLabel(); - this.localizedTextSetters.put("tv.settings.locale", + + final var localeLabel = new JLabel(); + this.localizedTextSetters.put("tv.settings.locale", localeLabel::setText); miscPanel.add(localeLabel, new GridBagBuilder(0, 3, 1, 1) .setAnchor(GridBagConstraints.LINE_START).build()); - + this.presenter.getAvailableLocales().stream().sorted() .forEachOrdered(this.localeSelector::addItem); this.localeSelector.setSelectedItem(this.presenter.getUserLocale()); @@ -691,51 +693,51 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { }); miscPanel.add(localeSelector, new GridBagBuilder(1, 3, 1, 1) .setAnchor(GridBagConstraints.LINE_END).build()); - - final JButton unitFileButton = new JButton(); - this.localizedTextSetters.put("tv.settings.unitfiles.button", + + final var unitFileButton = new JButton(); + this.localizedTextSetters.put("tv.settings.unitfiles.button", unitFileButton::setText); unitFileButton.setEnabled(false); miscPanel.add(unitFileButton, new GridBagBuilder(0, 4, 2, 1) .setAnchor(GridBagConstraints.LINE_START).build()); } - + return settingsPanel; } - + @Override public Set<String> getDimensionNames() { return Collections .unmodifiableSet(new JComboBoxItemSet<>(this.dimensionSelector)); } - + @Override public String getFromExpression() { return this.fromEntry.getText(); } - + @Override public Optional<String> getFromSelection() { return this.fromSearch.getSelectedValue(); } - + @Override public Set<String> getFromUnitNames() { // this should work because the only way I can mutate the item list is // with setFromUnits which only accepts a Set return new HashSet<>(this.fromSearch.getItems()); } - + @Override public String getInputValue() { return this.valueInput.getText(); } - + @Override public Presenter getPresenter() { return this.presenter; } - + /** * @return the precision of the presenter's rounding rule, if that is * meaningful @@ -748,14 +750,13 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { return OptionalInt .of(((StandardDisplayRules.FixedDecimals) presenterRule) .decimalPlaces()); - else if (presenterRule instanceof StandardDisplayRules.FixedPrecision) + if (presenterRule instanceof StandardDisplayRules.FixedPrecision) return OptionalInt .of(((StandardDisplayRules.FixedPrecision) presenterRule) .significantFigures()); - else - return OptionalInt.empty(); + return OptionalInt.empty(); } - + /** * @return presenter's prefix repetition rule * @since 2022-04-19 @@ -767,7 +768,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { ? Optional.of((DefaultPrefixRepetitionRule) prefixRule) : Optional.empty(); } - + /** * Determines which rounding type the presenter is currently using, if any. * @@ -779,48 +780,47 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { if (Objects.equals(presenterRule, StandardDisplayRules.uncertaintyBased())) return Optional.of(StandardRoundingType.UNCERTAINTY); - else if (presenterRule instanceof StandardDisplayRules.FixedDecimals) + if (presenterRule instanceof StandardDisplayRules.FixedDecimals) return Optional.of(StandardRoundingType.DECIMAL_PLACES); - else if (presenterRule instanceof StandardDisplayRules.FixedPrecision) + if (presenterRule instanceof StandardDisplayRules.FixedPrecision) return Optional.of(StandardRoundingType.SIGNIFICANT_DIGITS); - else - return Optional.empty(); + return Optional.empty(); } - + @Override public Optional<String> getSelectedDimensionName() { - final String selectedItem = (String) this.dimensionSelector + final var selectedItem = (String) this.dimensionSelector .getSelectedItem(); return Optional.ofNullable(selectedItem); } - + @Override public String getToExpression() { return this.toEntry.getText(); } - + @Override public Optional<String> getToSelection() { return this.toSearch.getSelectedValue(); } - + @Override public Set<String> getToUnitNames() { // this should work because the only way I can mutate the item list is // with setToUnits which only accepts a Set return new HashSet<>(this.toSearch.getItems()); } - + @Override public Optional<String> getViewedPrefixName() { return this.prefixNameList.getSelectedValue(); } - + @Override public Optional<String> getViewedUnitName() { return this.unitNameList.getSelectedValue(); } - + @Override public void setDimensionNames(Set<String> dimensionNames) { this.dimensionSelector.removeAllItems(); @@ -828,44 +828,44 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { this.dimensionSelector.addItem(d); } } - + @Override public void setFromUnitNames(Set<String> units) { this.fromSearch.setItems(units); } - + @Override public void setToUnitNames(Set<String> units) { this.toSearch.setItems(units); } - + @Override public void setViewablePrefixNames(Set<String> prefixNames) { this.prefixNameList.setItems(prefixNames); } - + @Override public void setViewableUnitNames(Set<String> unitNames) { this.unitNameList.setItems(unitNames); } - + @Override public void showErrorMessage(String title, String message) { JOptionPane.showMessageDialog(this.frame, message, title, JOptionPane.ERROR_MESSAGE); } - + @Override public void showExpressionConversionOutput(UnitConversionRecord uc) { this.expressionOutput.setText(uc.toString()); } - + @Override public void showPrefix(NameSymbol name, String multiplierString) { this.prefixTextBox.setText( String.format("%s%nMultiplier: %s", name, multiplierString)); } - + @Override public void showUnit(NameSymbol name, String definition, String dimensionName, UnitType type) { @@ -873,16 +873,16 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { String.format("%s%nDefinition: %s%nDimension: %s%nType: %s", name, definition, dimensionName, type)); } - + @Override public void showUnitConversionOutput(UnitConversionRecord uc) { this.unitOutput.setText(uc.toString()); } - + /** * Sets the presenter's rounding rule to the one specified by the current * settings - * + * * @since 2022-04-18 * @since v0.4.0 */ @@ -910,7 +910,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { this.frame.setTitle(this.presenter.getLocalizedText("tv.title") .replace("[v]", ProgramInfo.VERSION.toString())); this.infoTextArea.setText(this.presenter.getAboutText()); - this.localizedTextSetters.forEach((id, action) -> - action.accept(this.presenter.getLocalizedText(id))); + this.localizedTextSetters.forEach( + (id, action) -> action.accept(this.presenter.getLocalizedText(id))); } } diff --git a/src/main/java/sevenUnitsGUI/UnitConversionRecord.java b/src/main/java/sevenUnitsGUI/UnitConversionRecord.java index 958deae..3c2bb6c 100644 --- a/src/main/java/sevenUnitsGUI/UnitConversionRecord.java +++ b/src/main/java/sevenUnitsGUI/UnitConversionRecord.java @@ -44,7 +44,7 @@ public final class UnitConversionRecord { input.getValue().toString(false, RoundingMode.HALF_EVEN), output.getValue().toString(false, RoundingMode.HALF_EVEN)); } - + /** * Gets a {@code UnitConversionRecord} from two unit values * @@ -60,7 +60,7 @@ public final class UnitConversionRecord { output.getUnit().getName(), String.valueOf(input.getValue()), String.valueOf(output.getValue())); } - + /** * Gets a {@code UnitConversionRecord} * @@ -78,16 +78,12 @@ public final class UnitConversionRecord { return new UnitConversionRecord(fromName, toName, inputValueString, outputValueString); } - - /** - * The name of the unit or expression that was converted from - */ + + /** The name of the unit or expression that was converted from */ private final String fromName; - /** - * The name of the unit or expression that was converted to - */ + /** The name of the unit or expression that was converted to */ private final String toName; - + /** * A string representing the input value. It doesn't need to be the same as * the input value's string representation; it could be rounded, for example. @@ -98,7 +94,7 @@ public final class UnitConversionRecord { * the input value's string representation; it could be rounded, for example. */ private final String outputValueString; - + /** * @param fromName name of unit or expression that was converted * from @@ -115,14 +111,14 @@ public final class UnitConversionRecord { this.inputValueString = inputValueString; this.outputValueString = outputValueString; } - + @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof UnitConversionRecord)) return false; - final UnitConversionRecord other = (UnitConversionRecord) obj; + final var other = (UnitConversionRecord) obj; if (this.fromName == null) { if (other.fromName != null) return false; @@ -145,7 +141,7 @@ public final class UnitConversionRecord { return false; return true; } - + /** * @return name of unit or expression that was converted from * @since 2022-04-09 @@ -154,11 +150,11 @@ public final class UnitConversionRecord { public String fromName() { return this.fromName; } - + @Override public int hashCode() { - final int prime = 31; - int result = 1; + final var prime = 31; + var result = 1; result = prime * result + (this.fromName == null ? 0 : this.fromName.hashCode()); result = prime * result + (this.inputValueString == null ? 0 @@ -169,7 +165,7 @@ public final class UnitConversionRecord { + (this.toName == null ? 0 : this.toName.hashCode()); return result; } - + /** * @return string representing input value * @since 2022-04-09 @@ -178,7 +174,7 @@ public final class UnitConversionRecord { public String inputValueString() { return this.inputValueString; } - + /** * @return string representing output value * @since 2022-04-09 @@ -187,7 +183,7 @@ public final class UnitConversionRecord { public String outputValueString() { return this.outputValueString; } - + /** * @return name of unit or expression that was converted to * @since 2022-04-09 @@ -196,12 +192,12 @@ public final class UnitConversionRecord { public String toName() { return this.toName; } - + @Override public String toString() { - final String inputString = this.inputValueString.isBlank() ? this.fromName + final var inputString = this.inputValueString.isBlank() ? this.fromName : this.inputValueString + " " + this.fromName; - final String outputString = this.outputValueString.isBlank() ? this.toName + final var outputString = this.outputValueString.isBlank() ? this.toName : this.outputValueString + " " + this.toName; return inputString + " = " + outputString; } diff --git a/src/main/java/sevenUnitsGUI/UnitConversionView.java b/src/main/java/sevenUnitsGUI/UnitConversionView.java index c7ffda4..fa3a388 100644 --- a/src/main/java/sevenUnitsGUI/UnitConversionView.java +++ b/src/main/java/sevenUnitsGUI/UnitConversionView.java @@ -21,7 +21,7 @@ import java.util.Set; /** * A View that supports single unit-based conversion - * + * * @author Adrien Hopkins * @since 2021-12-15 * @since v0.4.0 @@ -110,7 +110,7 @@ public interface UnitConversionView extends View { /** * Shows the output of a unit conversion. - * + * * @param uc record of unit conversion * @since 2021-12-24 * @since v0.4.0 diff --git a/src/main/java/sevenUnitsGUI/View.java b/src/main/java/sevenUnitsGUI/View.java index fc04593..0adeb3a 100644 --- a/src/main/java/sevenUnitsGUI/View.java +++ b/src/main/java/sevenUnitsGUI/View.java @@ -24,7 +24,7 @@ import sevenUnits.utils.NameSymbol; /** * An object that controls user interaction with 7Units - * + * * @author Adrien Hopkins * @since 2021-12-15 * @since v0.4.0 @@ -112,10 +112,10 @@ public interface View { */ void showUnit(NameSymbol name, String definition, String dimensionName, UnitType type); - + /** * Updates the view's text to reflect the presenter's locale. - * + * * This method <b>must not</b> call {@link Presenter#setUserLocale(String)}. */ void updateText(); diff --git a/src/main/java/sevenUnitsGUI/ViewBot.java b/src/main/java/sevenUnitsGUI/ViewBot.java index 689b460..750e2d9 100644 --- a/src/main/java/sevenUnitsGUI/ViewBot.java +++ b/src/main/java/sevenUnitsGUI/ViewBot.java @@ -30,7 +30,7 @@ import sevenUnits.utils.Nameable; /** * A class that simulates a View (supports both unit and expression conversion) * for testing. Getters and setters work as expected. - * + * * @author Adrien Hopkins * @since 2022-01-29 * @since v0.4.0 @@ -66,7 +66,7 @@ public final class ViewBot return true; if (!(obj instanceof PrefixViewingRecord)) return false; - final PrefixViewingRecord other = (PrefixViewingRecord) obj; + final var other = (PrefixViewingRecord) obj; return Objects.equals(this.multiplierString, other.multiplierString) && Objects.equals(this.nameSymbol, other.nameSymbol); } @@ -93,7 +93,7 @@ public final class ViewBot @Override public String toString() { - final StringBuilder builder = new StringBuilder(); + final var builder = new StringBuilder(); builder.append("PrefixViewingRecord [nameSymbol="); builder.append(this.nameSymbol); builder.append(", multiplierString="); @@ -156,7 +156,7 @@ public final class ViewBot return true; if (!(obj instanceof UnitViewingRecord)) return false; - final UnitViewingRecord other = (UnitViewingRecord) obj; + final var other = (UnitViewingRecord) obj; return Objects.equals(this.definition, other.definition) && Objects.equals(this.dimensionName, other.dimensionName) && Objects.equals(this.nameSymbol, other.nameSymbol) @@ -186,7 +186,7 @@ public final class ViewBot @Override public String toString() { - final StringBuilder builder = new StringBuilder(); + final var builder = new StringBuilder(); builder.append("UnitViewingRecord [nameSymbol="); builder.append(this.nameSymbol); builder.append(", definition="); @@ -424,6 +424,7 @@ public final class ViewBot /** * Sets the view's selected dimension + * * @param selectedDimensionName name of dimension to select (string) */ public void setSelectedDimensionName(String selectedDimensionName) { @@ -453,9 +454,7 @@ public final class ViewBot "toSelection cannot be null."); } - /** - * @param toSelection unit set in the 'To' selection - */ + /** @param toSelection unit set in the 'To' selection */ public void setToSelection(String toSelection) { this.setToSelection(Optional.of(toSelection)); } @@ -475,9 +474,7 @@ public final class ViewBot // do nothing, ViewBot supports selecting any unit } - /** - * @param viewedPrefixName name of prefix being used - */ + /** @param viewedPrefixName name of prefix being used */ public void setViewedPrefixName(Optional<String> viewedPrefixName) { this.prefixViewerSelection = viewedPrefixName; } @@ -490,9 +487,7 @@ public final class ViewBot this.setViewedPrefixName(Optional.of(viewedPrefixName)); } - /** - * @param viewedUnitName name of unit being used - */ + /** @param viewedUnitName name of unit being used */ public void setViewedUnitName(Optional<String> viewedUnitName) { this.unitViewerSelection = viewedUnitName; } diff --git a/src/main/java/sevenUnitsGUI/package-info.java b/src/main/java/sevenUnitsGUI/package-info.java index 74ec18c..9432960 100644 --- a/src/main/java/sevenUnitsGUI/package-info.java +++ b/src/main/java/sevenUnitsGUI/package-info.java @@ -16,7 +16,7 @@ */ /** * The MVP GUI of SevenUnits - * + * * @author Adrien Hopkins * @since 2021-12-15 * @since v0.4.0 diff --git a/src/test/java/sevenUnits/unit/UnitDatabaseTest.java b/src/test/java/sevenUnits/unit/UnitDatabaseTest.java index 800d13d..3d6d663 100644 --- a/src/test/java/sevenUnits/unit/UnitDatabaseTest.java +++ b/src/test/java/sevenUnits/unit/UnitDatabaseTest.java @@ -58,7 +58,6 @@ class UnitDatabaseTest { private V value; /** - * * @since 2021-10-07 * @since v0.3.2 */ @@ -190,7 +189,7 @@ class UnitDatabaseTest { } private static final Stream<Arguments> testEvaluateExpressionValid() { - UncertainDouble uncertainTwoThirds = UncertainDouble.of(2.0, 1.0) + final var uncertainTwoThirds = UncertainDouble.of(2.0, 1.0) .dividedBy(UncertainDouble.of(3.0, 1.0)); return Stream.of( Arguments.of("J + (2 * 3) J + (20 / 4) J", @@ -206,19 +205,14 @@ class UnitDatabaseTest { Arguments.of("2 J / 3 J", LinearUnitValue.of(J.dividedBy(J), uncertainTwoThirds))); } - + private static final Stream<Arguments> testFormatExpression() { - return Stream.of( - Arguments.of("1*2", "1 * 2"), - Arguments.of("1/2", "1 / 2"), - Arguments.of("1|2", "1 | 2"), - Arguments.of("1^2", "1 ^ 2"), - Arguments.of("1 * 2", "1 * 2"), - Arguments.of("+1", "+1"), - Arguments.of("-1", "-1"), + return Stream.of(Arguments.of("1*2", "1 * 2"), + Arguments.of("1/2", "1 / 2"), Arguments.of("1|2", "1 | 2"), + Arguments.of("1^2", "1 ^ 2"), Arguments.of("1 * 2", "1 * 2"), + Arguments.of("+1", "+1"), Arguments.of("-1", "-1"), Arguments.of("1.1e+5", "1.1e+5"), - Arguments.of("1.25e-5", "1.25e-5") - ); + Arguments.of("1.25e-5", "1.25e-5")); } /** @@ -266,15 +260,14 @@ class UnitDatabaseTest { database.addPrefix("B", B); database.addPrefix("C", C); - final var actual = database - .evaluateUnitExpression(expression); + final var actual = database.evaluateUnitExpression(expression); assertEquals(expected, actual); final var expectedU = expected.getUnit().times(expected.getValueExact()); final var actualU = database.getUnitFromExpression(expression); assertEquals(expectedU, actualU); } - + @ParameterizedTest @MethodSource public void testFormatExpression(String expression, String expected) { @@ -335,8 +328,7 @@ class UnitDatabaseTest { infiniteDatabase.addPrefix("B", B); infiniteDatabase.addPrefix("C", C); - final var entrySet = infiniteDatabase.unitMap() - .entrySet(); + final var entrySet = infiniteDatabase.unitMap().entrySet(); final var keySet = infiniteDatabase.unitMap().keySet(); assertThrows(IllegalStateException.class, () -> entrySet.toArray()); assertThrows(IllegalStateException.class, () -> keySet.toArray()); @@ -376,8 +368,7 @@ class UnitDatabaseTest { @ValueSource(ints = { 1, 2, 3, 4, 5 }) public void testLoadingInvalidUnitFile(int num) { final var database = new UnitDatabase(); - final var filename = String.format("/test-unitsfile-invalid%d.txt", - num); + final var filename = String.format("/test-unitsfile-invalid%d.txt", num); final var errs = loadUnitsFile(database, filename); assertFalse(errs.isEmpty(), "no error from invalid file " + filename); final var e = errs.get(0).problem(); @@ -418,7 +409,7 @@ class UnitDatabaseTest { assertEquals(7, database.getPrefix("A").getMultiplier()); assertEquals(11, database.getPrefix("B").getMultiplier()); assertEquals(13, database.getPrefix("C").getMultiplier()); - + // test invalid prefixes assertThrows(NoSuchElementException.class, () -> database.getPrefix("N/A")); @@ -487,8 +478,7 @@ class UnitDatabaseTest { final var map1 = database1.unitMap(); final var keyIterator1 = map1.keySet().iterator(); - final var entryIterator1 = map1.entrySet() - .iterator(); + final var entryIterator1 = map1.entrySet().iterator(); final Set<String> expectedKeys = Set.of("U", "V", "W"); final Set<String> actualKeys = new HashSet<>(); @@ -552,8 +542,7 @@ class UnitDatabaseTest { @Test public void testPrefixlessUnitMap() { final var database = new UnitDatabase(); - final var prefixlessUnits = database - .unitMapPrefixless(true); + final var prefixlessUnits = database.unitMapPrefixless(true); database.addUnit("U", U); database.addUnit("V", V); @@ -690,10 +679,8 @@ class UnitDatabaseTest { final var NUM_UNITS = database.unitMapPrefixless(true).size(); final var NUM_PREFIXES = database.prefixMap(true).size(); - final var nameIterator = database.unitMap().keySet() - .iterator(); - final var entryIterator = database.unitMap() - .entrySet().iterator(); + final var nameIterator = database.unitMap().keySet().iterator(); + final var entryIterator = database.unitMap().entrySet().iterator(); var expectedLength = 1; var unitsWithThisLengthSoFar = 0; diff --git a/src/test/java/sevenUnits/unit/UnitTest.java b/src/test/java/sevenUnits/unit/UnitTest.java index 4d9a103..7ae550f 100644 --- a/src/test/java/sevenUnits/unit/UnitTest.java +++ b/src/test/java/sevenUnits/unit/UnitTest.java @@ -32,7 +32,7 @@ import sevenUnits.utils.NameSymbol; /** * Testing the various Unit classes. This is NOT part of this program's public * API. - * + * * @author Adrien Hopkins * @since 2018-12-22 * @since v0.1.0 @@ -40,119 +40,121 @@ import sevenUnits.utils.NameSymbol; class UnitTest { /** A random number generator */ private static final Random rng = ThreadLocalRandom.current(); - + @Test public void testAdditionAndSubtraction() { - final LinearUnit inch = Metric.METRE.times(0.0254) + final var inch = Metric.METRE.times(0.0254) .withName(NameSymbol.of("inch", "in")); - final LinearUnit foot = Metric.METRE.times(0.3048) + final var foot = Metric.METRE.times(0.3048) .withName(NameSymbol.of("foot", "ft")); - - assertTrue(inch.plus(foot).equalsApproximately(Metric.METRE.times(0.3302)), - String.format("Expected: %s, Actual: %s", - inch.plus(foot), Metric.METRE.times(0.3302))); - assertTrue(foot.minus(inch).equalsApproximately(Metric.METRE.times(0.2794)), - String.format("Expected: %s, Actual: %s", - foot.minus(inch), Metric.METRE.times(0.2794))); - + + assertTrue( + inch.plus(foot).equalsApproximately(Metric.METRE.times(0.3302)), + String.format("Expected: %s, Actual: %s", inch.plus(foot), + Metric.METRE.times(0.3302))); + assertTrue( + foot.minus(inch).equalsApproximately(Metric.METRE.times(0.2794)), + String.format("Expected: %s, Actual: %s", foot.minus(inch), + Metric.METRE.times(0.2794))); + // test with LinearUnitValue - final LinearUnitValue value1 = LinearUnitValue.getExact(Metric.METRE, 15); - final LinearUnitValue value2 = LinearUnitValue.getExact(foot, 120); - final LinearUnitValue value3 = LinearUnitValue.getExact(Metric.METRE, + final var value1 = LinearUnitValue.getExact(Metric.METRE, 15); + final var value2 = LinearUnitValue.getExact(foot, 120); + final var value3 = LinearUnitValue.getExact(Metric.METRE, 0.5); - final LinearUnitValue value4 = LinearUnitValue.getExact(Metric.KILOGRAM, + final var value4 = LinearUnitValue.getExact(Metric.KILOGRAM, 60); - + // make sure addition is done correctly assertEquals(51.576, value1.plus(value2).getValueExact(), 0.001); assertEquals(15.5, value1.plus(value3).getValueExact()); assertEquals(52.076, value1.plus(value2).plus(value3).getValueExact(), 0.001); - + // make sure addition uses the correct unit, and is still associative // (ignoring floating-point rounding errors) assertEquals(Metric.METRE, value1.plus(value2).getUnit()); assertEquals(Metric.METRE, value1.plus(value2).plus(value3).getUnit()); assertEquals(foot, value2.plus(value1).getUnit()); assertTrue(value1.plus(value2).equals(value2.plus(value1), true)); - + // make sure errors happen when they should assertThrows(IllegalArgumentException.class, () -> value1.plus(value4)); assertThrows(IllegalArgumentException.class, () -> value1.minus(value4)); } - + @Test public void testConversion() { - final LinearUnit metre = Metric.METRE; + final var metre = Metric.METRE; final Unit inch = metre.times(0.0254); - - final UnitValue value = UnitValue.of(inch, 75); - + + final var value = UnitValue.of(inch, 75); + assertEquals(1.9, inch.convertTo(metre, 75), 0.01); assertEquals(1.9, value.convertTo(metre).getValue(), 0.01); - + // try random stuff - for (int i = 0; i < 1000; i++) { + for (var i = 0; i < 1000; i++) { // initiate random values - final double conversionFactor = UnitTest.rng.nextDouble() * 1000000; - final double testValue = UnitTest.rng.nextDouble() * 1000000; - final double expected = testValue * conversionFactor; - + final var conversionFactor = UnitTest.rng.nextDouble() * 1000000; + final var testValue = UnitTest.rng.nextDouble() * 1000000; + final var expected = testValue * conversionFactor; + // test final Unit unit = Metric.METRE.times(conversionFactor); - final double actual = unit.convertToBase(testValue); - + final var actual = unit.convertToBase(testValue); + assertEquals(actual, expected, expected * DecimalComparison.DOUBLE_EPSILON); } } - + @Test public void testEquals() { - final LinearUnit metre = Metric.METRE; + final var metre = Metric.METRE; final Unit meter = Metric.BaseUnits.METRE.asLinearUnit(); - + assertEquals(metre, meter); } - + @Test public void testIsMetric() { final Unit metre = Metric.METRE; final Unit megasecond = Metric.SECOND.withPrefix(Metric.MEGA); final Unit hour = Metric.HOUR; - + assertTrue(metre.isMetric()); assertTrue(megasecond.isMetric()); assertFalse(hour.isMetric()); } - + @Test public void testMultiplicationAndDivision() { // test unit-times-unit multiplication - final LinearUnit generatedJoule = Metric.KILOGRAM + final var generatedJoule = Metric.KILOGRAM .times(Metric.METRE.toExponent(2)) .dividedBy(Metric.SECOND.toExponent(2)); - final LinearUnit actualJoule = Metric.JOULE; - + final var actualJoule = Metric.JOULE; + assertEquals(generatedJoule, actualJoule); - + // test multiplication by conversion factors - final LinearUnit kilometre = Metric.METRE.times(1000); - final LinearUnit hour = Metric.SECOND.times(3600); - final LinearUnit generatedKPH = kilometre.dividedBy(hour); - - final LinearUnit actualKPH = Metric.METRE.dividedBy(Metric.SECOND) + final var kilometre = Metric.METRE.times(1000); + final var hour = Metric.SECOND.times(3600); + final var generatedKPH = kilometre.dividedBy(hour); + + final var actualKPH = Metric.METRE.dividedBy(Metric.SECOND) .dividedBy(3.6); - + assertEquals(generatedKPH, actualKPH); } - + @Test public void testPrefixes() { - final LinearUnit generatedKilometre = Metric.METRE + final var generatedKilometre = Metric.METRE .withPrefix(Metric.KILO); - final LinearUnit actualKilometre = Metric.METRE.times(1000); - + final var actualKilometre = Metric.METRE.times(1000); + assertEquals(generatedKilometre, actualKilometre); } } diff --git a/src/test/java/sevenUnits/unit/UnitValueTest.java b/src/test/java/sevenUnits/unit/UnitValueTest.java index 6182b20..3679703 100644 --- a/src/test/java/sevenUnits/unit/UnitValueTest.java +++ b/src/test/java/sevenUnits/unit/UnitValueTest.java @@ -36,7 +36,7 @@ import sevenUnits.utils.UncertainDouble; /** * Tests for the UnitValue and LinearUnitValue classes - * + * * @since v1.0.0 */ public final class UnitValueTest { diff --git a/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java b/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java index ea96574..f203fad 100644 --- a/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java +++ b/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java @@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -38,7 +37,7 @@ import sevenUnits.utils.ConditionalExistenceCollections.ConditionalExistenceIter * normal operations on conditional existence collections and ensures that * elements that do not pass the existence condition are not included in the * results. - * + * * @author Adrien Hopkins * @since 2019-10-16 * @since v0.3.0 @@ -47,22 +46,22 @@ class ConditionalExistenceCollectionsTest { /** * The returned iterator ignores elements that don't start with "a". - * + * * @return test iterator * @since 2019-10-17 * @since v0.3.0 */ ConditionalExistenceIterator<String> getTestIterator() { final List<String> items = Arrays.asList("aa", "ab", "ba"); - final Iterator<String> it = items.iterator(); - final ConditionalExistenceIterator<String> cit = (ConditionalExistenceIterator<String>) ConditionalExistenceCollections + final var it = items.iterator(); + final var cit = (ConditionalExistenceIterator<String>) ConditionalExistenceCollections .conditionalExistenceIterator(it, s -> s.startsWith("a")); return cit; } /** * The returned map ignores mappings where the value is zero. - * + * * @return map to be used for test data * @since 2019-10-16 * @since v0.3.0 @@ -79,59 +78,49 @@ class ConditionalExistenceCollectionsTest { return conditionalMap; } - /** - * Test method for the ConditionalExistenceMap's containsKey method. - */ + /** Test method for the ConditionalExistenceMap's containsKey method. */ @Test void testContainsKeyObject() { - final Map<String, Integer> map = this.getTestMap(); + final var map = this.getTestMap(); assertTrue(map.containsKey("one")); assertTrue(map.containsKey("ten")); assertFalse(map.containsKey("five")); assertFalse(map.containsKey("zero")); } - /** - * Test method for the ConditionalExistenceMap's containsValue method. - */ + /** Test method for the ConditionalExistenceMap's containsValue method. */ @Test void testContainsValueObject() { - final Map<String, Integer> map = this.getTestMap(); + final var map = this.getTestMap(); assertTrue(map.containsValue(1)); assertTrue(map.containsValue(10)); assertFalse(map.containsValue(5)); assertFalse(map.containsValue(0)); } - /** - * Test method for the ConditionalExistenceMap's entrySet method. - */ + /** Test method for the ConditionalExistenceMap's entrySet method. */ @Test void testEntrySet() { - final Map<String, Integer> map = this.getTestMap(); + final var map = this.getTestMap(); for (final Entry<String, Integer> e : map.entrySet()) { assertTrue(e.getValue() != 0); } } - /** - * Test method for the ConditionalExistenceMap's get method. - */ + /** Test method for the ConditionalExistenceMap's get method. */ @Test void testGetObject() { - final Map<String, Integer> map = this.getTestMap(); + final var map = this.getTestMap(); assertEquals(1, map.get("one")); assertEquals(10, map.get("ten")); assertEquals(null, map.get("five")); assertEquals(null, map.get("zero")); } - /** - * Test method for the ConditionalExistenceCollection's iterator. - */ + /** Test method for the ConditionalExistenceCollection's iterator. */ @Test void testIterator() { - final ConditionalExistenceIterator<String> testIterator = this + final var testIterator = this .getTestIterator(); assertTrue(testIterator.hasNext); @@ -150,22 +139,18 @@ class ConditionalExistenceCollectionsTest { assertThrows(NoSuchElementException.class, testIterator::next); } - /** - * Test method for the ConditionalExistenceMap's keySet operation. - */ + /** Test method for the ConditionalExistenceMap's keySet operation. */ @Test void testKeySet() { - final Map<String, Integer> map = this.getTestMap(); - assertFalse(map.keySet().contains("zero")); + final var map = this.getTestMap(); + assertFalse(map.containsKey("zero")); } - /** - * Test method for the ConditionalExistenceMap's values operation. - */ + /** Test method for the ConditionalExistenceMap's values operation. */ @Test void testValues() { - final Map<String, Integer> map = this.getTestMap(); - assertFalse(map.values().contains(0)); + final var map = this.getTestMap(); + assertFalse(map.containsValue(0)); } } diff --git a/src/test/java/sevenUnits/utils/ExpressionParserTest.java b/src/test/java/sevenUnits/utils/ExpressionParserTest.java index 72d3b19..2e0b4b0 100644 --- a/src/test/java/sevenUnits/utils/ExpressionParserTest.java +++ b/src/test/java/sevenUnits/utils/ExpressionParserTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.params.provider.MethodSource; /** * A test for the {@code ExpressionParser} class. This is NOT part of this * program's public API. - * + * * @author Adrien Hopkins * @since 2019-03-22 * @since v0.2.0 @@ -45,9 +45,7 @@ class ExpressionParserTest { .addUnaryOperator("recip", o1 -> 1 / o1, 3) .addBinaryOperator("^", (o1, o2) -> (int) Math.pow(o1, o2), 4).build(); - /** - * The expressions used in the expression parsing tests - */ + /** The expressions used in the expression parsing tests */ private static final List<String> TEST_EXPRESSIONS = List.of( // test parsing of expressions "1 + 2 ^ 5 * 3", "(1 + 2) ^ 5 * 3", @@ -56,22 +54,9 @@ class ExpressionParserTest { // ensure it normally goes from left to right "1 + 2 + 3 + 4", "12 - 4 - 3", "12 - (4 - 3)", "1 / 2 + 3"); - /** - * The expected results for evaluating these expressions - */ + /** The expected results for evaluating these expressions */ private static final int[] RESULTS = { 97, 729, 133, 10, 5, 11, 3 }; - /** - * @return A stream of objects, where each one is an expression and the - * expected result - * @since 2021-09-27 - * @since v0.3.2 - */ - private static final Stream<Arguments> testParseExpressionData() { - return IntStream.range(0, TEST_EXPRESSIONS.size()) - .mapToObj(i -> Arguments.of(TEST_EXPRESSIONS.get(i), RESULTS[i])); - } - private static final Stream<Arguments> testConvertExpressionToRPN() { return Stream.of(Arguments.of("1 + 2 ^ 5 * 3", "1 2 5 ^ 3 * +"), Arguments.of("(1 + 2) ^ 5 * 3", "1 2 + 5 ^ 3 *"), @@ -91,18 +76,6 @@ class ExpressionParserTest { Arguments.of("1 + neg 2", "1 2 neg +")); } - private static final Stream<Arguments> testParseRPN() { - return Stream.of(Arguments.of("1 2 5 ^ 3 * +", 97), - Arguments.of("1 2 + 5 ^ 3 *", 729), - Arguments.of("12 5 * 3 2 3 * ^ 72 - 3 3 2 * + / +", 133), - Arguments.of("1 2 + 3 + 4 +", 10), Arguments.of("12 4 - 3 -", 5), - Arguments.of("12 4 3 - -", 11), Arguments.of("1 2 / 3 +", 3), - Arguments.of("12", 12), Arguments.of("2 3 * 4 +", 10), - Arguments.of("2 3 * 4 -", 2), Arguments.of("2 3 4 + *", 14), - Arguments.of("2 3 4 - *", -2), Arguments.of("2 neg", -2), - Arguments.of("1 2 neg +", -1)); - } - private static final Stream<String> testInvalidExpression() { return Stream.of("+", "1 +", "1 + * 2", "1 (+ 1)", "neg"); } @@ -112,13 +85,26 @@ class ExpressionParserTest { } /** - * Test method for - * {@link sevenUnits.utils.ExpressionParser#parseExpression(java.lang.String)}. + * @return A stream of objects, where each one is an expression and the + * expected result + * @since 2021-09-27 + * @since v0.3.2 */ - @ParameterizedTest - @MethodSource("testParseExpressionData") - public void testParseExpression(String expression, int value) { - assertEquals(value, numberParser.parseExpression(expression)); + private static final Stream<Arguments> testParseExpressionData() { + return IntStream.range(0, TEST_EXPRESSIONS.size()) + .mapToObj(i -> Arguments.of(TEST_EXPRESSIONS.get(i), RESULTS[i])); + } + + private static final Stream<Arguments> testParseRPN() { + return Stream.of(Arguments.of("1 2 5 ^ 3 * +", 97), + Arguments.of("1 2 + 5 ^ 3 *", 729), + Arguments.of("12 5 * 3 2 3 * ^ 72 - 3 3 2 * + / +", 133), + Arguments.of("1 2 + 3 + 4 +", 10), Arguments.of("12 4 - 3 -", 5), + Arguments.of("12 4 3 - -", 11), Arguments.of("1 2 / 3 +", 3), + Arguments.of("12", 12), Arguments.of("2 3 * 4 +", 10), + Arguments.of("2 3 * 4 -", 2), Arguments.of("2 3 4 + *", 14), + Arguments.of("2 3 4 - *", -2), Arguments.of("2 neg", -2), + Arguments.of("1 2 neg +", -1)); } @ParameterizedTest @@ -138,15 +124,25 @@ class ExpressionParserTest { @ParameterizedTest @MethodSource - public void testParseRPN(String expressionRPN, int value) { - assertEquals(value, - numberParser.parseReversePolishExpression(expressionRPN)); + public void testInvalidRPN(String expressionRPN) { + assertThrows(RuntimeException.class, + () -> numberParser.parseReversePolishExpression(expressionRPN)); + } + + /** + * Test method for + * {@link sevenUnits.utils.ExpressionParser#parseExpression(java.lang.String)}. + */ + @ParameterizedTest + @MethodSource("testParseExpressionData") + public void testParseExpression(String expression, int value) { + assertEquals(value, numberParser.parseExpression(expression)); } @ParameterizedTest @MethodSource - public void testInvalidRPN(String expressionRPN) { - assertThrows(RuntimeException.class, - () -> numberParser.parseReversePolishExpression(expressionRPN)); + public void testParseRPN(String expressionRPN, int value) { + assertEquals(value, + numberParser.parseReversePolishExpression(expressionRPN)); } } diff --git a/src/test/java/sevenUnits/utils/NameSymbolTest.java b/src/test/java/sevenUnits/utils/NameSymbolTest.java index 3ae2448..f8843e0 100644 --- a/src/test/java/sevenUnits/utils/NameSymbolTest.java +++ b/src/test/java/sevenUnits/utils/NameSymbolTest.java @@ -33,37 +33,65 @@ import org.junit.jupiter.params.provider.MethodSource; /** * Tests for the {@link NameSymbol} class. - * + * * @since v1.0.0 */ class NameSymbolTest { private static Stream<Arguments> testEqualsHashCode() { return Stream.of( - Arguments.of(NameSymbol.ofName("test"), NameSymbol.ofName("test"), true), + Arguments.of(NameSymbol.ofName("test"), NameSymbol.ofName("test"), + true), Arguments.of(NameSymbol.ofName("a"), NameSymbol.ofName("b"), false), - Arguments.of(NameSymbol.ofSymbol("test"), NameSymbol.ofSymbol("test"), true), - Arguments.of(NameSymbol.ofSymbol("a"), NameSymbol.ofSymbol("b"), false), - Arguments.of(NameSymbol.ofName("test"), NameSymbol.ofSymbol("test"), false), - Arguments.of(NameSymbol.of("main", "s"), NameSymbol.of("main", "s"), true), - Arguments.of(NameSymbol.of("main", "s"), NameSymbol.of("main", "s", "m"), false), + Arguments.of(NameSymbol.ofSymbol("test"), + NameSymbol.ofSymbol("test"), true), + Arguments.of(NameSymbol.ofSymbol("a"), NameSymbol.ofSymbol("b"), + false), + Arguments.of(NameSymbol.ofName("test"), NameSymbol.ofSymbol("test"), + false), + Arguments.of(NameSymbol.of("main", "s"), NameSymbol.of("main", "s"), + true), + Arguments.of(NameSymbol.of("main", "s"), + NameSymbol.of("main", "s", "m"), false), Arguments.of(new NameSymbol(null, null, new HashSet<>()), new NameSymbol(null, null, new HashSet<>()), true), - Arguments.of(new NameSymbol( - Optional.of("main"), Optional.of("s"), new HashSet<>()), + Arguments.of( + new NameSymbol(Optional.of("main"), Optional.of("s"), + new HashSet<>()), new NameSymbol(null, null, new HashSet<>()), false), Arguments.of(new NameSymbol(null, null, new HashSet<>()), new NameSymbol(Optional.of("main"), Optional.of("s"), - new HashSet<>()), false), - Arguments.of(new NameSymbol(Optional.of("main"), null, new HashSet<>()), + new HashSet<>()), + false), + Arguments.of( + new NameSymbol(Optional.of("main"), null, new HashSet<>()), new NameSymbol(Optional.of("main"), Optional.of("s"), - new HashSet<>()), false)); + new HashSet<>()), + false)); + } + + @Test + public void testCreate() { + final Set<String> names = Set.of("a", "b", "c"); + final var ns = NameSymbol.ofNullable(null, null, names); + assertTrue(ns.getPrimaryName().isPresent(), + "NameSymbol created without primary name."); + assertTrue(names.contains(ns.getPrimaryName().orElseThrow()), + String.format("Primary name (%s) was not obtained from names set.", + ns.getPrimaryName())); + assertFalse( + ns.getOtherNames().contains(ns.getPrimaryName().orElseThrow()), + String.format("Primary name (%s) was included in other names set.", + ns.getPrimaryName())); + assertEquals(Set.of("a", "b", "c"), names, + "names input was changed by ofNullable()"); } - + /** - * Tests that two NameSymbols are or are not equal. - * If they are equal, also ensures they have the same hash code. - * @param a first NameSymbol to test - * @param b second NameSymbol to test + * Tests that two NameSymbols are or are not equal. If they are equal, also + * ensures they have the same hash code. + * + * @param a first NameSymbol to test + * @param b second NameSymbol to test * @param equal true iff a should be equal to be, otherwise false */ @ParameterizedTest @@ -77,18 +105,4 @@ class NameSymbolTest { assertFalse(Objects.equals(a, b)); } } - - @Test - public void testCreate() { - Set<String> names = Set.of("a", "b", "c"); - NameSymbol ns = NameSymbol.ofNullable(null, null, names); - assertTrue(ns.getPrimaryName().isPresent(), "NameSymbol created without primary name."); - assertTrue(names.contains(ns.getPrimaryName().orElseThrow()), - String.format("Primary name (%s) was not obtained from names set.", - ns.getPrimaryName())); - assertFalse(ns.getOtherNames().contains(ns.getPrimaryName().orElseThrow()), - String.format("Primary name (%s) was included in other names set.", - ns.getPrimaryName())); - assertEquals(Set.of("a", "b", "c"), names, "names input was changed by ofNullable()"); - } } diff --git a/src/test/java/sevenUnits/utils/ObjectProductTest.java b/src/test/java/sevenUnits/utils/ObjectProductTest.java index 584b3f3..7c5df88 100644 --- a/src/test/java/sevenUnits/utils/ObjectProductTest.java +++ b/src/test/java/sevenUnits/utils/ObjectProductTest.java @@ -34,7 +34,7 @@ import sevenUnits.unit.Metric; /** * Tests for {@link ObjectProduct} using BaseDimension as a test object. This is * NOT part of this program's public API. - * + * * @author Adrien Hopkins * @since 2018-12-12 * @since v0.1.0 @@ -42,7 +42,7 @@ import sevenUnits.unit.Metric; class ObjectProductTest { /** * Tests {@link UnitDimension#equals} - * + * * @since 2018-12-12 * @since v0.1.0 */ @@ -54,7 +54,7 @@ class ObjectProductTest { /** * Tests {@code UnitDimension}'s exponentiation - * + * * @since 2019-01-15 * @since v0.1.0 */ @@ -66,7 +66,7 @@ class ObjectProductTest { /** * Tests {@code UnitDimension}'s multiplication and division. - * + * * @since 2018-12-12 * @since v0.1.0 */ diff --git a/src/test/java/sevenUnits/utils/SemanticVersionTest.java b/src/test/java/sevenUnits/utils/SemanticVersionTest.java index 3bef773..047f0b5 100644 --- a/src/test/java/sevenUnits/utils/SemanticVersionTest.java +++ b/src/test/java/sevenUnits/utils/SemanticVersionTest.java @@ -40,7 +40,7 @@ import org.junit.jupiter.api.Test; public final class SemanticVersionTest { /** * Test for {@link SemanticVersionNumber#compatible} - * + * * @since 2022-02-20 * @since v0.4.0 */ @@ -66,32 +66,32 @@ public final class SemanticVersionTest { /** * Tests {@link SemanticVersionNumber#toString} for complex version numbers - * + * * @since 2022-02-19 * @since v0.4.0 */ @Test public void testComplexToString() { - final SemanticVersionNumber v1 = builder(1, 2, 3).preRelease(1, 2, 3) + final var v1 = builder(1, 2, 3).preRelease(1, 2, 3) .build(); assertEquals("1.2.3-1.2.3", v1.toString()); - final SemanticVersionNumber v2 = builder(4, 5, 6).preRelease("abc", 123) + final var v2 = builder(4, 5, 6).preRelease("abc", 123) .buildMetadata("2022-02-19").build(); assertEquals("4.5.6-abc.123+2022-02-19", v2.toString()); - final SemanticVersionNumber v3 = builder(1, 0, 0) + final var v3 = builder(1, 0, 0) .preRelease("x-y-z", "--").build(); assertEquals("1.0.0-x-y-z.--", v3.toString()); } /** * Tests that complex version can be created and their parts read - * + * * @since 2022-02-19 * @since v0.4.0 */ @Test public void testComplexVersions() { - final SemanticVersionNumber v1 = builder(1, 2, 3).preRelease(1, 2, 3) + final var v1 = builder(1, 2, 3).preRelease(1, 2, 3) .build(); assertEquals(1, v1.majorVersion()); assertEquals(2, v1.minorVersion()); @@ -99,7 +99,7 @@ public final class SemanticVersionTest { assertEquals(List.of("1", "2", "3"), v1.preReleaseIdentifiers()); assertEquals(List.of(), v1.buildMetadata()); - final SemanticVersionNumber v2 = builder(4, 5, 6).preRelease("abc", 123) + final var v2 = builder(4, 5, 6).preRelease("abc", 123) .buildMetadata("2022-02-19").build(); assertEquals(4, v2.majorVersion()); assertEquals(5, v2.minorVersion()); @@ -107,7 +107,7 @@ public final class SemanticVersionTest { assertEquals(List.of("abc", "123"), v2.preReleaseIdentifiers()); assertEquals(List.of("2022-02-19"), v2.buildMetadata()); - final SemanticVersionNumber v3 = builder(1, 0, 0) + final var v3 = builder(1, 0, 0) .preRelease("x-y-z", "--").build(); assertEquals(1, v3.majorVersion()); assertEquals(0, v3.minorVersion()); @@ -118,7 +118,7 @@ public final class SemanticVersionTest { /** * Test that semantic version strings can be parsed correctly - * + * * @since 2022-02-19 * @since v0.4.0 * @see SemanticVersionNumber#fromString @@ -158,9 +158,7 @@ public final class SemanticVersionTest { "Could not parse 1.2.3-abc.56.def+2022abc99"); } - /** - * Ensures it is impossible to create invalid version numbers - */ + /** Ensures it is impossible to create invalid version numbers */ @Test public void testInvalidVersionNumbers() { // stableVersion() @@ -204,7 +202,7 @@ public final class SemanticVersionTest { assertThrows(IllegalArgumentException.class, () -> builder(-3, 0, 7), "Negative major version number tolerated by builder"); - final SemanticVersionNumber.Builder testBuilder = builder(1, 2, 3); + final var testBuilder = builder(1, 2, 3); // note: builder.buildMetadata(null) doesn't even compile lol // builder.buildMetadata assertThrows(NullPointerException.class, @@ -270,7 +268,7 @@ public final class SemanticVersionTest { /** * Test for {@link SemanticVersionNumber#isStable} - * + * * @since 2022-02-19 * @since v0.4.0 */ @@ -294,30 +292,30 @@ public final class SemanticVersionTest { * {@link SemanticVersionNumber#compareTo} according to official rules. Tests * all of the versions compared in section 11 of the SemVer 2.0.0 document * and some more. - * + * * @since 2022-02-19 * @since v0.4.0 */ @Test public void testOrder() { - final SemanticVersionNumber v100a = builder(1, 0, 0).preRelease("alpha") + final var v100a = builder(1, 0, 0).preRelease("alpha") .build(); // 1.0.0-alpha - final SemanticVersionNumber v100a1 = preRelease(1, 0, 0, "alpha", 1); // 1.0.0-alpha.1 - final SemanticVersionNumber v100ab = builder(1, 0, 0) + final var v100a1 = preRelease(1, 0, 0, "alpha", 1); // 1.0.0-alpha.1 + final var v100ab = builder(1, 0, 0) .preRelease("alpha", "beta").build(); // 1.0.0-alpha.beta - final SemanticVersionNumber v100b = builder(1, 0, 0).preRelease("beta") + final var v100b = builder(1, 0, 0).preRelease("beta") .build(); // 1.0.0-alpha - final SemanticVersionNumber v100b2 = preRelease(1, 0, 0, "beta", 2); // 1.0.0-beta.2 - final SemanticVersionNumber v100b11 = preRelease(1, 0, 0, "beta", 11); // 1.0.0-beta.11 - final SemanticVersionNumber v100rc1 = preRelease(1, 0, 0, "rc", 1); // 1.0.0-rc.1 - final SemanticVersionNumber v100 = stableVersion(1, 0, 0); - final SemanticVersionNumber v100plus = builder(1, 0, 0) + final var v100b2 = preRelease(1, 0, 0, "beta", 2); // 1.0.0-beta.2 + final var v100b11 = preRelease(1, 0, 0, "beta", 11); // 1.0.0-beta.11 + final var v100rc1 = preRelease(1, 0, 0, "rc", 1); // 1.0.0-rc.1 + final var v100 = stableVersion(1, 0, 0); + final var v100plus = builder(1, 0, 0) .buildMetadata("blah", "blah", "blah").build(); // 1.0.0+blah.blah.blah - final SemanticVersionNumber v200 = stableVersion(2, 0, 0); - final SemanticVersionNumber v201 = stableVersion(2, 0, 1); - final SemanticVersionNumber v210 = stableVersion(2, 1, 0); - final SemanticVersionNumber v211 = stableVersion(2, 1, 1); - final SemanticVersionNumber v300 = stableVersion(3, 0, 0); + final var v200 = stableVersion(2, 0, 0); + final var v201 = stableVersion(2, 0, 1); + final var v210 = stableVersion(2, 1, 0); + final var v211 = stableVersion(2, 1, 1); + final var v300 = stableVersion(3, 0, 0); // test order of version numbers assertTrue(v100a.compareTo(v100a1) < 0, "1.0.0-alpha >= 1.0.0-alpha.1"); @@ -355,18 +353,18 @@ public final class SemanticVersionTest { /** * Tests that simple stable versions can be created and their parts read - * + * * @since 2022-02-19 * @since v0.4.0 */ @Test public void testSimpleStableVersions() { - final SemanticVersionNumber v100 = stableVersion(1, 0, 0); + final var v100 = stableVersion(1, 0, 0); assertEquals(1, v100.majorVersion()); assertEquals(0, v100.minorVersion()); assertEquals(0, v100.patchVersion()); - final SemanticVersionNumber v925 = stableVersion(9, 2, 5); + final var v925 = stableVersion(9, 2, 5); assertEquals(9, v925.majorVersion()); assertEquals(2, v925.minorVersion()); assertEquals(5, v925.patchVersion()); @@ -375,28 +373,28 @@ public final class SemanticVersionTest { /** * Tests that {@link SemanticVersionNumber#toString} works for simple version * numbers - * + * * @since 2022-02-19 * @since v0.4.0 */ @Test public void testSimpleToString() { - final SemanticVersionNumber v100 = stableVersion(1, 0, 0); + final var v100 = stableVersion(1, 0, 0); assertEquals("1.0.0", v100.toString()); - final SemanticVersionNumber v845a1 = preRelease(8, 4, 5, "alpha", 1); + final var v845a1 = preRelease(8, 4, 5, "alpha", 1); assertEquals("8.4.5-alpha.1", v845a1.toString()); } /** * Tests that simple unstable versions can be created and their parts read - * + * * @since 2022-02-19 * @since v0.4.0 */ @Test public void testSimpleUnstableVersions() { - final SemanticVersionNumber v350a1 = preRelease(3, 5, 0, "alpha", 1); + final var v350a1 = preRelease(3, 5, 0, "alpha", 1); assertEquals(3, v350a1.majorVersion(), "Incorrect major version for v3.5.0a1"); assertEquals(5, v350a1.minorVersion(), diff --git a/src/test/java/sevenUnits/utils/UncertainDoubleTest.java b/src/test/java/sevenUnits/utils/UncertainDoubleTest.java index 518c818..8dcd595 100644 --- a/src/test/java/sevenUnits/utils/UncertainDoubleTest.java +++ b/src/test/java/sevenUnits/utils/UncertainDoubleTest.java @@ -35,48 +35,44 @@ import org.junit.jupiter.api.Test; * @since v0.3.2 */ class UncertainDoubleTest { - /** - * Ensures that the compareTo function behaves correctly. - */ + /** Ensures that the compareTo function behaves correctly. */ @Test final void testCompareTo() { assertTrue(of(2.0, 0.5).compareTo(of(2.0, 0.1)) == 0); assertTrue(of(2.0, 0.5).compareTo(of(1.0, 0.1)) > 0); assertTrue(of(2.0, 0.5).compareTo(of(3.0, 0.1)) < 0); } - - /** - * Tests the ___exact operations - */ + + /** Tests the ___exact operations */ @Test final void testExactOperations() { - final UncertainDouble x = UncertainDouble.of(Math.PI, 0.1); - + final var x = UncertainDouble.of(Math.PI, 0.1); + // slightly different because roundoff errors - final UncertainDouble x1 = UncertainDouble.of(Math.PI + Math.E - Math.E, + final var x1 = UncertainDouble.of(Math.PI + Math.E - Math.E, 0.1); - final UncertainDouble x2 = UncertainDouble.of(Math.PI * Math.E / Math.E, + final var x2 = UncertainDouble.of(Math.PI * Math.E / Math.E, 0.1); - + // get results - final UncertainDouble result1 = x.plusExact(Math.E).minusExact(Math.E); - final UncertainDouble result2 = x.timesExact(Math.E) + final var result1 = x.plusExact(Math.E).minusExact(Math.E); + final var result2 = x.timesExact(Math.E) .dividedByExact(Math.E); - + // test that these operations work & don't change uncertainty assertEquals(x1, result1); assertTrue(x.equivalent(result1)); assertEquals(x2, result2); assertTrue(x.equivalent(result2)); - + // exponents are different assertEquals(Math.pow(Math.PI, Math.E), x.toExponentExact(Math.E).value()); } - + /** * Test for {@link UncertainDouble#fromRoundedString} - * + * * @since 2022-04-18 * @since v0.4.0 */ @@ -84,27 +80,25 @@ class UncertainDoubleTest { final void testFromRoundedString() { assertEquals(of(12345.678, 0.001), fromRoundedString("12345.678")); } - - /** - * Test for {@link UncertainDouble#fromString} - */ + + /** Test for {@link UncertainDouble#fromString} */ @Test final void testFromString() { // valid strings assertEquals(of(2.0, 0.5), fromString("2.0 ± 0.5")); assertEquals(of(2.0, 0.5), fromString("2.0 +- 0.5")); assertEquals(of(2.0, 0.0), fromString("2.0")); - + // invalid strings for (final String s : List.of("2.A", "A", "2.0 ± ", " ± 3.5")) { assertThrows(IllegalArgumentException.class, () -> fromString(s)); } - + // back and forth assertEquals("2.0 ± 0.5", of(2.0, 0.5).toString()); assertEquals("2.0", of(2.0, 0).toString()); } - + @Test final void testHashCode() { assertEquals(of(2.0, 0.5).hashCode(), fromString("2.0 ± 0.5").hashCode()); diff --git a/src/test/java/sevenUnitsGUI/I18nTest.java b/src/test/java/sevenUnitsGUI/I18nTest.java index 78f5da4..2f90d76 100644 --- a/src/test/java/sevenUnitsGUI/I18nTest.java +++ b/src/test/java/sevenUnitsGUI/I18nTest.java @@ -28,68 +28,67 @@ import org.junit.jupiter.params.provider.MethodSource; /** * Tests for the internationalization system. - * + * * @since v1.0.0 */ class I18nTest { + private static final Stream<String> testLocaleSupported() { + return Stream.of("en", "fr"); + } + private static final Stream<Arguments> testLocalization() { - return Stream.of( - Arguments.of("tv.title", "en", "7Units [v]"), + return Stream.of(Arguments.of("tv.title", "en", "7Units [v]"), Arguments.of("tv.title", "fr", "7Unités [v]"), Arguments.of("tv.convert_units.title", "en", "Convert Units"), Arguments.of("tv.convert_units.title", "fr", "Convertir Unités")); } - - private static final Stream<String> testLocaleSupported() { - return Stream.of("en", "fr"); - } /** * Tests that the default locale is supported. - * + * * @since v1.0.0 * @see Presenter#DEFAULT_LOCALE */ @Test void testDefaultLocaleSupported() { - Presenter p = new Presenter(new ViewBot()); + final var p = new Presenter(new ViewBot()); assertNotNull(p.locales.get(Presenter.DEFAULT_LOCALE), "Default locale is not supported."); } - + /** * Ensures that the system supports the provided locale. - * + * * @param localeName locale to test for support - * + * * @since 2025-06-04 * @since v1.0.0 */ @ParameterizedTest @MethodSource void testLocaleSupported(String localeName) { - Presenter p = new Presenter(new ViewBot()); + final var p = new Presenter(new ViewBot()); assertNotNull(p.locales.get(localeName), "Locale \"" + localeName + "\" is not supported."); } /** - * Tests that the system can correctly localize text, - * using the default locales. - * + * Tests that the system can correctly localize text, using the default + * locales. + * * @param key key of text to localize * @param locale locale to use * @param expected expected value of output text - * + * * @since 2025-06-04 * @since v1.0.0 */ @ParameterizedTest @MethodSource void testLocalization(String key, String locale, String expected) { - Presenter p = new Presenter(new ViewBot()); + final var p = new Presenter(new ViewBot()); p.setUserLocale(locale); - String actual = p.getLocalizedText(key); + final var actual = p.getLocalizedText(key); assertEquals(expected, actual); } diff --git a/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java b/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java index 50b390b..ead5f4a 100644 --- a/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java +++ b/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java @@ -37,7 +37,7 @@ import sevenUnits.unit.Metric; class PrefixRepetitionTest { /** * Ensures that the complex repetition rule disallows invalid prefix lists. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -57,7 +57,7 @@ class PrefixRepetitionTest { /** * Tests the {@code NO_REPETITION} rule. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -71,7 +71,7 @@ class PrefixRepetitionTest { /** * Tests the {@code NO_RESTRICTION} rule. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -85,7 +85,7 @@ class PrefixRepetitionTest { /** * Ensures that the complex repetition rule allows valid prefix lists. - * + * * @since 2022-07-17 * @since v0.4.0 */ diff --git a/src/test/java/sevenUnitsGUI/PrefixSearchTest.java b/src/test/java/sevenUnitsGUI/PrefixSearchTest.java index b605d05..00dd960 100644 --- a/src/test/java/sevenUnitsGUI/PrefixSearchTest.java +++ b/src/test/java/sevenUnitsGUI/PrefixSearchTest.java @@ -40,9 +40,7 @@ import sevenUnits.unit.Metric; * @since v0.4.0 */ class PrefixSearchTest { - /** - * A method that creates duplicate copies of the common prefix rule. - */ + /** A method that creates duplicate copies of the common prefix rule. */ private static final PrefixSearchRule getCommonRuleCopy() { return getCoherentOnlyRule(Set.of(Metric.KILO, Metric.MILLI)); } @@ -110,7 +108,7 @@ class PrefixSearchTest { /** * Tests prefix searching for a non-coherent unit and * {@link PrefixSearchRule#COMMON_PREFIXES}. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -125,7 +123,7 @@ class PrefixSearchTest { /** * Tests that {@link PrefixSearchRule#NO_PREFIXES} returns the original unit. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -151,10 +149,10 @@ class PrefixSearchTest { */ @Test final void testToString() { - final String toString = COMMON_PREFIXES.toString(); - final String valid1 = "Apply the following prefixes: [kilo (\u00D7 1000.0), milli (\u00D7 0.001)]"; - final String valid2 = "Apply the following prefixes: [milli (\u00D7 0.001), kilo (\u00D7 1000.0)]"; - + final var toString = COMMON_PREFIXES.toString(); + final var valid1 = "Apply the following prefixes: [kilo (\u00D7 1000.0), milli (\u00D7 0.001)]"; + final var valid2 = "Apply the following prefixes: [milli (\u00D7 0.001), kilo (\u00D7 1000.0)]"; + assertTrue(valid1.equals(toString) || valid2.equals(toString), "COMMON_PREFIXES.toString invalid (was \"" + toString + "\")."); } diff --git a/src/test/java/sevenUnitsGUI/RoundingTest.java b/src/test/java/sevenUnitsGUI/RoundingTest.java index e6453f2..589b8d0 100644 --- a/src/test/java/sevenUnitsGUI/RoundingTest.java +++ b/src/test/java/sevenUnitsGUI/RoundingTest.java @@ -137,7 +137,7 @@ class RoundingTest { /** * Tests that the rounding methods' equals() methods work. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -161,7 +161,7 @@ class RoundingTest { // test that FixedDecimals is never equal to FixedPrecision // this unlikely argument is the test - the equals should return false! @SuppressWarnings("unlikely-arg-type") - final boolean differentRulesEqual = Objects.equals(fixedDecimals(4), + final var differentRulesEqual = Objects.equals(fixedDecimals(4), fixedPrecision(4)); assertFalse(differentRulesEqual, "fixedDecimals(4) == fixedPrecision(4)"); } @@ -226,7 +226,7 @@ class RoundingTest { /** * Tests that {@link StandardDisplayRules#getStandardRule} gets rounding * rules as intended. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -244,7 +244,7 @@ class RoundingTest { /** * Tests that the rounding methods' equals() methods work. - * + * * @since 2022-07-17 * @since v0.4.0 */ @@ -258,7 +258,7 @@ class RoundingTest { /** * Tests that the {@code toString()} methods of the three rounding rule * classes work correctly. - * + * * @since 2022-07-17 * @since v0.4.0 */ diff --git a/src/test/java/sevenUnitsGUI/TabbedViewTest.java b/src/test/java/sevenUnitsGUI/TabbedViewTest.java index 3716673..b32579c 100644 --- a/src/test/java/sevenUnitsGUI/TabbedViewTest.java +++ b/src/test/java/sevenUnitsGUI/TabbedViewTest.java @@ -33,67 +33,67 @@ import org.junit.jupiter.api.Timeout; class TabbedViewTest { /** * @return a view with all settings set to standard values - * + * * @since 2022-07-17 * @since v0.4.0 */ private static final TabbedView setupView() { final var view = new TabbedView(); final var presenter = view.getPresenter(); - + presenter.setNumberDisplayRule(StandardDisplayRules.uncertaintyBased()); presenter.setPrefixRepetitionRule( DefaultPrefixRepetitionRule.NO_RESTRICTION); presenter.setSearchRule(PrefixSearchRule.COMMON_PREFIXES); presenter.setOneWayConversionEnabled(false); presenter.setShowDuplicates(true); - + return view; } - + /** * Simulates an expression conversion operation, and ensures it works * properly. - * + * * @since 2022-07-17 * @since v0.4.0 */ @Test void testExpressionConversion() { final var view = setupView(); - + // prepare for unit conversion view.masterPane.setSelectedIndex(1); view.fromEntry.setText("250.0 inch"); view.toEntry.setText("metre"); - + view.convertExpressionButton.doClick(); - + // check result of conversion assertEquals("250.0 inch = 6.350 metre", view.expressionOutput.getText()); } - + /** * Simulates a unit conversion operation, and ensures it works properly. - * + * * @since 2022-07-17 * @since v0.4.0 */ @Test void testUnitConversion() { final var view = setupView(); - + // prepare for unit conversion view.masterPane.setSelectedIndex(0); view.dimensionSelector.setSelectedItem("Length"); view.fromSearch.getSearchList().setSelectedValue("inch", true); view.toSearch.getSearchList().setSelectedValue("metre", true); view.valueInput.setText("250.0"); - + view.convertUnitButton.doClick(); - + // check result of conversion assertEquals("250.0 inch = 6.350 metre", view.unitOutput.getText()); } - + } |