From f7d477442be8ec80e92ecf7e12d576c604c42c1e Mon Sep 17 00:00:00 2001 From: Klemek Date: Wed, 21 Feb 2018 18:55:58 +0100 Subject: [PATCH] Initial commit v1.0 --- .gitignore | 4 + README.md | 195 ++++++++ download/betterlists-1.0-sources.jar | Bin 0 -> 45811 bytes download/betterlists-1.0.jar | Bin 0 -> 20525 bytes .../klemek/betterlists/BetterArrayList.java | 83 +++ .../klemek/betterlists/BetterLinkedList.java | 74 +++ src/fr/klemek/betterlists/BetterList.java | 471 ++++++++++++++++++ src/fr/klemek/betterlists/BetterStack.java | 51 ++ src/fr/klemek/betterlists/BetterVector.java | 100 ++++ .../klemek/betterlists/BetterListsTests.java | 334 +++++++++++++ 10 files changed, 1312 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 download/betterlists-1.0-sources.jar create mode 100644 download/betterlists-1.0.jar create mode 100644 src/fr/klemek/betterlists/BetterArrayList.java create mode 100644 src/fr/klemek/betterlists/BetterLinkedList.java create mode 100644 src/fr/klemek/betterlists/BetterList.java create mode 100644 src/fr/klemek/betterlists/BetterStack.java create mode 100644 src/fr/klemek/betterlists/BetterVector.java create mode 100644 test/fr/klemek/betterlists/BetterListsTests.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..924c569 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/bin/ +/.classpath +/.project +/.settings/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2a0a3a --- /dev/null +++ b/README.md @@ -0,0 +1,195 @@ +# BetterLists (by Klemek) + +An extension of the java.util.List interface which include some of the C# LINQ useful functions. + +List classes are extended as well. (ArrayList -> BetterArrayList) + +Current version v1.0 + +Before BetterLists : +```Java +ArrayList contacts = someFunction(); + +ArrayList contactsEmails = new ArrayList<>(); +for(int i = 5; i < contacts.size(); i++){ + if(c.getEmail() != null){ + contactsEmails.add(c.getEmail()); + } +} +``` +With BetterLists : +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +BetterList contactsEmails = contacts.skip(5) + .where(c -> c.getEmail() != null) + .select(c -> c.getEmail()); +``` + +NOTE : Please note that, unlike C# LINQ, these functions are not optimized at low levels and will have the same impact as standard loops in your program. + +## Download + +* [betterlists-1.0.jar](../../raw/master/download/betterlists-1.0.jar) +* [betterlists-1.0-sources.jar](../../raw/master/download/betterlists-1.0-sources.jar) + +## All code examples +### List + +| Name | Description | +| :- | :- | +| [all](#all) | Determines whether all elements of the sequence satisfy a condition. | +| [any](#any) | Determines whether any element of the sequence satisfies a condition. | +| [count](#count) | Returns a number that represents how many elements in the specified sequence satisfy a condition. | +| [exclusion](#exclusion) | Produces the set exclusion of two sequences. | +| [first / firstOrDefault](#first-firstordefault) | Returns the first element in the sequence that satisfies a specified condition. (Returns an error if no elements match the condition unless you use the firstOrDefault function) | +| [last / lastOrDefault](#last-lastordefault) | Returns the last element in the sequence that satisfies a specified condition. (Returns an error if no elements match the condition unless you use the lastOrDefault function) | +| [max](#max) | Invokes a transform function on each element of the sequence and returns the maximum nullable Double value. | +| [mean](#mean) | Computes the mean of the sequence of Double values that are obtained by invoking a transform function on each element of the input sequence. | +| [min](#min) | Invokes a transform function on each element of the sequence and returns the minimum nullable Double value. | +| [orderBy / orderByDescending](#orderby-orderbydescending) | Sorts the elements of a sequence in ascending order by using a specified comparer. (You can user orderByDescending to change the order) | +| [reverse](#reverse) | Inverts the order of the elements in the sequence. | +| [select](#select) | Projects each element of a sequence into a new form. | +| [skip / skipWhile](#skip-skipwhile) | Bypasses elements in the sequence as long as a specified condition is true and then returns the remaining elements. | +| [sum](#sum) | Computes the sum of the sequence of Double values that are obtained by invoking a transform function on each element of the input sequence. | +| [take / takeWhile](#take-takewhile) | Returns a specified number of contiguous elements from the start of the sequence. | +| [union](#union) | Produces the set union of two sequences. | +| [where](#where) | Filters a sequence of values based on a predicate. | + +### all +Determines whether all elements of the sequence satisfy a condition. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +boolean allAdults = contacts.all(c -> c.getAge() >= 21); +``` + +### any +Determines whether any element of the sequence satisfies a condition. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +boolean someUnderage = contacts.any(c -> c.getAge() < 21); +``` + +### count +Returns a number that represents how many elements in the specified sequence satisfy a condition. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +int adultsCount = contacts.count(c -> c.getAge() >= 21); +``` + +### exclusion +Produces the set exclusion of two sequences. +```Java +BetterArrayList frenchContacts = BetterArrayList.fromList(someFunction()); +ArrayList validContacts = someOtherFunction(); + +BetterList invalidFrenchContacts = frenchContacts.exclusion(validContacts); +``` + +### first / firstOrDefault +Returns the first element in the sequence that satisfies a specified condition. (Returns an error if no elements match the condition unless you use the `firstOrDefault` function) +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +Contact firstManager = contacts.first(c -> c.isManager()); +``` + +### last / lastOrDefault +Returns the last element in the sequence that satisfies a specified condition. (Returns an error if no elements match the condition unless you use the `lastOrDefault` function) +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +Contact lastRegular = contacts.last(c -> !c.isManager()); +``` + +### max +Invokes a transform function on each element of the sequence and returns the maximum nullable Double value. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +int maxAge = (int)contacts.max(c -> (double)c.getAge()); +``` + +### mean +Computes the mean of the sequence of Double values that are obtained by invoking a transform function on each element of the input sequence. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +int meanAge = (int)contacts.mean(c -> (double)c.getAge()); +``` + +### min +Invokes a transform function on each element of the sequence and returns the minimum nullable Double value. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +int minAge = (int)contacts.min(c -> (double)c.getAge()); +``` + +### orderBy / orderByDescending +Sorts the elements of a sequence in ascending order by using a specified comparer. (You can user `orderByDescending` to change the order) +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +BetterList orderedContacts = contacts.orderBy(c -> c.getName); +``` + +### reverse +Inverts the order of the elements in the sequence. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +BetterList reversedContacts = contacts.reverse(); +``` + +### select +Projects each element of a sequence into a new form. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +BetterList contactsMails = contacts.select(c -> c.getEmail()); +``` + +### skip / skipWhile +Bypasses elements in the sequence as long as a specified condition is true and then returns the remaining elements. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +BetterList contacts2 = contacts.skipWhile(c -> c.getEmail().startsWith("society")); +``` + +### sum +Computes the sum of the sequence of Double values that are obtained by invoking a transform function on each element of the input sequence. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +double salary = contacts.skip(c -> c.getSalary()); +``` + +### take / takeWhile +Returns a specified number of contiguous elements from the start of the sequence. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +BetterList contacts2 = contacts.takeWhile(c -> c.getEmail().startsWith("society")); +``` + +### union +Produces the set union of two sequences. +```Java +BetterArrayList frenchContacts = BetterArrayList.fromList(someFunction()); +ArrayList validContacts = someOtherFunction(); + +BetterList validFrenchContacts = frenchContacts.union(validContacts); +``` + +### where +Filters a sequence of values based on a predicate. +```Java +BetterArrayList contacts = BetterArrayList.fromList(someFunction()); + +BetterList validContacts = contacts.where(c -> c.getEmail() != null); +``` \ No newline at end of file diff --git a/download/betterlists-1.0-sources.jar b/download/betterlists-1.0-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..8c8ede1ca7fa53be382833b75467297c4afed4f6 GIT binary patch literal 45811 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 O{C5Y4=tG~PU;iJ|%ib#h literal 0 HcmV?d00001 diff --git a/download/betterlists-1.0.jar b/download/betterlists-1.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..3e5c29f616d318138d61d8948d64e3c4c41cf65e GIT binary patch literal 20525 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 PFu=w1D)gs&guneC{Biq! literal 0 HcmV?d00001 diff --git a/src/fr/klemek/betterlists/BetterArrayList.java b/src/fr/klemek/betterlists/BetterArrayList.java new file mode 100644 index 0000000..9e33fbe --- /dev/null +++ b/src/fr/klemek/betterlists/BetterArrayList.java @@ -0,0 +1,83 @@ +package fr.klemek.betterlists; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * An extension of the java.util.ArrayList class which include some of the C# + * LINQ useful functions. + * + * @author Klemek + * + * @see java.util.ArrayList + */ +public class BetterArrayList extends ArrayList implements BetterList { + + private static final long serialVersionUID = 4772544470059394618L; + + /** + * Constructs a list containing the elements of the specified collection, in the + * order they are returned by the collection's iterator. + * + * @param c + * - the collection whose elements are to be placed into this list + */ + public static BetterArrayList fromList(Collection c) { + return new BetterArrayList(c); + } + + /** + * Constructs an empty list with an initial capacity of ten. + */ + public BetterArrayList() { + super(); + } + + /** + * Constructs a list containing the elements of the specified collection, in the + * order they are returned by the collection's iterator. + * + * @param c + * - the collection whose elements are to be placed into this list + */ + public BetterArrayList(Collection c) { + super(c); + } + + /** + * Constructs an empty list with the specified initial capacity. + * + * @param initialCapacity + * - the initial capacity of the list + */ + public BetterArrayList(int initialCapacity) { + super(initialCapacity); + } + + /** + * Returns a view of the portion of this list between the specified fromIndex, + * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the + * returned list is empty.) The returned list is backed by this list, so + * non-structural changes in the returned list are reflected in this list, and + * vice-versa. The returned list supports all of the optional list operations + * supported by this list. This method eliminates the need for explicit range + * operations (of the sort that commonly exist for arrays). Any operation that + * expects a list can be used as a range operation by passing a subList view + * instead of a whole list. (see List.subList) + * + * @param fromIndex + * - low endpoint (inclusive) of the subList + * @param toIndex + * - high endpoint (exclusive) of the subList + * @return a view of the specified range within this list + * @throws IndexOutOfBoundsException + * for an illegal endpoint index value (fromIndex < 0 || toIndex > + * size || fromIndex > toIndex) + * @see java.util.List + */ + @Override + public BetterArrayList subList(int fromIndex, int toIndex) { + return (BetterArrayList) ((List) this).subList(fromIndex, toIndex); + } +} diff --git a/src/fr/klemek/betterlists/BetterLinkedList.java b/src/fr/klemek/betterlists/BetterLinkedList.java new file mode 100644 index 0000000..33fa469 --- /dev/null +++ b/src/fr/klemek/betterlists/BetterLinkedList.java @@ -0,0 +1,74 @@ +package fr.klemek.betterlists; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +/** + * An extension of the java.util.LinkedList class which include some of the C# + * LINQ useful functions. + * + * @author Klemek + * + * @see java.util.LinkedList + */ +public class BetterLinkedList extends LinkedList implements BetterList { + + private static final long serialVersionUID = 4837198308074701770L; + + /** + * Constructs a list containing the elements of the specified collection, in the + * order they are returned by the collection's iterator. + * + * @param c + * - the collection whose elements are to be placed into this list + */ + public static BetterLinkedList fromList(Collection c) { + return new BetterLinkedList(c); + } + + /** + * Constructs an empty list. + */ + public BetterLinkedList() { + super(); + } + + /** + * Constructs a list containing the elements of the specified collection, in the + * order they are returned by the collection's iterator. + * + * @param c + * - the collection whose elements are to be placed into this list + */ + public BetterLinkedList(Collection c) { + super(c); + } + + /** + * Returns a view of the portion of this list between the specified fromIndex, + * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the + * returned list is empty.) The returned list is backed by this list, so + * non-structural changes in the returned list are reflected in this list, and + * vice-versa. The returned list supports all of the optional list operations + * supported by this list. This method eliminates the need for explicit range + * operations (of the sort that commonly exist for arrays). Any operation that + * expects a list can be used as a range operation by passing a subList view + * instead of a whole list. (see List.subList) + * + * @param fromIndex + * - low endpoint (inclusive) of the subList + * @param toIndex + * - high endpoint (exclusive) of the subList + * @return a view of the specified range within this list + * @throws IndexOutOfBoundsException + * for an illegal endpoint index value (fromIndex < 0 || toIndex > + * size || fromIndex > toIndex) + * @see java.util.List + */ + @Override + public BetterLinkedList subList(int fromIndex, int toIndex) { + return (BetterLinkedList) ((List) this).subList(fromIndex, toIndex); + } + +} diff --git a/src/fr/klemek/betterlists/BetterList.java b/src/fr/klemek/betterlists/BetterList.java new file mode 100644 index 0000000..b520011 --- /dev/null +++ b/src/fr/klemek/betterlists/BetterList.java @@ -0,0 +1,471 @@ +package fr.klemek.betterlists; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.function.Function; + +/** + * An extension of the java.util.List interface which include some of the C# + * LINQ useful functions. + * + * @author Klemek + * + * @see java.util.List + */ +public interface BetterList extends List { + + /** + * Determines whether all elements of the sequence satisfy a condition. + * + * @param predicate + * - A function to test each element for a condition. + * @return true if every element of the source sequence passes the test in the + * specified predicate, or if the sequence is empty; otherwise, false. + */ + public default boolean all(Function predicate) { + for (T element : this) + if (!predicate.apply(element)) + return false; + return true; + } + + /** + * Determines whether any element of the sequence satisfies a condition. + * + * @param predicate + * - A function to test each element for a condition. + * @return true if any elements in the source sequence pass the test in the + * specified predicate; otherwise, false. + */ + public default boolean any(Function predicate) { + for (T element : this) + if (predicate.apply(element)) + return true; + return false; + } + + /** + * Returns the number of elements in the sequence. + * + * @return The number of elements in the input sequence. + */ + public default int count() { + return count(e -> true); + } + + /** + * Returns a number that represents how many elements in the specified sequence + * satisfy a condition. + * + * @param predicate + * - A function to test each element for a condition. + * @return A number that represents how many elements in the sequence satisfy + * the condition in the predicate function. + */ + public default int count(Function predicate) { + int out = 0; + for (T element : this) + if (predicate.apply(element)) + out++; + return out; + } + + /** + * Produces the set exclusion of two sequences. + * + * @param other + * - Another List whose distinct elements form the second set for the + * exclusion. + * @return A List that contains the elements from the first sequence not present + * in the other. + */ + public default BetterList exclusion(List other) { + BetterList out = new BetterArrayList(); + for (T element : this) + if (!other.contains(element)) + out.add(element); + return out; + } + + /** + * Returns the first element in the sequence. + * + * @throws NoSuchElementException + * If the sequence is empty. + * @return The first element in the sequence. + */ + public default T first() { + return first(e -> true); + } + + /** + * Returns the first element in the sequence that satisfies a specified + * condition. + * + * @param predicate + * - A function to test each element for a condition. + * @throws NoSuchElementException + * No element satisfies the condition in predicate or the sequence + * is empty. + * @return The first element in the sequence that passes the test in the + * specified predicate function. + */ + public default T first(Function predicate) { + for (T element : this) + if (predicate.apply(element)) + return element; + throw new NoSuchElementException(); + } + + /** + * Returns the first element of the sequence that satisfies a condition or the + * default value if no such element is found. + * + * @param predicate + * - A function to test each element for a condition. + * @param defaultValue + * - A default value to be returned if no element passes the test + * @return defaultValue if the sequence is empty or if no element passes the + * test specified by predicate; otherwise, the first element in the + * sequence that passes the test specified by predicate. + */ + public default T firstOrDefault(Function predicate, T defaultValue) { + for (T element : this) + if (predicate.apply(element)) + return element; + return defaultValue; + } + + /** + * Returns the first element of the sequence or a default value if the sequence + * is empty. + * + * @param defaultValue + * - A default value to be returned if the sequence is empty + * @return defaultValue if the sequence is empty otherwise, the first element in + * the sequence. + */ + public default T firstOrDefault(T defaultValue) { + return firstOrDefault(e -> true, defaultValue); + } + + /** + * Returns the last element of the sequence. + * + * @throws NoSuchElementException + * If the sequence is empty. + * @return the last element of the sequence. + */ + public default T last() { + return last(e -> true); + } + + /** + * Returns the last element of the sequence that satisfies a specified + * condition. + * + * @param predicate + * - A function to test each element for a condition. + * @throws NoSuchElementException + * No element satisfies the condition in predicate or the sequence + * is empty. + * @return the last element of the sequence that satisfies a specified + * condition. + */ + public default T last(Function predicate) { + T value = null; + for (T element : this) + if (predicate.apply(element)) + value = element; + if (value == null) + throw new NoSuchElementException(); + return value; + } + + /** + * Returns the last element of the sequence that satisfies a condition or the + * default value if no such element is found. + * + * @param predicate + * - A function to test each element for a condition. + * @param defaultValue + * - A default value to be returned if no element passes the test + * @return defaultValue if the sequence is empty or if no element passes the + * test specified by predicate; otherwise, the last element in the + * sequence that passes the test specified by predicate. + */ + public default T lastOrDefault(Function predicate, T defaultValue) { + T value = null; + for (T element : this) + if (predicate.apply(element)) + value = element; + return value == null ? defaultValue : value; + } + + /** + * Returns the last element of the sequence or a default value if the sequence + * is empty. + * + * @param defaultValue + * - A default value to be returned if the sequence is empty + * @return defaultValue if the sequence is empty otherwise, the last element in + * the sequence. + */ + public default T lastOrDefault(T defaultValue) { + return lastOrDefault(e -> true, defaultValue); + } + + /** + * Invokes a transform function on each element of the sequence and returns the + * maximum nullable Double value. + * + * @param selector + * - A transform function to apply to each element. + * @return The value of type Double that corresponds to the maximum value in the + * sequence or null if the sequence is empty. + */ + public default Double max(Function selector) { + Double max = null; + for (T element : this) + if (max == null || selector.apply(element) > max) + max = selector.apply(element); + return max; + } + + /** + * Computes the mean of the sequence of Double values that are obtained by + * invoking a transform function on each element of the input sequence. + * + * @param selector + * - A transform function to apply to each element. + * @return The mean of the projected values. Null if the sequence contains no + * elements. + */ + public default Double mean(Function selector) { + int count = this.count(); + if (count == 0) + return null; + return this.sum(selector) / this.count(); + } + + /** + * Invokes a transform function on each element of the sequence and returns the + * minimum nullable Double value. + * + * @param selector + * - A transform function to apply to each element. + * @return The value of type Double that corresponds to the minimum value in the + * sequence or null if the sequence is empty. + */ + public default Double min(Function selector) { + Double min = null; + for (T element : this) + if (min == null || selector.apply(element) < min) + min = selector.apply(element); + return min; + } + + /** + * Sorts the elements of a sequence in ascending order by using a specified comparer. + * @param selector + * - A transform function to apply to each element. + * @return a List whose elements are sorted according to a key. + */ + public default > BetterList orderBy(Function selector){ + BetterList out = new BetterArrayList(); + out.addAll(this); + Collections.sort(out, new Comparator() { + + @Override + public int compare(T o1, T o2) { + return selector.apply(o1).compareTo(selector.apply(o2)); + } + + }); + return out; + } + + /** + * Sorts the elements of a sequence in descending order by using a specified comparer. + * @param selector + * - A transform function to apply to each element. + * @return a List whose elements are sorted according to a key. + */ + public default > BetterList orderByDescending(Function selector){ + BetterList out = new BetterArrayList(); + out.addAll(this); + Collections.sort(out, new Comparator() { + + @Override + public int compare(T o1, T o2) { + return selector.apply(o2).compareTo(selector.apply(o1)); + } + + }); + return out; + } + + /** + * Inverts the order of the elements in the sequence. + * + * @return A sequence whose elements correspond to those of the sequence in + * reverse order. + */ + public default BetterList reverse() { + BetterList out = new BetterArrayList(); + for (T element : this) + out.add(0, element); + return out; + } + + /** + * Projects each element of a sequence into a new form. + * + * @param + * The type of the projected values + * @param selector + * - A transform function to apply to each element. + * @return A List whose elements are the result of invoking the transform + * function on each element of the sequence. + */ + public default BetterList select(Function selector) { + BetterList out = new BetterArrayList(); + for (T element : this) + out.add(selector.apply(element)); + return out; + } + + /** + * Bypasses a specified number of elements in the sequence and then returns the + * remaining elements. + * + * @param count + * - The number of elements to skip before returning the remaining + * elements. + * @return a List that contains the elements that occur after the specified + * index in the sequence. + */ + public default BetterList skip(int count) { + BetterList out = new BetterArrayList(); + int n = 0; + for (T element : this) { + if (n >= count) + out.add(element); + n++; + } + return out; + } + + /** + * Bypasses elements in the sequence as long as a specified condition is true + * and then returns the remaining elements. + * + * @param predicate + * - A function to test each element for a condition. + * @return a List that contains the elements from the sequence starting at the + * first element in the linear series that does not pass the test + * specified by predicate. + */ + public default BetterList skipWhile(Function predicate) { + BetterList out = new BetterArrayList(); + boolean match = true; + for (T element : this) + if (!match || !predicate.apply(element)) { + match = false; + out.add(element); + } + return out; + } + + /** + * Computes the sum of the sequence of Double values that are obtained by + * invoking a transform function on each element of the input sequence. + * + * @param selector + * - A transform function to apply to each element. + * @return The sum of the projected values. Zero if the sequence contains no + * elements. + */ + public default Double sum(Function selector) { + double sum = 0d; + for (T element : this) + sum += selector.apply(element); + return sum; + } + + /** + * Returns a specified number of contiguous elements from the start of the + * sequence. + * + * @param count + * - The number of elements to return. + * @return a List that contains the specified number of elements from the start + * of the input sequence. + */ + public default BetterList take(int count) { + BetterList out = new BetterArrayList(); + int n = 0; + for (T element : this) { + if (n < count) + out.add(element); + else + break; + n++; + } + return out; + } + + /** + * Returns elements from the sequence as long as a specified condition is true. + * + * @param predicate + * - A function to test each element for a condition. + * @return a List that contains the elements from the sequence that occur before + * the element at which the test no longer passes. + */ + public default BetterList takeWhile(Function predicate) { + BetterList out = new BetterArrayList(); + for (T element : this) + if (predicate.apply(element)) + out.add(element); + else + break; + return out; + } + + /** + * Produces the set union of two sequences. + * + * @param other + * - Another List whose distinct elements form the second set for the + * union. + * @return A List that contains the elements from both sequences, excluding + * duplicates. + */ + public default BetterList union(List other) { + BetterList out = new BetterArrayList(); + for (T element : this) + if (other.contains(element)) + out.add(element); + return out; + } + + /** + * Filters a sequence of values based on a predicate. + * + * @param predicate + * - A function to test each element for a condition. + * @return a List that contains elements from the sequence that satisfy the + * condition. + */ + public default BetterList where(Function predicate) { + BetterList out = new BetterArrayList(); + for (T element : this) + if (predicate.apply(element)) + out.add(element); + return out; + } + +} diff --git a/src/fr/klemek/betterlists/BetterStack.java b/src/fr/klemek/betterlists/BetterStack.java new file mode 100644 index 0000000..f33c967 --- /dev/null +++ b/src/fr/klemek/betterlists/BetterStack.java @@ -0,0 +1,51 @@ +package fr.klemek.betterlists; + +import java.util.List; +import java.util.Stack; + +/** + * An extension of the java.util.Stack class which include some of the C# LINQ + * useful functions. + * + * @author Klemek + * + * @see java.util.Stack + */ +public class BetterStack extends Stack implements BetterList { + + private static final long serialVersionUID = 5642889973315247461L; + + /** + * Creates an empty Stack. + */ + public BetterStack() { + super(); + } + + /** + * Returns a view of the portion of this list between the specified fromIndex, + * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the + * returned list is empty.) The returned list is backed by this list, so + * non-structural changes in the returned list are reflected in this list, and + * vice-versa. The returned list supports all of the optional list operations + * supported by this list. This method eliminates the need for explicit range + * operations (of the sort that commonly exist for arrays). Any operation that + * expects a list can be used as a range operation by passing a subList view + * instead of a whole list. (see List.subList) + * + * @param fromIndex + * - low endpoint (inclusive) of the subList + * @param toIndex + * - high endpoint (exclusive) of the subList + * @return a view of the specified range within this list + * @throws IndexOutOfBoundsException + * for an illegal endpoint index value (fromIndex < 0 || toIndex > + * size || fromIndex > toIndex) + * @see java.util.List + */ + @Override + public BetterStack subList(int fromIndex, int toIndex) { + return (BetterStack) ((List) this).subList(fromIndex, toIndex); + } + +} diff --git a/src/fr/klemek/betterlists/BetterVector.java b/src/fr/klemek/betterlists/BetterVector.java new file mode 100644 index 0000000..fddf1bf --- /dev/null +++ b/src/fr/klemek/betterlists/BetterVector.java @@ -0,0 +1,100 @@ +package fr.klemek.betterlists; + +import java.util.Collection; +import java.util.List; +import java.util.Vector; + +/** + * An extension of the java.util.Vector class which include some of the C# LINQ + * useful functions. + * + * @author Klemek + * + * @see java.util.Vector + */ +public class BetterVector extends Vector implements BetterList { + + private static final long serialVersionUID = -704157461726911759L; + + /** + * Constructs a vector containing the elements of the specified collection, in + * the order they are returned by the collection's iterator. + * + * @param c + * - the collection whose elements are to be placed into this vector + */ + public static BetterVector fromList(Collection c) { + return new BetterVector(c); + } + + /** + * Constructs an empty vector so that its internal data array has size 10 and + * its standard capacity increment is zero. + */ + public BetterVector() { + super(); + } + + /** + * Constructs a vector containing the elements of the specified collection, in + * the order they are returned by the collection's iterator. + * + * @param c + * - the collection whose elements are to be placed into this vector + */ + public BetterVector(Collection c) { + super(c); + } + + /** + * Constructs an empty vector with the specified initial capacity and with its + * capacity increment equal to zero. + * + * @param initialCapacity + * - the initial capacity of the vector + */ + public BetterVector(int initialCapacity) { + super(initialCapacity); + } + + /** + * Constructs an empty vector with the specified initial capacity and capacity + * increment. + * + * @param initialCapacity + * - the initial capacity of the vector + * @param capacityIncrement + * - the amount by which the capacity is increased when the vector + * overflows + */ + public BetterVector(int initialCapacity, int capacityIncrement) { + super(initialCapacity, capacityIncrement); + } + + /** + * Returns a view of the portion of this list between the specified fromIndex, + * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the + * returned list is empty.) The returned list is backed by this list, so + * non-structural changes in the returned list are reflected in this list, and + * vice-versa. The returned list supports all of the optional list operations + * supported by this list. This method eliminates the need for explicit range + * operations (of the sort that commonly exist for arrays). Any operation that + * expects a list can be used as a range operation by passing a subList view + * instead of a whole list. (see List.subList) + * + * @param fromIndex + * - low endpoint (inclusive) of the subList + * @param toIndex + * - high endpoint (exclusive) of the subList + * @return a view of the specified range within this list + * @throws IndexOutOfBoundsException + * for an illegal endpoint index value (fromIndex < 0 || toIndex > + * size || fromIndex > toIndex) + * @see java.util.List + */ + @Override + public BetterVector subList(int fromIndex, int toIndex) { + return (BetterVector) ((List) this).subList(fromIndex, toIndex); + } + +} diff --git a/test/fr/klemek/betterlists/BetterListsTests.java b/test/fr/klemek/betterlists/BetterListsTests.java new file mode 100644 index 0000000..8f9e90a --- /dev/null +++ b/test/fr/klemek/betterlists/BetterListsTests.java @@ -0,0 +1,334 @@ +package fr.klemek.betterlists; + +import java.util.ArrayList; +import java.util.NoSuchElementException; + +import org.junit.Assert; +import org.junit.Test; + +public class BetterListsTests { + + protected class Dummy { + double d; + String s; + + public Dummy(double d, String s) { + this.d = d; + this.s = s; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Dummy other = (Dummy) obj; + if (!getOuterType().equals(other.getOuterType())) + return false; + if (Double.doubleToLongBits(d) != Double.doubleToLongBits(other.d)) + return false; + if (s == null) { + if (other.s != null) + return false; + } else if (!s.equals(other.s)) + return false; + return true; + } + + private BetterListsTests getOuterType() { + return BetterListsTests.this; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getOuterType().hashCode(); + long temp; + temp = Double.doubleToLongBits(d); + result = prime * result + (int) (temp ^ (temp >>> 32)); + result = prime * result + ((s == null) ? 0 : s.hashCode()); + return result; + } + } + + @Test + public void testAll() { + ArrayList al = new ArrayList(); + al.add(new Dummy(1d,"hello")); + al.add(new Dummy(2d,"test")); + al.add(new Dummy(2d,"hello")); + + BetterArrayList bal = BetterArrayList.fromList(al); + + Assert.assertTrue(bal.all(du -> du.d > 0)); + Assert.assertFalse(bal.all(du -> du.d > 1)); + } + + @Test + public void testAny() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(2d,"hello")); + + Assert.assertTrue(bal.any(du -> du.s.startsWith("t"))); + Assert.assertFalse(bal.any(du -> du.s.startsWith("b"))); + } + + @Test + public void testCount() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(2d,"hello")); + + Assert.assertEquals(3, bal.count()); + Assert.assertEquals(2, bal.count(du -> du.s.length() > 4)); + } + + @Test + public void testExclude() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello")); + bal1.add(new Dummy(2d,"test")); + bal1.add(new Dummy(3d,"hello")); + bal1.add(new Dummy(4d,"test")); + + BetterArrayList bal2 = new BetterArrayList(); + bal2.add(new Dummy(2d,"test")); + bal2.add(new Dummy(3d,"hello")); + bal2.add(new Dummy(5d,"test")); + + BetterArrayList bal3 = (BetterArrayList) bal1.exclusion(bal2); + Assert.assertEquals(2, bal3.size()); + Assert.assertEquals(bal1.get(0), bal3.get(0)); + Assert.assertEquals(bal1.get(3), bal3.get(1)); + } + + @Test + public void testFirst() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(2d,"hello")); + + Assert.assertEquals(bal.get(0), bal.first(du -> du.s.startsWith("h"))); + + try { + bal.first(du -> du.s.startsWith("d")); + Assert.fail("no error"); + } catch (NoSuchElementException e) { + } + + Assert.assertEquals(bal.get(0), bal.firstOrDefault(du -> du.s.startsWith("h"), new Dummy(3d,"default"))); + + Assert.assertEquals(new Dummy(3d,"default"), bal.firstOrDefault(du -> du.s.startsWith("d"), new Dummy(3d,"default"))); + } + + @Test + public void testLast() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(2d,"hello")); + + Assert.assertEquals(bal.get(2), bal.last(du -> du.s.startsWith("h"))); + + try { + bal.last(du -> du.s.startsWith("d")); + Assert.fail("no error"); + } catch (NoSuchElementException e) { + } + + Assert.assertEquals(bal.get(2), bal.lastOrDefault(du -> du.s.startsWith("h"), new Dummy(3d,"default"))); + + Assert.assertEquals(new Dummy(3d,"default"), bal.lastOrDefault(du -> du.s.startsWith("d"), new Dummy(3d,"default"))); + } + + @Test + public void testMax() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(3d,"hello2")); + + Assert.assertEquals(6d, bal.max(du -> (double)du.s.length()), 0.001d); + } + + @Test + public void testMean() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(3d,"hello2")); + + Assert.assertEquals(5d, bal.mean(du -> (double)du.s.length()), 0.001d); + } + + @Test + public void testMin() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(3d,"hello2")); + + Assert.assertEquals(4d, bal.min(du -> (double)du.s.length()), 0.001d); + } + + @Test + public void testOrderBy() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello1")); + bal1.add(new Dummy(2d,"hello2")); + bal1.add(new Dummy(3d,"hello0")); + bal1.add(new Dummy(4d,"test")); + bal1.add(new Dummy(5d,"hello4")); + + BetterArrayList bal2 = (BetterArrayList) bal1.orderBy(c -> c.s); + Assert.assertNotEquals(bal1, bal2); + Assert.assertEquals(bal1.get(2), bal2.get(0)); + Assert.assertEquals(bal1.get(0), bal2.get(1)); + Assert.assertEquals(bal1.get(1), bal2.get(2)); + Assert.assertEquals(bal1.get(4), bal2.get(3)); + Assert.assertEquals(bal1.get(3), bal2.get(4)); + } + + @Test + public void testOrderByDescending() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello1")); + bal1.add(new Dummy(2d,"hello2")); + bal1.add(new Dummy(3d,"hello0")); + bal1.add(new Dummy(4d,"test")); + bal1.add(new Dummy(5d,"hello4")); + + BetterArrayList bal2 = (BetterArrayList) bal1.orderByDescending(c -> c.d); + Assert.assertNotEquals(bal1, bal2); + for(int i = 0; i < 5; i++) + Assert.assertEquals(bal1.get(4-i), bal2.get(i)); + } + + @Test + public void testReverse() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello")); + bal1.add(new Dummy(2d,"hello")); + bal1.add(new Dummy(3d,"hello")); + bal1.add(new Dummy(4d,"test")); + bal1.add(new Dummy(5d,"hello")); + + BetterArrayList bal2 = (BetterArrayList) bal1.reverse(); + Assert.assertEquals(5, bal2.size()); + for(int i = 0; i < 5; i++) + Assert.assertEquals(bal1.get(i), bal2.get(4-i)); + } + + @Test + public void testSelect() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello")); + bal1.add(new Dummy(2d,"hello")); + bal1.add(new Dummy(3d,"hello")); + bal1.add(new Dummy(4d,"test")); + bal1.add(new Dummy(5d,"hello")); + + BetterArrayList bal2 = (BetterArrayList) bal1.select(du -> du.d); + Assert.assertEquals(5, bal2.size()); + for(int i = 0; i < 5; i++) + Assert.assertEquals(bal1.get(i).d, bal2.get(i), 0.0001); + } + + @Test + public void testSkip() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello")); + bal1.add(new Dummy(2d,"hello")); + bal1.add(new Dummy(3d,"hello")); + bal1.add(new Dummy(4d,"test")); + bal1.add(new Dummy(5d,"hello")); + + Assert.assertEquals(bal1, bal1.skip(0)); + Assert.assertEquals(0, bal1.skip(10).size()); + + BetterArrayList bal2 = (BetterArrayList) bal1.skip(2); + Assert.assertEquals(3, bal2.size()); + for(int i = 0; i < 3; i++) + Assert.assertEquals(bal1.get(i+2), bal2.get(i)); + + BetterArrayList bal3 = (BetterArrayList) bal1.skipWhile(du -> du.s.startsWith("h")); + Assert.assertEquals(2, bal3.size()); + for(int i = 0; i < 2; i++) + Assert.assertEquals(bal1.get(i+3), bal3.get(i)); + } + + @Test + public void testSum() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(3d,"hello2")); + + Assert.assertEquals(6d, bal.sum(du -> du.d), 0.001d); + } + + @Test + public void testTake() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello")); + bal1.add(new Dummy(2d,"hello")); + bal1.add(new Dummy(3d,"hello")); + bal1.add(new Dummy(4d,"test")); + bal1.add(new Dummy(5d,"hello")); + + Assert.assertEquals(bal1, bal1.take(10)); + + Assert.assertEquals(0, bal1.take(0).size()); + + BetterArrayList bal2 = (BetterArrayList) bal1.take(2); + Assert.assertEquals(2, bal2.size()); + for(int i = 0; i < 2; i++) + Assert.assertEquals(bal1.get(i), bal2.get(i)); + + BetterArrayList bal3 = (BetterArrayList) bal1.takeWhile(du -> du.s.startsWith("h")); + Assert.assertEquals(3, bal3.size()); + for(int i = 0; i < 3; i++) + Assert.assertEquals(bal1.get(i), bal3.get(i)); + } + + @Test + public void testUnion() { + BetterArrayList bal1 = new BetterArrayList(); + bal1.add(new Dummy(1d,"hello")); + bal1.add(new Dummy(2d,"test")); + bal1.add(new Dummy(3d,"hello")); + bal1.add(new Dummy(4d,"test")); + + BetterArrayList bal2 = new BetterArrayList(); + bal2.add(new Dummy(2d,"test")); + bal2.add(new Dummy(3d,"hello")); + bal2.add(new Dummy(5d,"test")); + + BetterArrayList bal3 = (BetterArrayList) bal1.union(bal2); + Assert.assertEquals(2, bal3.size()); + Assert.assertEquals(bal1.get(1), bal3.get(0)); + Assert.assertEquals(bal1.get(2), bal3.get(1)); + } + + @Test + public void testWhere() { + BetterArrayList bal = new BetterArrayList(); + bal.add(new Dummy(1d,"hello")); + bal.add(new Dummy(2d,"test")); + bal.add(new Dummy(3d,"hello")); + + BetterArrayList bal2 = (BetterArrayList) bal.where(du -> du.s.startsWith("h")); + + Assert.assertEquals(2, bal2.size()); + Assert.assertEquals(new Dummy(1d,"hello"), bal2.get(0)); + Assert.assertEquals(new Dummy(3d,"hello"), bal2.get(1)); + } +}