summaryrefslogtreecommitdiff
path: root/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/org')
-rwxr-xr-xsrc/org/unitConverter/UnitsDatabase.java395
1 files changed, 259 insertions, 136 deletions
diff --git a/src/org/unitConverter/UnitsDatabase.java b/src/org/unitConverter/UnitsDatabase.java
index 901c6ef..959c151 100755
--- a/src/org/unitConverter/UnitsDatabase.java
+++ b/src/org/unitConverter/UnitsDatabase.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiFunction;
@@ -83,6 +84,153 @@ public final class UnitsDatabase {
* @since 2019-04-13
*/
private static final class PrefixedUnitEntrySet extends AbstractSet<Map.Entry<String, Unit>> {
+ /**
+ * The entry for this set.
+ *
+ * @author Adrien Hopkins
+ * @since 2019-04-14
+ */
+ private static final class PrefixedUnitEntry implements Entry<String, Unit> {
+ private final String key;
+ private final Unit value;
+
+ /**
+ * Creates the {@code PrefixedUnitEntry}.
+ *
+ * @param key
+ * @param value
+ * @since 2019-04-14
+ */
+ public PrefixedUnitEntry(final String key, final Unit value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public String getKey() {
+ return this.key;
+ }
+
+ @Override
+ public Unit getValue() {
+ return this.value;
+ }
+
+ @Override
+ public Unit setValue(final Unit value) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * An iterator that iterates over the units of a {@code PrefixedUnitNameSet}.
+ *
+ * @author Adrien Hopkins
+ * @since 2019-04-14
+ */
+ private static final class PrefixedUnitEntryIterator implements Iterator<Entry<String, Unit>> {
+ // position in the unit list
+ private int unitNamePosition = 0;
+ // the indices of the prefixes attached to the current unit
+ private final List<Integer> prefixCoordinates = new ArrayList<>();
+
+ private final Map<String, Unit> map;
+ private final List<String> unitNames;
+ private final List<String> prefixNames;
+
+ /**
+ * Creates the {@code UnitsDatabase.PrefixedUnitMap.PrefixedUnitNameSet.PrefixedUnitNameIterator}.
+ *
+ * @since 2019-04-14
+ */
+ public PrefixedUnitEntryIterator(final PrefixedUnitEntrySet set) {
+ this.map = set.map;
+ this.unitNames = new ArrayList<>(set.map.units.keySet());
+ this.prefixNames = new ArrayList<>(set.map.prefixes.keySet());
+ }
+
+ /**
+ * @return current unit name
+ * @since 2019-04-14
+ */
+ private String getCurrentUnitName() {
+ final StringBuilder unitName = new StringBuilder();
+ for (final int i : this.prefixCoordinates) {
+ unitName.append(this.prefixNames.get(i));
+ }
+ unitName.append(this.unitNames.get(this.unitNamePosition));
+
+ return unitName.toString();
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (this.unitNames.isEmpty())
+ return false;
+ else {
+ if (this.prefixNames.isEmpty())
+ return this.unitNamePosition >= this.unitNames.size() - 1;
+ else
+ return true;
+ }
+ }
+
+ /**
+ * Changes this iterator's position to the next available one.
+ *
+ * @since 2019-04-14
+ */
+ private void incrementPosition() {
+ this.unitNamePosition++;
+
+ if (this.unitNamePosition >= this.unitNames.size()) {
+ // we have used all of our units, go to a different prefix
+ this.unitNamePosition = 0;
+
+ // if the prefix coordinates are empty, then set it to [0]
+ if (this.prefixCoordinates.isEmpty()) {
+ this.prefixCoordinates.add(0, 0);
+ } else {
+ // get the prefix coordinate to increment, then increment
+ int i = this.prefixCoordinates.size() - 1;
+ this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1);
+
+ // fix any carrying errors
+ while (i >= 0 && this.prefixCoordinates.get(i) >= this.prefixNames.size()) {
+ // carry over
+ this.prefixCoordinates.set(i--, 0); // null and decrement at the same time
+
+ if (i < 0) { // we need to add a new coordinate
+ this.prefixCoordinates.add(0, 0);
+ } else { // increment an existing one
+ this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public Entry<String, Unit> next() {
+ if (!this.hasNext())
+ throw new NoSuchElementException("No units left!");
+ // if I have prefixes, ensure I'm not using a nonlinear unit
+ // since all of the unprefixed stuff is done, just remove nonlinear units
+ if (!this.prefixCoordinates.isEmpty()) {
+ while (this.unitNamePosition < this.unitNames.size()
+ && !(this.map.get(this.unitNames.get(this.unitNamePosition)) instanceof LinearUnit)) {
+ this.unitNames.remove(this.unitNamePosition);
+ }
+ }
+
+ final String nextName = this.getCurrentUnitName();
+
+ this.incrementPosition();
+
+ return new PrefixedUnitEntry(nextName, this.map.get(nextName));
+ }
+ }
+
// the map that created this set
private final PrefixedUnitMap map;
@@ -143,83 +291,7 @@ public final class UnitsDatabase {
@Override
public Iterator<Entry<String, Unit>> iterator() {
- return new Iterator<Entry<String, Unit>>() {
- // position in the unit list
- int unitNamePosition = -1;
- // the indices of the prefixes attached to the current unit
- List<Integer> prefixCoordinates = new ArrayList<>();
-
- List<String> unitNames = new ArrayList<>(PrefixedUnitEntrySet.this.map.units.keySet());
- List<String> prefixNames = new ArrayList<>(PrefixedUnitEntrySet.this.map.prefixes.keySet());
-
- @Override
- public boolean hasNext() {
- if (this.unitNames.isEmpty())
- return false;
- else {
- if (this.prefixNames.isEmpty())
- return this.unitNamePosition >= this.unitNames.size() - 1;
- else
- return true;
- }
- }
-
- @Override
- public Entry<String, Unit> next() {
- // increment unit name position
- this.unitNamePosition++;
-
- // if I have prefixes, ensure I'm not using a nonlinear unit
- // since all of the unprefixed stuff is done, just remove nonlinear units
- if (!this.prefixCoordinates.isEmpty()) {
- while (!(PrefixedUnitEntrySet.this.map
- .get(this.unitNames.get(this.unitNamePosition)) instanceof LinearUnit)) {
- this.unitNames.remove(this.unitNamePosition);
- }
- }
-
- // carry over
- if (!this.prefixNames.isEmpty() && this.unitNamePosition >= this.unitNames.size() - 1) {
- // handle prefix position
- this.unitNamePosition = 0;
- int i = this.prefixCoordinates.size() - 1;
- this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1);
-
- while (this.prefixCoordinates.get(i) >= this.prefixNames.size() - 1) {
- this.prefixCoordinates.set(i, 0);
- i--;
- if (i < 0) {
- this.prefixCoordinates.add(0, 0);
- }
- }
- }
-
- // create the unit name
- final StringBuilder unitNameBuilder = new StringBuilder();
- for (final int i : this.prefixCoordinates) {
- unitNameBuilder.append(this.prefixNames.get(i));
- }
- unitNameBuilder.append(this.unitNames.get(this.unitNamePosition));
-
- final String unitName = unitNameBuilder.toString();
- return new Entry<String, Unit>() {
- @Override
- public String getKey() {
- return unitName;
- }
-
- @Override
- public Unit getValue() {
- return PrefixedUnitEntrySet.this.map.get(unitName);
- }
-
- @Override
- public Unit setValue(final Unit value) {
- throw new UnsupportedOperationException();
- }
- };
- }
- };
+ return new PrefixedUnitEntryIterator(this);
}
@Override
@@ -282,6 +354,115 @@ public final class UnitsDatabase {
* @since 2019-04-13
*/
private static final class PrefixedUnitNameSet extends AbstractSet<String> {
+ /**
+ * An iterator that iterates over the units of a {@code PrefixedUnitNameSet}.
+ *
+ * @author Adrien Hopkins
+ * @since 2019-04-14
+ */
+ private static final class PrefixedUnitNameIterator implements Iterator<String> {
+ // position in the unit list
+ private int unitNamePosition = 0;
+ // the indices of the prefixes attached to the current unit
+ private final List<Integer> prefixCoordinates = new ArrayList<>();
+
+ private final Map<String, Unit> map;
+ private final List<String> unitNames;
+ private final List<String> prefixNames;
+
+ /**
+ * Creates the {@code UnitsDatabase.PrefixedUnitMap.PrefixedUnitNameSet.PrefixedUnitNameIterator}.
+ *
+ * @since 2019-04-14
+ */
+ public PrefixedUnitNameIterator(final PrefixedUnitNameSet set) {
+ this.map = set.map;
+ this.unitNames = new ArrayList<>(set.map.units.keySet());
+ this.prefixNames = new ArrayList<>(set.map.prefixes.keySet());
+ }
+
+ /**
+ * @return current unit name
+ * @since 2019-04-14
+ */
+ private String getCurrentUnitName() {
+ final StringBuilder unitName = new StringBuilder();
+ for (final int i : this.prefixCoordinates) {
+ unitName.append(this.prefixNames.get(i));
+ }
+ unitName.append(this.unitNames.get(this.unitNamePosition));
+
+ return unitName.toString();
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (this.unitNames.isEmpty())
+ return false;
+ else {
+ if (this.prefixNames.isEmpty())
+ return this.unitNamePosition >= this.unitNames.size() - 1;
+ else
+ return true;
+ }
+ }
+
+ /**
+ * Changes this iterator's position to the next available one.
+ *
+ * @since 2019-04-14
+ */
+ private void incrementPosition() {
+ this.unitNamePosition++;
+
+ if (this.unitNamePosition >= this.unitNames.size()) {
+ // we have used all of our units, go to a different prefix
+ this.unitNamePosition = 0;
+
+ // if the prefix coordinates are empty, then set it to [0]
+ if (this.prefixCoordinates.isEmpty()) {
+ this.prefixCoordinates.add(0, 0);
+ } else {
+ // get the prefix coordinate to increment, then increment
+ int i = this.prefixCoordinates.size() - 1;
+ this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1);
+
+ // fix any carrying errors
+ while (i >= 0 && this.prefixCoordinates.get(i) >= this.prefixNames.size()) {
+ // carry over
+ this.prefixCoordinates.set(i--, 0); // null and decrement at the same time
+
+ if (i < 0) { // we need to add a new coordinate
+ this.prefixCoordinates.add(0, 0);
+ } else { // increment an existing one
+ this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public String next() {
+ if (!this.hasNext())
+ throw new NoSuchElementException("No units left!");
+ // if I have prefixes, ensure I'm not using a nonlinear unit
+ // since all of the unprefixed stuff is done, just remove nonlinear units
+ if (!this.prefixCoordinates.isEmpty()) {
+ while (this.unitNamePosition < this.unitNames.size()
+ && !(this.map.get(this.unitNames.get(this.unitNamePosition)) instanceof LinearUnit)) {
+ this.unitNames.remove(this.unitNamePosition);
+ }
+ }
+
+ final String nextName = this.getCurrentUnitName();
+
+ this.incrementPosition();
+
+ return nextName;
+ }
+ }
+
// the map that created this set
private final PrefixedUnitMap map;
@@ -330,65 +511,7 @@ public final class UnitsDatabase {
@Override
public Iterator<String> iterator() {
- return new Iterator<String>() {
- // position in the unit list
- int unitNamePosition = -1;
- // the indices of the prefixes attached to the current unit
- List<Integer> prefixCoordinates = new ArrayList<>();
-
- List<String> unitNames = new ArrayList<>(PrefixedUnitNameSet.this.map.units.keySet());
- List<String> prefixNames = new ArrayList<>(PrefixedUnitNameSet.this.map.prefixes.keySet());
-
- @Override
- public boolean hasNext() {
- if (this.unitNames.isEmpty())
- return false;
- else {
- if (this.prefixNames.isEmpty())
- return this.unitNamePosition >= this.unitNames.size() - 1;
- else
- return true;
- }
- }
-
- @Override
- public String next() {
- // increment unit name position
- this.unitNamePosition++;
-
- // if I have prefixes, ensure I'm not using a nonlinear unit
- // since all of the unprefixed stuff is done, just remove nonlinear units
- if (!this.prefixCoordinates.isEmpty()) {
- while (!(PrefixedUnitNameSet.this.map
- .get(this.unitNames.get(this.unitNamePosition)) instanceof LinearUnit)) {
- this.unitNames.remove(this.unitNamePosition);
- }
- }
-
- // carry over
- if (!this.prefixNames.isEmpty() && this.unitNamePosition >= this.unitNames.size() - 1) {
- // handle prefix position
- this.unitNamePosition = 0;
- int i = this.prefixCoordinates.size() - 1;
- this.prefixCoordinates.set(i, this.prefixCoordinates.get(i) + 1);
-
- while (this.prefixCoordinates.get(i) >= this.prefixNames.size() - 1) {
- this.prefixCoordinates.set(i, 0);
- i--;
- if (i < 0) {
- this.prefixCoordinates.add(0, 0);
- }
- }
- }
-
- final StringBuilder unitName = new StringBuilder();
- for (final int i : this.prefixCoordinates) {
- unitName.append(this.prefixNames.get(i));
- }
- unitName.append(this.unitNames.get(this.unitNamePosition));
- return unitName.toString();
- }
- };
+ return new PrefixedUnitNameIterator(this);
}
@Override