diff options
Diffstat (limited to 'src/main/java/bjc/data')
| -rw-r--r-- | src/main/java/bjc/data/Contexts.java | 96 | ||||
| -rw-r--r-- | src/main/java/bjc/data/GeneratingIterator.java | 2 | ||||
| -rw-r--r-- | src/main/java/bjc/data/MarkListIterator.java | 175 | ||||
| -rw-r--r-- | src/main/java/bjc/data/Multimap.java | 16 | ||||
| -rw-r--r-- | src/main/java/bjc/data/Pair.java | 14 | ||||
| -rw-r--r-- | src/main/java/bjc/data/ResettableIterator.java | 14 |
6 files changed, 244 insertions, 73 deletions
diff --git a/src/main/java/bjc/data/Contexts.java b/src/main/java/bjc/data/Contexts.java index b028ad1..f587fe6 100644 --- a/src/main/java/bjc/data/Contexts.java +++ b/src/main/java/bjc/data/Contexts.java @@ -37,67 +37,67 @@ public class Contexts { public static Context create(Context parent) { return new ContextImpl(parent); } +} - private static class NullContextImpl implements Context { - @Override - public Context getParent() { - return this; - } +class NullContextImpl implements Context { + @Override + public Context getParent() { + return this; + } - @Override - public void register(String name, Object o) { - throw new UnsupportedOperationException(); - } + @Override + public void register(String name, Object o) { + throw new UnsupportedOperationException(); + } - @Override - public Object get(String name) { - throw new NoSuchElementException(); - } - - @Override - public <T> T get(Class<T> contract) { - throw new NoSuchElementException(); - } + @Override + public Object get(String name) { + throw new NoSuchElementException(); } + + @Override + public <T> T get(Class<T> contract) { + throw new NoSuchElementException(); + } +} - private static class ContextImpl implements Context { +class ContextImpl implements Context { - private final Context parent; + private final Context parent; - private final Map<String, Object> objects; + private final Map<String, Object> objects; - public ContextImpl(Context parent) { - this.parent = parent; - this.objects = new HashMap<>(); - } + public ContextImpl(Context parent) { + this.parent = parent; + this.objects = new HashMap<>(); + } - @Override - public void register(String name, Object o) { - objects.put(name, o); - } + @Override + public void register(String name, Object o) { + objects.put(name, o); + } - @Override - public Object get(String name) { - if (objects.containsKey(name)) { - return objects.get(name); - } - return parent.get(name); + @Override + public Object get(String name) { + if (objects.containsKey(name)) { + return objects.get(name); } + return parent.get(name); + } - @SuppressWarnings("unchecked") - @Override - public <T> T get(Class<T> contract) { - for (Object o : objects.values()) { - if (contract.isInstance(o)) { - return (T) o; - } + @SuppressWarnings("unchecked") + @Override + public <T> T get(Class<T> contract) { + for (Object o : objects.values()) { + if (contract.isInstance(o)) { + return (T) o; } - return parent.get(contract); } + return parent.get(contract); + } - @Override - public Context getParent() { - return parent; - } + @Override + public Context getParent() { + return parent; } -} +}
\ No newline at end of file diff --git a/src/main/java/bjc/data/GeneratingIterator.java b/src/main/java/bjc/data/GeneratingIterator.java index f926833..8900b94 100644 --- a/src/main/java/bjc/data/GeneratingIterator.java +++ b/src/main/java/bjc/data/GeneratingIterator.java @@ -42,7 +42,7 @@ public class GeneratingIterator<E> implements Iterator<E> { @Override public boolean hasNext() { - return stpper.test(state); + return !stpper.test(state); } /* diff --git a/src/main/java/bjc/data/MarkListIterator.java b/src/main/java/bjc/data/MarkListIterator.java new file mode 100644 index 0000000..35baa28 --- /dev/null +++ b/src/main/java/bjc/data/MarkListIterator.java @@ -0,0 +1,175 @@ +package bjc.data; + +import java.util.*; + +/** + * ListIterator which allows navigation/marking of an iterator. + * + * @author bjcul + * + * @param <E> The element type + */ +public class MarkListIterator<E> implements ListIterator<E> { + private Iterator<E> backing; + + private List<E> cache; + private Deque<Integer> marks; + + private int currIdx; + private int maxIdx; + + /** + * Create a new marking list iterator. + * + * @param backing The iterator which backs us. + */ + public MarkListIterator(Iterator<E> backing) { + this.backing = backing; + + this.currIdx = 0; + this.maxIdx = 0; + + this.cache = new ArrayList<>(); + this.marks = new ArrayDeque<>(); + } + + /** + * Get the current element of the iterator. + * + * @return The current iterator of the element + */ + public E current() { + return cache.get(currIdx); + } + + /** + * Create a new marking list iterator. + * + * @param backing The iterable to get the backing iterator from. + */ + public MarkListIterator(Iterable<E> backing) { + this(backing.iterator()); + } + + @Override + public boolean hasNext() { + if (currIdx < maxIdx) + return true; + return backing.hasNext(); + } + + @Override + public E next() { + if (currIdx < maxIdx) { + return cache.get(currIdx++); + } + currIdx++; + maxIdx++; + E next = backing.next(); + cache.add(next); + return next; + } + + @Override + public boolean hasPrevious() { + return maxIdx > 0 && currIdx > 0; + } + + @Override + public E previous() { + currIdx--; + return cache.get(currIdx); + } + + @Override + public int nextIndex() { + return currIdx + 1; + } + + @Override + public int previousIndex() { + return currIdx - 1; + } + + /** + * Mark the current position in the iterator. + */ + public void mark() { + marks.push(currIdx); + } + + /** + * Reset the iterator to the last position that was marked, leaving the mark in + * place. + * + * @return Whether or not a rollback actually happened + */ + public boolean rollback() { + return rollback(false); + } + + /** + * Reset the iterator to the last position that was marked. + * + * @param clearMark Whether to clear the mark being rolled back to. + * + * @return Whether or not a rollback actually happened + */ + public boolean rollback(boolean clearMark) { + if (marks.isEmpty()) return false; + + if (clearMark) { + currIdx = marks.pop(); + } else { + currIdx = marks.peek(); + } + return true; + } + + /** + * Remove the last position that was marked. + * + * @return The marked position + */ + public int commit() { + return marks.pop(); + } + + /** + * Resets the cache state of this iterator. + * + * Once this has been called, all of the previous elements and marks are + * discarded. + */ + public void reset() { + this.cache = new ArrayList<>(); + this.marks = new ArrayDeque<>(); + + this.currIdx = 0; + this.maxIdx = 0; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Can't remove items"); + } + + @Override + public void set(E e) { + throw new UnsupportedOperationException("Can't set items"); + } + + @Override + public void add(E e) { + throw new UnsupportedOperationException("Can't add items"); + } + + /** + * Check if this iterator has at least one active mark. + * + * @return Whether this iterator has any active marks. + */ + public boolean hasMark() { + return !marks.isEmpty(); + } +} diff --git a/src/main/java/bjc/data/Multimap.java b/src/main/java/bjc/data/Multimap.java deleted file mode 100644 index 0e858b7..0000000 --- a/src/main/java/bjc/data/Multimap.java +++ /dev/null @@ -1,16 +0,0 @@ -package bjc.data; - -/** - * A map with support for multiple values per key. - * - * @param <KeyType> - * The type of the keys for the map. - * @param <ValueType> - * The type of the values for the map. - * - * @author Ben Culkin - */ -public class Multimap<KeyType, ValueType> { - // TODO either implement this, or find if there is an implementation I've - // written elsewhere -} diff --git a/src/main/java/bjc/data/Pair.java b/src/main/java/bjc/data/Pair.java index baf1894..1d4be5e 100644 --- a/src/main/java/bjc/data/Pair.java +++ b/src/main/java/bjc/data/Pair.java @@ -1,5 +1,8 @@ package bjc.data; +import java.util.Formattable; +import java.util.FormattableFlags; +import java.util.Formatter; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; @@ -18,7 +21,7 @@ import bjc.funcdata.theory.Bifunctor; * The type of the right side of the pair. * */ -public interface Pair<LeftType, RightType> extends Bifunctor<LeftType, RightType> { +public interface Pair<LeftType, RightType> extends Bifunctor<LeftType, RightType>, Formattable { /** * Bind a function across the values in this pair. * @@ -247,4 +250,13 @@ public interface Pair<LeftType, RightType> extends Bifunctor<LeftType, RightType public static <Left, Right> Pair<Left, Right> pair(Left left, Right right) { return new SimplePair<>(left, right); } + + @Override + default void formatTo(Formatter formatter, int flags, int width, int precision) { + if ((flags & FormattableFlags.ALTERNATE) != 0) { + formatter.format("(%s, %s)", getLeft(), getRight()); + } else { + formatter.format("Pair [l=%s, r=%s", getLeft(), getRight()); + } + } } diff --git a/src/main/java/bjc/data/ResettableIterator.java b/src/main/java/bjc/data/ResettableIterator.java index 8b7f07a..8c1c4aa 100644 --- a/src/main/java/bjc/data/ResettableIterator.java +++ b/src/main/java/bjc/data/ResettableIterator.java @@ -5,12 +5,12 @@ import java.util.*; /* * @TODO Oct 6, 2020 - Ben Culkin - :CleverCache * - * In the future, there are certain efficencies we could take with our cached + * In the future, there are certain efficiencies we could take with our cached * elements; namely, the case where we repeat the same element multiple times, * or the case where we have a mixture of identical (and probably sizable) elements * - * The general downside to these of course, is that these efficencies would cost - * us something in terms of complexity, as well as not benefitting iterators which + * The general downside to these of course, is that these efficiencies would cost + * us something in terms of complexity, as well as not benefiting iterators which * aren't large enough. * * Still an interesting thought as to the best way to implement such a thing though. @@ -57,7 +57,7 @@ public class ResettableIterator<T> implements Iterator<T> { @Override public boolean hasNext() { if (isRepeating) return cacheIterator.hasNext() ? true : backing.hasNext(); - else return backing.hasNext(); + return backing.hasNext(); } @Override @@ -65,10 +65,10 @@ public class ResettableIterator<T> implements Iterator<T> { if (isRepeating) { if (cacheIterator.hasNext()) { return cacheIterator.next(); - } else { - cacheIterator = null; - isRepeating = false; } + + cacheIterator = null; + isRepeating = false; } T itm = backing.next(); |
