diff options
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java')
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java | 199 |
1 files changed, 140 insertions, 59 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java index 73ace88..88db172 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java @@ -13,16 +13,19 @@ import java.util.function.Function; import java.util.function.Predicate; import bjc.utils.data.GenHolder; +import bjc.utils.data.Pair; /** - * A wrapper over another list that provides eager functional operations over it. - * Differs from a stream in every way except for the fact that they both provide functional - * operations. + * A wrapper over another list that provides eager functional operations + * over it. Differs from a stream in every way except for the fact that + * they both provide functional operations. + * * @author ben * - * @param <E> The type in this list + * @param <E> + * The type in this list */ -public class FunctionalList<E> { +public class FunctionalList<E> implements Cloneable { private List<E> wrap; /** @@ -34,7 +37,9 @@ public class FunctionalList<E> { /** * Create a new functional list containing the specified items. - * @param items The items to put into this functional list. + * + * @param items + * The items to put into this functional list. */ @SafeVarargs public FunctionalList(E... items) { @@ -46,26 +51,32 @@ public class FunctionalList<E> { } /** - * Create a functional list using the same backing list as the provided list. + * Create a functional list using the same backing list as the provided + * list. * - * @param fl The source for a backing list + * @param fl + * The source for a backing list */ - public FunctionalList(FunctionalList<E> fl) { + public FunctionalList(FunctionalList<E> fl) { // TODO Find out if this should make a copy of fl.wrap instead. wrap = fl.wrap; } /** * Create a new functional list with the specified size. - * @param sz The size of the backing list . + * + * @param sz + * The size of the backing list . */ private FunctionalList(int sz) { wrap = new ArrayList<>(sz); } - + /** * Create a new functional list as a wrapper of a existing list. - * @param l The list to use as a backing list. + * + * @param l + * The list to use as a backing list. */ public FunctionalList(List<E> l) { wrap = l; @@ -73,17 +84,31 @@ public class FunctionalList<E> { /** * Add an item to this list - * @param item The item to add to this list. + * + * @param item + * The item to add to this list. * @return Whether the item was added to the list succesfully. */ public boolean add(E item) { return wrap.add(item); } + + /** + * Prepend an item to the list + * @param item The item to prepend to the list + */ + public void prepend(E item) { + wrap.add(0, item); + } /** - * Check if all of the elements of this list match the specified predicate. - * @param p The predicate to use for checking. - * @return Whether all of the elements of the list match the specified predicate. + * Check if all of the elements of this list match the specified + * predicate. + * + * @param p + * The predicate to use for checking. + * @return Whether all of the elements of the list match the specified + * predicate. */ public boolean allMatch(Predicate<E> p) { for (E item : wrap) { @@ -96,8 +121,11 @@ public class FunctionalList<E> { /** * Check if any of the elements in this list match the specified list. - * @param p The predicate to use for checking. - * @return Whether any element in the list matches the provided predicate. + * + * @param p + * The predicate to use for checking. + * @return Whether any element in the list matches the provided + * predicate. */ public boolean anyMatch(Predicate<E> p) { for (E item : wrap) { @@ -109,29 +137,36 @@ public class FunctionalList<E> { } /** - * Combine this list with another one into a new list and merge the results. - * Works sort of like a combined zip/map over resulting pairs. - * Does not change the underlying list. + * Combine this list with another one into a new list and merge the + * results. Works sort of like a combined zip/map over resulting pairs. + * Does not change the underlying list. + * + * NOTE: The returned list will have the length of the shorter of this + * list and the combined one. * - * NOTE: The returned list will have the length of the shorter of this list and the combined one. - * @param l The list to combine with - * @param bf The function to use for combining element pairs. + * @param l + * The list to combine with + * @param bf + * The function to use for combining element pairs. * @return A new list containing the merged pairs of lists. */ - public <T, F> FunctionalList<F> combineWith(FunctionalList<T> l, BiFunction<E, T, F> bf) { + public <T, F> FunctionalList<F> combineWith(FunctionalList<T> l, + BiFunction<E, T, F> bf) { FunctionalList<F> r = new FunctionalList<>(); - + Iterator<T> i2 = l.wrap.iterator(); - - for (Iterator<E> i1 = wrap.iterator(); i1.hasNext() && i2.hasNext();) { + + for (Iterator<E> i1 = wrap.iterator(); i1.hasNext() + && i2.hasNext();) { r.add(bf.apply(i1.next(), i2.next())); } - + return r; } /** * Get the first element in the list + * * @return The first element in this list. */ public E first() { @@ -139,10 +174,13 @@ public class FunctionalList<E> { } /** - * Apply a function to each member of the list, then flatten the results. - * Does not change the underlying list. - * @param f The function to apply to each member of the list. - * @return A new list containing the flattened results of applying the provided function. + * Apply a function to each member of the list, then flatten the + * results. Does not change the underlying list. + * + * @param f + * The function to apply to each member of the list. + * @return A new list containing the flattened results of applying the + * provided function. */ public <T> FunctionalList<T> flatMap(Function<E, List<T>> f) { FunctionalList<T> fl = new FunctionalList<>(this.wrap.size()); @@ -158,7 +196,9 @@ public class FunctionalList<E> { /** * Apply a given action for each member of the list - * @param c The action to apply to each member of the list. + * + * @param c + * The action to apply to each member of the list. */ public void forEach(Consumer<E> c) { wrap.forEach(c); @@ -166,7 +206,10 @@ public class FunctionalList<E> { /** * Apply a given function to each element in the list and its index. - * @param c The function to apply to each element in the list and its index. + * + * @param c + * The function to apply to each element in the list and its + * index. */ public void forEachIndexed(BiConsumer<Integer, E> c) { int i = 0; @@ -178,7 +221,9 @@ public class FunctionalList<E> { /** * Retrieve a value in the list by its index. - * @param i The index to retrieve a value from. + * + * @param i + * The index to retrieve a value from. * @return The value at the specified index in the list. */ public E getByIndex(int i) { @@ -187,6 +232,7 @@ public class FunctionalList<E> { /** * Get the internal backing list. + * * @return The backing list this list is based off of. */ public List<E> getInternal() { @@ -195,6 +241,7 @@ public class FunctionalList<E> { /** * Check if this list is empty. + * * @return Whether or not this list is empty. */ public boolean isEmpty() { @@ -202,9 +249,11 @@ public class FunctionalList<E> { } /** - * Create a new list by applying the given function to each element in the list. - * Does not change the underlying list. - * @param f The function to apply to each element in the list + * Create a new list by applying the given function to each element in + * the list. Does not change the underlying list. + * + * @param f + * The function to apply to each element in the list * @return A new list containing the mapped elements of this list. */ public <T> FunctionalList<T> map(Function<E, T> f) { @@ -216,8 +265,11 @@ public class FunctionalList<E> { } /** - * Select a random item from this list, using the provided random number generator. - * @param rnd The random number generator to use. + * Select a random item from this list, using the provided random + * number generator. + * + * @param rnd + * The random number generator to use. * @return A random element from this list. */ public E randItem(Random rnd) { @@ -226,27 +278,38 @@ public class FunctionalList<E> { /** * Reduce this list to a single value, using a accumulative approach. - * @param val The initial value of the accumulative state. - * @param bf The function to use to combine a list element with the accumulative state. - * @param finl The function to use to convert the accumulative state into a final result. - * @return A single value condensed from this list and transformed into its final state. + * + * @param val + * The initial value of the accumulative state. + * @param bf + * The function to use to combine a list element with the + * accumulative state. + * @param finl + * The function to use to convert the accumulative state + * into a final result. + * @return A single value condensed from this list and transformed into + * its final state. */ - public <T, F> F reduceAux(T val, BiFunction<E, T, T> bf, Function<T, F> finl) { + public <T, F> F reduceAux(T val, BiFunction<E, T, T> bf, + Function<T, F> finl) { GenHolder<T> acum = new GenHolder<>(val); - + wrap.forEach(e -> { acum.held = bf.apply(e, acum.held); }); - + return finl.apply(acum.held); } /** - * Perform a binary search for the specified key using the provided means of - * comparing elements. - * Since this IS a binary search, the list must have been sorted before hand. - * @param key The key to search for. - * @param cmp The way to compare elements for searching + * Perform a binary search for the specified key using the provided + * means of comparing elements. Since this IS a binary search, the list + * must have been sorted before hand. + * + * @param key + * The key to search for. + * @param cmp + * The way to compare elements for searching * @return The element if it is in this list, or null if it is not. */ public E search(E key, Comparator<E> cmp) { @@ -254,19 +317,22 @@ public class FunctionalList<E> { return (res >= 0) ? wrap.get(res) : null; } - + /** - * Sort the elements of this list using the provided way of comparing elements. - * Does change the underlying list. - * @param cmp The way to compare elements for sorting. + * Sort the elements of this list using the provided way of comparing + * elements. Does change the underlying list. + * + * @param cmp + * The way to compare elements for sorting. */ public void sort(Comparator<E> cmp) { Collections.sort(wrap, cmp); } - + /* * Reduce this item to a form useful for looking at in the debugger. * (non-Javadoc) + * * @see java.lang.Object#toString() */ public String toString() { @@ -274,9 +340,24 @@ public class FunctionalList<E> { forEach(s -> sb.append(s + ", ")); - sb.deleteCharAt(sb.length()); + sb.deleteCharAt(sb.length() - 1); sb.append(")"); return sb.toString(); } + + public <T> FunctionalList<Pair<E, T>> pairWith(FunctionalList<T> fl) { + return combineWith(fl, Pair<E, T>::new); + } + + @Override + public FunctionalList<E> clone() { + FunctionalList<E> fl = new FunctionalList<>(); + + for (E ele : wrap) { + fl.add(ele); + } + + return fl; + } } |
