diff --git a/src/main/java/com/thealgorithms/conversions/UnitsConverter.java b/src/main/java/com/thealgorithms/conversions/UnitsConverter.java
index 81c4d4562..00690b2c0 100644
--- a/src/main/java/com/thealgorithms/conversions/UnitsConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/UnitsConverter.java
@@ -7,6 +7,43 @@ import java.util.NoSuchElementException;
import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;
+/**
+ * A class that handles unit conversions using affine transformations.
+ *
+ *
The {@code UnitsConverter} allows converting values between different units using
+ * pre-defined affine conversion formulas. Each conversion is represented by an
+ * {@link AffineConverter} that defines the scaling and offset for the conversion.
+ *
+ *
For each unit, both direct conversions (e.g., Celsius to Fahrenheit) and inverse
+ * conversions (e.g., Fahrenheit to Celsius) are generated automatically. It also computes
+ * transitive conversions (e.g., Celsius to Kelvin via Fahrenheit if both conversions exist).
+ *
+ *
Key features include:
+ *
+ * - Automatic handling of inverse conversions (e.g., Fahrenheit to Celsius).
+ * - Compositional conversions, meaning if conversions between A -> B and B -> C exist,
+ * it can automatically generate A -> C conversion.
+ * - Supports multiple unit systems as long as conversions are provided in pairs.
+ *
+ *
+ * Example Usage
+ *
+ * Map<Pair<String, String>, AffineConverter> basicConversions = Map.ofEntries(
+ * entry(Pair.of("Celsius", "Fahrenheit"), new AffineConverter(9.0 / 5.0, 32.0)),
+ * entry(Pair.of("Kelvin", "Celsius"), new AffineConverter(1.0, -273.15))
+ * );
+ *
+ * UnitsConverter converter = new UnitsConverter(basicConversions);
+ * double result = converter.convert("Celsius", "Fahrenheit", 100.0);
+ * // Output: 212.0 (Celsius to Fahrenheit conversion of 100°C)
+ *
+ *
+ * Exception Handling
+ *
+ * - If the input unit and output unit are the same, an {@link IllegalArgumentException} is thrown.
+ * - If a conversion between the requested units does not exist, a {@link NoSuchElementException} is thrown.
+ *
+ */
public final class UnitsConverter {
private final Map, AffineConverter> conversions;
private final Set units;
@@ -68,11 +105,29 @@ public final class UnitsConverter {
return res;
}
+ /**
+ * Constructor for {@code UnitsConverter}.
+ *
+ * Accepts a map of basic conversions and automatically generates inverse and
+ * transitive conversions.
+ *
+ * @param basicConversions the initial set of unit conversions to add.
+ */
public UnitsConverter(final Map, AffineConverter> basicConversions) {
conversions = computeAllConversions(basicConversions);
units = extractUnits(conversions);
}
+ /**
+ * Converts a value from one unit to another.
+ *
+ * @param inputUnit the unit of the input value.
+ * @param outputUnit the unit to convert the value into.
+ * @param value the value to convert.
+ * @return the converted value in the target unit.
+ * @throws IllegalArgumentException if inputUnit equals outputUnit.
+ * @throws NoSuchElementException if no conversion exists between the units.
+ */
public double convert(final String inputUnit, final String outputUnit, final double value) {
if (inputUnit.equals(outputUnit)) {
throw new IllegalArgumentException("inputUnit must be different from outputUnit.");
@@ -81,6 +136,11 @@ public final class UnitsConverter {
return conversions.computeIfAbsent(conversionKey, k -> { throw new NoSuchElementException("No converter for: " + k); }).convert(value);
}
+ /**
+ * Retrieves the set of all units supported by this converter.
+ *
+ * @return a set of available units.
+ */
public Set availableUnits() {
return units;
}
diff --git a/src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java b/src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java
index 580a66bc0..0952129ef 100644
--- a/src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java
+++ b/src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java
@@ -1,10 +1,12 @@
package com.thealgorithms.conversions;
import static java.util.Map.entry;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.api.Test;
@@ -24,4 +26,19 @@ public class UnitsConverterTest {
assertThrows(NoSuchElementException.class, () -> someConverter.convert("X", "A", 20.0));
assertThrows(NoSuchElementException.class, () -> someConverter.convert("X", "Y", 20.0));
}
+
+ @Test
+ void testAvailableUnits() {
+ final UnitsConverter someConverter = new UnitsConverter(Map.ofEntries(entry(Pair.of("Celsius", "Fahrenheit"), new AffineConverter(9.0 / 5.0, 32.0)), entry(Pair.of("Kelvin", "Celsius"), new AffineConverter(1.0, -273.15))));
+ assertEquals(Set.of("Celsius", "Fahrenheit", "Kelvin"), someConverter.availableUnits());
+ }
+
+ @Test
+ void testInvertConversion() {
+ final UnitsConverter someConverter = new UnitsConverter(Map.ofEntries(entry(Pair.of("A", "B"), new AffineConverter(2.0, 5.0))));
+ // Check conversion from A -> B
+ assertEquals(25.0, someConverter.convert("A", "B", 10.0), 0.0001);
+ // Check inverse conversion from B -> A
+ assertEquals(10.0, someConverter.convert("B", "A", 25.0), 0.0001);
+ }
}