summaryrefslogtreecommitdiff
path: root/src/main/java/sevenUnits/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/sevenUnits/utils')
-rw-r--r--src/main/java/sevenUnits/utils/ObjectProduct.java135
1 files changed, 67 insertions, 68 deletions
diff --git a/src/main/java/sevenUnits/utils/ObjectProduct.java b/src/main/java/sevenUnits/utils/ObjectProduct.java
index 1dacb7d..5b1b739 100644
--- a/src/main/java/sevenUnits/utils/ObjectProduct.java
+++ b/src/main/java/sevenUnits/utils/ObjectProduct.java
@@ -27,8 +27,8 @@ import java.util.Set;
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.
+ * An immutable product of multiple objects of a type, such as base units. The
+ * objects can be multiplied and exponentiated.
*
* @author Adrien Hopkins
* @since 2019-10-16
@@ -37,38 +37,35 @@ public final class ObjectProduct<T> {
/**
* Returns an empty ObjectProduct of a certain type
*
- * @param <T>
- * type of objects that can be multiplied
+ * @param <T> type of objects that can be multiplied
* @return empty product
* @since 2019-10-16
*/
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
+ * @param <T> type of object in product
+ * @param map map mapping objects to exponents
* @return object product
* @since 2019-10-16
*/
- public static final <T> ObjectProduct<T> fromExponentMapping(final Map<T, Integer> map) {
+ public static final <T> ObjectProduct<T> fromExponentMapping(
+ final Map<T, Integer> map) {
return new ObjectProduct<>(new HashMap<>(map));
}
-
+
/**
- * Gets an ObjectProduct that has one of the inputted argument, and nothing else.
+ * Gets an ObjectProduct that has one of the inputted argument, and nothing
+ * else.
*
- * @param object
- * object that will be in the product
+ * @param object object that will be in the product
* @return product
* @since 2019-10-16
- * @throws NullPointerException
- * if object is null
+ * @throws NullPointerException if object is null
*/
public static final <T> ObjectProduct<T> oneOf(final T object) {
Objects.requireNonNull(object, "object must not be null.");
@@ -76,35 +73,34 @@ public final class ObjectProduct<T> {
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.
+ * The objects that make up the product, mapped to their exponents. This map
+ * treats zero as null, and is immutable.
*
* @since 2019-10-16
*/
final Map<T, Integer> exponents;
-
+
/**
* Creates the {@code ObjectProduct}.
*
- * @param exponents
- * objects that make up this product
+ * @param exponents objects that make up this product
* @since 2019-10-16
*/
private ObjectProduct(final Map<T, Integer> exponents) {
- this.exponents = Collections.unmodifiableMap(ConditionalExistenceCollections.conditionalExistenceMap(exponents,
- e -> !Integer.valueOf(0).equals(e.getValue())));
+ this.exponents = Collections.unmodifiableMap(
+ ConditionalExistenceCollections.conditionalExistenceMap(exponents,
+ e -> !Integer.valueOf(0).equals(e.getValue())));
}
-
+
/**
* Calculates the quotient of two products
*
- * @param other
- * other product
+ * @param other other product
* @return quotient of two products
* @since 2019-10-16
- * @throws NullPointerException
- * if other is null
+ * @throws NullPointerException if other is null
*/
public ObjectProduct<T> dividedBy(final ObjectProduct<T> other) {
Objects.requireNonNull(other, "other must not be null.");
@@ -112,17 +108,17 @@ public final class ObjectProduct<T> {
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) {
@@ -133,7 +129,7 @@ public final class ObjectProduct<T> {
final ObjectProduct<?> other = (ObjectProduct<?>) obj;
return Objects.equals(this.exponents, other.exponents);
}
-
+
/**
* @return immutable map mapping objects to exponents
* @since 2019-10-16
@@ -141,30 +137,31 @@ public final class ObjectProduct<T> {
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.
+ * @return a set of all of the base objects with non-zero exponents that make
+ * up this dimension.
* @since 2018-12-12
* @since v0.1.0
*/
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
+
+ // add all dimensions with a nonzero exponent - zero exponents shouldn't
+ // be there in the first place
for (final T dimension : this.exponents.keySet()) {
if (!this.exponents.get(dimension).equals(0)) {
dimensions.add(dimension);
}
}
-
+
return dimensions;
}
-
+
/**
* Gets the exponent for a specific dimension.
*
- * @param dimension
- * dimension to check
+ * @param dimension dimension to check
* @return exponent for that dimension
* @since 2018-12-12
* @since v0.1.0
@@ -172,14 +169,15 @@ public final class ObjectProduct<T> {
public int getExponent(final T dimension) {
return this.exponents.getOrDefault(dimension, 0);
}
-
+
@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
+ * @return true if this product is a single object, i.e. it has one exponent
+ * of one and no other nonzero exponents
* @since 2019-10-16
*/
public boolean isSingleObject() {
@@ -194,16 +192,14 @@ public final class ObjectProduct<T> {
}
return oneCount == 1 && !twoOrMore;
}
-
+
/**
* Multiplies this product by another
*
- * @param other
- * other product
+ * @param other other product
* @return product of two products
* @since 2019-10-16
- * @throws NullPointerException
- * if other is null
+ * @throws NullPointerException if other is null
*/
public ObjectProduct<T> times(final ObjectProduct<T> other) {
Objects.requireNonNull(other, "other must not be null.");
@@ -211,22 +207,21 @@ public final class ObjectProduct<T> {
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
+ * @param exponent exponent
* @return result of exponentiation
* @since 2019-10-16
*/
@@ -237,11 +232,12 @@ public final class ObjectProduct<T> {
}
return new ObjectProduct<>(map);
}
-
+
/**
- * Converts this product to a string using the objects' {@link Object#toString()} method. If objects have a long
- * toString representation, it is recommended to use {@link #toString(Function)} instead to shorten the returned
- * string.
+ * Converts this product to a string using the objects'
+ * {@link Object#toString()} method. If objects have a long toString
+ * representation, it is recommended to use {@link #toString(Function)}
+ * instead to shorten the returned string.
*
* <p>
* {@inheritDoc}
@@ -250,35 +246,38 @@ public final class ObjectProduct<T> {
public String toString() {
return this.toString(Object::toString);
}
-
+
/**
- * Converts this product to a string. The objects that make up this product are represented by
- * {@code objectToString}
+ * 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
+ * @param objectToString function to convert objects to strings
* @return string representation of product
* @since 2019-10-16
*/
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);
- if (exponent > 0) {
- positiveStringComponents.add(String.format("%s^%d", objectToString.apply(object), exponent));
+ if (exponent > 1) {
+ positiveStringComponents.add(String.format("%s^%d",
+ objectToString.apply(object), exponent));
+ } else if (exponent == 1) {
+ positiveStringComponents.add(objectToString.apply(object));
} else if (exponent < 0) {
- negativeStringComponents.add(String.format("%s^%d", objectToString.apply(object), -exponent));
+ negativeStringComponents.add(String.format("%s^%d",
+ objectToString.apply(object), -exponent));
}
}
-
+
final String positiveString = positiveStringComponents.isEmpty() ? "1"
: String.join(" * ", positiveStringComponents);
final String negativeString = negativeStringComponents.isEmpty() ? ""
: " / " + String.join(" * ", negativeStringComponents);
-
+
return positiveString + negativeString;
}
}