Added maven framework

This commit is contained in:
Klemek
2018-08-30 21:22:06 +01:00
parent 9b634f226e
commit bcf6d395d4
9 changed files with 869 additions and 795 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
/out/ /target/
/maven-repo.bat /maven-repo.bat
/.idea/ /.idea/
*.iml *.iml
+75
View File
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.klemek</groupId>
<artifactId>betterlists</artifactId>
<version>1.4</version>
<name>BetterLists</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<outputDirectory>target/${project.artifactId}/WEB-INF/classes</outputDirectory>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<!-- Notify plugin/dependecies updates -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>display-dependency-updates</goal>
<goal>display-plugin-updates</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Compilation -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<outputDirectory>download</outputDirectory>
</configuration>
</plugin>
<!-- Unit tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</build>
</project>
@@ -1,94 +1,94 @@
package fr.klemek.betterlists; package fr.klemek.betterlists;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
/** /**
* An extension of the java.util.ArrayList class which include some of the C# * An extension of the java.util.ArrayList class which include some of the C#
* LINQ useful functions. * LINQ useful functions.
* *
* @author Klemek * @author Klemek
* @see java.util.ArrayList * @see java.util.ArrayList
*/ */
public class BetterArrayList<T> extends ArrayList<T> implements BetterList<T> { public class BetterArrayList<T> extends ArrayList<T> implements BetterList<T> {
private static final long serialVersionUID = 4772544470059394618L; private static final long serialVersionUID = 4772544470059394618L;
/** /**
* Constructs a list containing the elements of the specified collection, in the * Constructs a list containing the elements of the specified collection, in the
* order they are returned by the collection's iterator. * order they are returned by the collection's iterator.
* *
* @param c - the collection whose elements are to be placed into this list * @param c - the collection whose elements are to be placed into this list
*/ */
public static <T> BetterArrayList<T> fromList(Collection<T> c) { public static <T> BetterArrayList<T> fromList(Collection<T> c) {
return new BetterArrayList<>(c); return new BetterArrayList<>(c);
} }
/** /**
* Constructs a list containing the elements given in argument. * Constructs a list containing the elements given in argument.
* *
* @param a - the elements to be placed into this list * @param a - the elements to be placed into this list
*/ */
public static <T> BetterArrayList<T> asList(T... a) { public static <T> BetterArrayList<T> asList(T... a) {
return new BetterArrayList<>(a); return new BetterArrayList<>(a);
} }
/** /**
* Constructs an empty list with an initial capacity of ten. * Constructs an empty list with an initial capacity of ten.
*/ */
public BetterArrayList() { public BetterArrayList() {
super(); super();
} }
/** /**
* Constructs a list containing the elements of the specified collection, in the * Constructs a list containing the elements of the specified collection, in the
* order they are returned by the collection's iterator. * order they are returned by the collection's iterator.
* *
* @param c - the collection whose elements are to be placed into this list * @param c - the collection whose elements are to be placed into this list
*/ */
public BetterArrayList(Collection<? extends T> c) { public BetterArrayList(Collection<? extends T> c) {
super(c); super(c);
} }
/** /**
* Constructs a list containing the elements given in argument. * Constructs a list containing the elements given in argument.
* *
* @param a - the elements to be placed into this list * @param a - the elements to be placed into this list
*/ */
public BetterArrayList(T... a) { public BetterArrayList(T... a) {
super(Arrays.asList(a)); super(Arrays.asList(a));
} }
/** /**
* Constructs an empty list with the specified initial capacity. * Constructs an empty list with the specified initial capacity.
* *
* @param initialCapacity - the initial capacity of the list * @param initialCapacity - the initial capacity of the list
*/ */
public BetterArrayList(int initialCapacity) { public BetterArrayList(int initialCapacity) {
super(initialCapacity); super(initialCapacity);
} }
/** /**
* Returns a view of the portion of this list between the specified fromIndex, * Returns a view of the portion of this list between the specified fromIndex,
* inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the
* returned list is empty.) The returned list is backed by this list, so * 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 * 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 * vice-versa. The returned list supports all of the optional list operations
* supported by this list. This method eliminates the need for explicit range * supported by this list. This method eliminates the need for explicit range
* operations (of the sort that commonly exist for arrays). Any operation that * 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 * expects a list can be used as a range operation by passing a subList view
* instead of a whole list. (see List.subList) * instead of a whole list. (see List.subList)
* *
* @param fromIndex - low endpoint (inclusive) of the subList * @param fromIndex - low endpoint (inclusive) of the subList
* @param toIndex - high endpoint (exclusive) of the subList * @param toIndex - high endpoint (exclusive) of the subList
* @return a view of the specified range within this list * @return a view of the specified range within this list
* @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex > * @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex >
* size || fromIndex > toIndex) * size || fromIndex > toIndex)
* @see java.util.List * @see java.util.List
*/ */
@Override @Override
public BetterArrayList<T> subList(int fromIndex, int toIndex) { public BetterArrayList<T> subList(int fromIndex, int toIndex) {
return (BetterArrayList<T>) super.subList(fromIndex, toIndex); return (BetterArrayList<T>) super.subList(fromIndex, toIndex);
} }
} }
@@ -1,86 +1,86 @@
package fr.klemek.betterlists; package fr.klemek.betterlists;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
/** /**
* An extension of the java.util.LinkedList class which include some of the C# * An extension of the java.util.LinkedList class which include some of the C#
* LINQ useful functions. * LINQ useful functions.
* *
* @author Klemek * @author Klemek
* @see java.util.LinkedList * @see java.util.LinkedList
*/ */
public class BetterLinkedList<T> extends LinkedList<T> implements BetterList<T> { public class BetterLinkedList<T> extends LinkedList<T> implements BetterList<T> {
private static final long serialVersionUID = 4837198308074701770L; private static final long serialVersionUID = 4837198308074701770L;
/** /**
* Constructs a list containing the elements of the specified collection, in the * Constructs a list containing the elements of the specified collection, in the
* order they are returned by the collection's iterator. * order they are returned by the collection's iterator.
* *
* @param c - the collection whose elements are to be placed into this list * @param c - the collection whose elements are to be placed into this list
*/ */
public static <T> BetterLinkedList<T> fromList(Collection<T> c) { public static <T> BetterLinkedList<T> fromList(Collection<T> c) {
return new BetterLinkedList<>(c); return new BetterLinkedList<>(c);
} }
/** /**
* Constructs a list containing the elements given in argument. * Constructs a list containing the elements given in argument.
* *
* @param a - the elements to be placed into this list * @param a - the elements to be placed into this list
*/ */
public static <T> BetterLinkedList<T> asList(T... a) { public static <T> BetterLinkedList<T> asList(T... a) {
return new BetterLinkedList<>(a); return new BetterLinkedList<>(a);
} }
/** /**
* Constructs an empty list. * Constructs an empty list.
*/ */
public BetterLinkedList() { public BetterLinkedList() {
super(); super();
} }
/** /**
* Constructs a list containing the elements of the specified collection, in the * Constructs a list containing the elements of the specified collection, in the
* order they are returned by the collection's iterator. * order they are returned by the collection's iterator.
* *
* @param c - the collection whose elements are to be placed into this list * @param c - the collection whose elements are to be placed into this list
*/ */
public BetterLinkedList(Collection<? extends T> c) { public BetterLinkedList(Collection<? extends T> c) {
super(c); super(c);
} }
/** /**
* Constructs a list containing the elements given in argument. * Constructs a list containing the elements given in argument.
* *
* @param a - the elements to be placed into this list * @param a - the elements to be placed into this list
*/ */
public BetterLinkedList(T... a) { public BetterLinkedList(T... a) {
super(Arrays.asList(a)); super(Arrays.asList(a));
} }
/** /**
* Returns a view of the portion of this list between the specified fromIndex, * Returns a view of the portion of this list between the specified fromIndex,
* inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the
* returned list is empty.) The returned list is backed by this list, so * 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 * 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 * vice-versa. The returned list supports all of the optional list operations
* supported by this list. This method eliminates the need for explicit range * supported by this list. This method eliminates the need for explicit range
* operations (of the sort that commonly exist for arrays). Any operation that * 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 * expects a list can be used as a range operation by passing a subList view
* instead of a whole list. (see List.subList) * instead of a whole list. (see List.subList)
* *
* @param fromIndex - low endpoint (inclusive) of the subList * @param fromIndex - low endpoint (inclusive) of the subList
* @param toIndex - high endpoint (exclusive) of the subList * @param toIndex - high endpoint (exclusive) of the subList
* @return a view of the specified range within this list * @return a view of the specified range within this list
* @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex > * @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex >
* size || fromIndex > toIndex) * size || fromIndex > toIndex)
* @see java.util.List * @see java.util.List
*/ */
@Override @Override
public BetterLinkedList<T> subList(int fromIndex, int toIndex) { public BetterLinkedList<T> subList(int fromIndex, int toIndex) {
return (BetterLinkedList<T>) super.subList(fromIndex, toIndex); return (BetterLinkedList<T>) super.subList(fromIndex, toIndex);
} }
} }
@@ -1,457 +1,457 @@
package fr.klemek.betterlists; package fr.klemek.betterlists;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
/** /**
* An extension of the java.util.List interface which include some of the C# * An extension of the java.util.List interface which include some of the C#
* LINQ useful functions. * LINQ useful functions.
* *
* @author Klemek * @author Klemek
* @see java.util.List * @see java.util.List
*/ */
public interface BetterList<T> extends List<T> { public interface BetterList<T> extends List<T> {
/** /**
* Determines whether all elements of the sequence satisfy a condition. * Determines whether all elements of the sequence satisfy a condition.
* *
* @param predicate - A function to test each element for 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 * @return true if every element of the source sequence passes the test in the
* specified predicate, or if the sequence is empty; otherwise, false. * specified predicate, or if the sequence is empty; otherwise, false.
*/ */
default boolean all(Function<T, Boolean> predicate) { default boolean all(Function<T, Boolean> predicate) {
for (T element : this) for (T element : this)
if (!predicate.apply(element)) if (!predicate.apply(element))
return false; return false;
return true; return true;
} }
/** /**
* Determines whether any element of the sequence satisfies a condition. * Determines whether any element of the sequence satisfies a condition.
* *
* @param predicate - A function to test each element for 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 * @return true if any elements in the source sequence pass the test in the
* specified predicate; otherwise, false. * specified predicate; otherwise, false.
*/ */
default boolean any(Function<T, Boolean> predicate) { default boolean any(Function<T, Boolean> predicate) {
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
return true; return true;
return false; return false;
} }
/** /**
* Returns the number of elements in the sequence. * Returns the number of elements in the sequence.
* *
* @return The number of elements in the input sequence. * @return The number of elements in the input sequence.
*/ */
default int count() { default int count() {
return count(e -> true); return count(e -> true);
} }
/** /**
* Returns a number that represents how many elements in the specified sequence * Returns a number that represents how many elements in the specified sequence
* satisfy a condition. * satisfy a condition.
* *
* @param predicate - A function to test each element for 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 * @return A number that represents how many elements in the sequence satisfy
* the condition in the predicate function. * the condition in the predicate function.
*/ */
default int count(Function<T, Boolean> predicate) { default int count(Function<T, Boolean> predicate) {
int out = 0; int out = 0;
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
out++; out++;
return out; return out;
} }
/** /**
* Produces the set exclusion of two sequences. * Produces the set exclusion of two sequences.
* *
* @param other - Another List whose distinct elements form the second set for the * @param other - Another List whose distinct elements form the second set for the
* exclusion. * exclusion.
* @return A List that contains the elements from the first sequence not present * @return A List that contains the elements from the first sequence not present
* in the other. * in the other.
*/ */
default BetterList<T> exclusion(List<T> other) { default BetterList<T> exclusion(List<T> other) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
for (T element : this) for (T element : this)
if (!other.contains(element)) if (!other.contains(element))
out.add(element); out.add(element);
return out; return out;
} }
/** /**
* Returns the first element in the sequence. * Returns the first element in the sequence.
* *
* @return The first element in the sequence. * @return The first element in the sequence.
* @throws NoSuchElementException If the sequence is empty. * @throws NoSuchElementException If the sequence is empty.
*/ */
default T first() { default T first() {
return first(e -> true); return first(e -> true);
} }
/** /**
* Returns the first element in the sequence that satisfies a specified * Returns the first element in the sequence that satisfies a specified
* condition. * condition.
* *
* @param predicate - A function to test each element for a condition. * @param predicate - A function to test each element for a condition.
* @return The first element in the sequence that passes the test in the * @return The first element in the sequence that passes the test in the
* specified predicate function. * specified predicate function.
* @throws NoSuchElementException No element satisfies the condition in predicate or the sequence * @throws NoSuchElementException No element satisfies the condition in predicate or the sequence
* is empty. * is empty.
*/ */
default T first(Function<T, Boolean> predicate) { default T first(Function<T, Boolean> predicate) {
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
return element; return element;
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
/** /**
* Returns the first element of the sequence that satisfies a condition or the * Returns the first element of the sequence that satisfies a condition or the
* default value if no such element is found. * default value if no such element is found.
* *
* @param predicate - A function to test each element for a condition. * @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 * @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 * @return defaultValue if the sequence is empty or if no element passes the
* test specified by predicate; otherwise, the first element in the * test specified by predicate; otherwise, the first element in the
* sequence that passes the test specified by predicate. * sequence that passes the test specified by predicate.
*/ */
default T firstOrDefault(Function<T, Boolean> predicate, T defaultValue) { default T firstOrDefault(Function<T, Boolean> predicate, T defaultValue) {
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
return element; return element;
return defaultValue; return defaultValue;
} }
/** /**
* Returns the first element of the sequence or a default value if the sequence * Returns the first element of the sequence or a default value if the sequence
* is empty. * is empty.
* *
* @param defaultValue - A default value to be returned 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 * @return defaultValue if the sequence is empty otherwise, the first element in
* the sequence. * the sequence.
*/ */
default T firstOrDefault(T defaultValue) { default T firstOrDefault(T defaultValue) {
return firstOrDefault(e -> true, defaultValue); return firstOrDefault(e -> true, defaultValue);
} }
/** /**
* Returns the last element of the sequence. * Returns the last element of the sequence.
* *
* @return the last element of the sequence. * @return the last element of the sequence.
* @throws NoSuchElementException If the sequence is empty. * @throws NoSuchElementException If the sequence is empty.
*/ */
default T last() { default T last() {
return last(e -> true); return last(e -> true);
} }
/** /**
* Returns the last element of the sequence that satisfies a specified * Returns the last element of the sequence that satisfies a specified
* condition. * condition.
* *
* @param predicate - A function to test each element for a condition. * @param predicate - A function to test each element for a condition.
* @return the last element of the sequence that satisfies a specified * @return the last element of the sequence that satisfies a specified
* condition. * condition.
* @throws NoSuchElementException No element satisfies the condition in predicate or the sequence * @throws NoSuchElementException No element satisfies the condition in predicate or the sequence
* is empty. * is empty.
*/ */
default T last(Function<T, Boolean> predicate) { default T last(Function<T, Boolean> predicate) {
T value = null; T value = null;
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
value = element; value = element;
if (value == null) if (value == null)
throw new NoSuchElementException(); throw new NoSuchElementException();
return value; return value;
} }
/** /**
* Returns the last element of the sequence that satisfies a condition or the * Returns the last element of the sequence that satisfies a condition or the
* default value if no such element is found. * default value if no such element is found.
* *
* @param predicate - A function to test each element for a condition. * @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 * @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 * @return defaultValue if the sequence is empty or if no element passes the
* test specified by predicate; otherwise, the last element in the * test specified by predicate; otherwise, the last element in the
* sequence that passes the test specified by predicate. * sequence that passes the test specified by predicate.
*/ */
default T lastOrDefault(Function<T, Boolean> predicate, T defaultValue) { default T lastOrDefault(Function<T, Boolean> predicate, T defaultValue) {
T value = null; T value = null;
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
value = element; value = element;
return value == null ? defaultValue : value; return value == null ? defaultValue : value;
} }
/** /**
* Returns the last element of the sequence or a default value if the sequence * Returns the last element of the sequence or a default value if the sequence
* is empty. * is empty.
* *
* @param defaultValue - A default value to be returned 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 * @return defaultValue if the sequence is empty otherwise, the last element in
* the sequence. * the sequence.
*/ */
default T lastOrDefault(T defaultValue) { default T lastOrDefault(T defaultValue) {
return lastOrDefault(e -> true, defaultValue); return lastOrDefault(e -> true, defaultValue);
} }
/** /**
* Invokes a transform function on each element of the sequence and returns the * Invokes a transform function on each element of the sequence and returns the
* maximum nullable Double value. * maximum nullable Double value.
* *
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return The value of type Double that corresponds to the maximum value in the * @return The value of type Double that corresponds to the maximum value in the
* sequence or null if the sequence is empty. * sequence or null if the sequence is empty.
*/ */
default Double max(Function<T, Double> selector) { default Double max(Function<T, Double> selector) {
Double max = null; Double max = null;
for (T element : this) for (T element : this)
if (max == null || selector.apply(element) > max) if (max == null || selector.apply(element) > max)
max = selector.apply(element); max = selector.apply(element);
return max; return max;
} }
/** /**
* Computes the mean of the sequence of Double values that are obtained by * Computes the mean of the sequence of Double values that are obtained by
* invoking a transform function on each element of the input sequence. * invoking a transform function on each element of the input sequence.
* *
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return The mean of the projected values. Null if the sequence contains no * @return The mean of the projected values. Null if the sequence contains no
* elements. * elements.
*/ */
default Double mean(Function<T, Double> selector) { default Double mean(Function<T, Double> selector) {
int count = this.count(); int count = this.count();
if (count == 0) if (count == 0)
return null; return null;
return this.sum(selector) / this.count(); return this.sum(selector) / this.count();
} }
/** /**
* Invokes a transform function on each element of the sequence and returns the * Invokes a transform function on each element of the sequence and returns the
* minimum nullable Double value. * minimum nullable Double value.
* *
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return The value of type Double that corresponds to the minimum value in the * @return The value of type Double that corresponds to the minimum value in the
* sequence or null if the sequence is empty. * sequence or null if the sequence is empty.
*/ */
default Double min(Function<T, Double> selector) { default Double min(Function<T, Double> selector) {
Double min = null; Double min = null;
for (T element : this) for (T element : this)
if (min == null || selector.apply(element) < min) if (min == null || selector.apply(element) < min)
min = selector.apply(element); min = selector.apply(element);
return min; return min;
} }
/** /**
* Sorts the elements of a sequence in ascending order by using a specified comparer. * Sorts the elements of a sequence in ascending order by using a specified comparer.
* *
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return a List whose elements are sorted according to a key. * @return a List whose elements are sorted according to a key.
*/ */
default <E extends Comparable<E>> BetterList<T> orderBy(Function<T, E> selector) { default <E extends Comparable<E>> BetterList<T> orderBy(Function<T, E> selector) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
out.addAll(this); out.addAll(this);
Collections.sort(out, (o1, o2) -> selector.apply(o1).compareTo(selector.apply(o2))); Collections.sort(out, (o1, o2) -> selector.apply(o1).compareTo(selector.apply(o2)));
return out; return out;
} }
/** /**
* Sorts the elements of a sequence in descending order by using a specified comparer. * Sorts the elements of a sequence in descending order by using a specified comparer.
* *
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return a List whose elements are sorted according to a key. * @return a List whose elements are sorted according to a key.
*/ */
default <E extends Comparable<E>> BetterList<T> orderByDescending(Function<T, E> selector) { default <E extends Comparable<E>> BetterList<T> orderByDescending(Function<T, E> selector) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
out.addAll(this); out.addAll(this);
Collections.sort(out, (o1, o2) -> selector.apply(o2).compareTo(selector.apply(o1))); Collections.sort(out, (o1, o2) -> selector.apply(o2).compareTo(selector.apply(o1)));
return out; return out;
} }
/** /**
* Inverts the order of the elements in the sequence. * Inverts the order of the elements in the sequence.
* *
* @return A sequence whose elements correspond to those of the sequence in * @return A sequence whose elements correspond to those of the sequence in
* reverse order. * reverse order.
*/ */
default BetterList<T> reverse() { default BetterList<T> reverse() {
BetterList<T> out = new BetterArrayList<>(this.size()); BetterList<T> out = new BetterArrayList<>(this.size());
for (T element : this) for (T element : this)
out.add(0, element); out.add(0, element);
return out; return out;
} }
/** /**
* Projects each element of a sequence into a new form. * Projects each element of a sequence into a new form.
* *
* @param <E> The type of the projected values * @param <E> The type of the projected values
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return A List whose elements are the result of invoking the transform * @return A List whose elements are the result of invoking the transform
* function on each element of the sequence. * function on each element of the sequence.
*/ */
default <E> BetterList<E> select(Function<T, E> selector) { default <E> BetterList<E> select(Function<T, E> selector) {
BetterList<E> out = new BetterArrayList<>(); BetterList<E> out = new BetterArrayList<>();
for (T element : this) for (T element : this)
out.add(selector.apply(element)); out.add(selector.apply(element));
return out; return out;
} }
/** /**
* Projects each element of a sequence into a new list and flattens the * Projects each element of a sequence into a new list and flattens the
* resulting sequences into one sequence. * resulting sequences into one sequence.
* *
* @param <E> The type of the projected values lists * @param <E> The type of the projected values lists
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return A List whose elements are the result of invoking the one-to-many * @return A List whose elements are the result of invoking the one-to-many
* transform function on each element of the input sequence. * transform function on each element of the input sequence.
*/ */
default <E> BetterList<E> selectMany(Function<T, Collection<? extends E>> selector) { default <E> BetterList<E> selectMany(Function<T, Collection<? extends E>> selector) {
BetterList<E> out = new BetterArrayList<>(); BetterList<E> out = new BetterArrayList<>();
for (T element : this) for (T element : this)
out.addAll(selector.apply(element)); out.addAll(selector.apply(element));
return out; return out;
} }
/** /**
* Projects each element of a sequence into a new list and flattens the * Projects each element of a sequence into a new list and flattens the
* resulting sequences into one sequence. * resulting sequences into one sequence.
* *
* @param <E> The type of the projected values lists * @param <E> The type of the projected values lists
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return A List whose elements are the result of invoking the one-to-many * @return A List whose elements are the result of invoking the one-to-many
* transform function on each element of the input sequence. * transform function on each element of the input sequence.
*/ */
default <E> BetterList<E> selectManyArrays(Function<T, E[]> selector) { default <E> BetterList<E> selectManyArrays(Function<T, E[]> selector) {
BetterList<E> out = new BetterArrayList<>(); BetterList<E> out = new BetterArrayList<>();
for (T element : this) for (T element : this)
out.addAll(Arrays.asList(selector.apply(element))); out.addAll(Arrays.asList(selector.apply(element)));
return out; return out;
} }
/** /**
* Bypasses a specified number of elements in the sequence and then returns the * Bypasses a specified number of elements in the sequence and then returns the
* remaining elements. * remaining elements.
* *
* @param count - The number of elements to skip before returning the remaining * @param count - The number of elements to skip before returning the remaining
* elements. * elements.
* @return a List that contains the elements that occur after the specified * @return a List that contains the elements that occur after the specified
* index in the sequence. * index in the sequence.
*/ */
default BetterList<T> skip(int count) { default BetterList<T> skip(int count) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
int n = 0; int n = 0;
for (T element : this) { for (T element : this) {
if (n >= count) if (n >= count)
out.add(element); out.add(element);
n++; n++;
} }
return out; return out;
} }
/** /**
* Bypasses elements in the sequence as long as a specified condition is true * Bypasses elements in the sequence as long as a specified condition is true
* and then returns the remaining elements. * and then returns the remaining elements.
* *
* @param predicate - A function to test each element for a condition. * @param predicate - A function to test each element for a condition.
* @return a List that contains the elements from the sequence starting at the * @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 * first element in the linear series that does not pass the test
* specified by predicate. * specified by predicate.
*/ */
default BetterList<T> skipWhile(Function<T, Boolean> predicate) { default BetterList<T> skipWhile(Function<T, Boolean> predicate) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
boolean match = true; boolean match = true;
for (T element : this) for (T element : this)
if (!match || !predicate.apply(element)) { if (!match || !predicate.apply(element)) {
match = false; match = false;
out.add(element); out.add(element);
} }
return out; return out;
} }
/** /**
* Computes the sum of the sequence of Double values that are obtained by * Computes the sum of the sequence of Double values that are obtained by
* invoking a transform function on each element of the input sequence. * invoking a transform function on each element of the input sequence.
* *
* @param selector - A transform function to apply to each element. * @param selector - A transform function to apply to each element.
* @return The sum of the projected values. Zero if the sequence contains no * @return The sum of the projected values. Zero if the sequence contains no
* elements. * elements.
*/ */
default Double sum(Function<T, Double> selector) { default Double sum(Function<T, Double> selector) {
double sum = 0d; double sum = 0d;
for (T element : this) for (T element : this)
sum += selector.apply(element); sum += selector.apply(element);
return sum; return sum;
} }
/** /**
* Returns a specified number of contiguous elements from the start of the * Returns a specified number of contiguous elements from the start of the
* sequence. * sequence.
* *
* @param count - The number of elements to return. * @param count - The number of elements to return.
* @return a List that contains the specified number of elements from the start * @return a List that contains the specified number of elements from the start
* of the input sequence. * of the input sequence.
*/ */
default BetterList<T> take(int count) { default BetterList<T> take(int count) {
BetterList<T> out = new BetterArrayList<>(count); BetterList<T> out = new BetterArrayList<>(count);
int n = 0; int n = 0;
for (T element : this) { for (T element : this) {
if (n < count) if (n < count)
out.add(element); out.add(element);
else else
break; break;
n++; n++;
} }
return out; return out;
} }
/** /**
* Returns elements from the sequence as long as a specified condition is true. * Returns elements from the sequence as long as a specified condition is true.
* *
* @param predicate - A function to test each element for a condition. * @param predicate - A function to test each element for a condition.
* @return a List that contains the elements from the sequence that occur before * @return a List that contains the elements from the sequence that occur before
* the element at which the test no longer passes. * the element at which the test no longer passes.
*/ */
default BetterList<T> takeWhile(Function<T, Boolean> predicate) { default BetterList<T> takeWhile(Function<T, Boolean> predicate) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
out.add(element); out.add(element);
else else
break; break;
return out; return out;
} }
/** /**
* Produces the set union of two sequences. * Produces the set union of two sequences.
* *
* @param other - Another List whose distinct elements form the second set for the * @param other - Another List whose distinct elements form the second set for the
* union. * union.
* @return A List that contains the elements from both sequences, excluding * @return A List that contains the elements from both sequences, excluding
* duplicates. * duplicates.
*/ */
default BetterList<T> union(List<T> other) { default BetterList<T> union(List<T> other) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
for (T element : this) for (T element : this)
if (other.contains(element)) if (other.contains(element))
out.add(element); out.add(element);
return out; return out;
} }
/** /**
* Filters a sequence of values based on a predicate. * Filters a sequence of values based on a predicate.
* *
* @param predicate - A function to test each element for a condition. * @param predicate - A function to test each element for a condition.
* @return a List that contains elements from the sequence that satisfy the * @return a List that contains elements from the sequence that satisfy the
* condition. * condition.
*/ */
default BetterList<T> where(Function<T, Boolean> predicate) { default BetterList<T> where(Function<T, Boolean> predicate) {
BetterList<T> out = new BetterArrayList<>(); BetterList<T> out = new BetterArrayList<>();
for (T element : this) for (T element : this)
if (predicate.apply(element)) if (predicate.apply(element))
out.add(element); out.add(element);
return out; return out;
} }
} }
@@ -1,46 +1,46 @@
package fr.klemek.betterlists; package fr.klemek.betterlists;
import java.util.Stack; import java.util.Stack;
/** /**
* An extension of the java.util.Stack class which include some of the C# LINQ * An extension of the java.util.Stack class which include some of the C# LINQ
* useful functions. * useful functions.
* *
* @author Klemek * @author Klemek
* @see java.util.Stack * @see java.util.Stack
*/ */
public class BetterStack<T> extends Stack<T> implements BetterList<T> { public class BetterStack<T> extends Stack<T> implements BetterList<T> {
private static final long serialVersionUID = 5642889973315247461L; private static final long serialVersionUID = 5642889973315247461L;
/** /**
* Creates an empty Stack. * Creates an empty Stack.
*/ */
public BetterStack() { public BetterStack() {
super(); super();
} }
/** /**
* Returns a view of the portion of this list between the specified fromIndex, * Returns a view of the portion of this list between the specified fromIndex,
* inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the
* returned list is empty.) The returned list is backed by this list, so * 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 * 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 * vice-versa. The returned list supports all of the optional list operations
* supported by this list. This method eliminates the need for explicit range * supported by this list. This method eliminates the need for explicit range
* operations (of the sort that commonly exist for arrays). Any operation that * 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 * expects a list can be used as a range operation by passing a subList view
* instead of a whole list. (see List.subList) * instead of a whole list. (see List.subList)
* *
* @param fromIndex - low endpoint (inclusive) of the subList * @param fromIndex - low endpoint (inclusive) of the subList
* @param toIndex - high endpoint (exclusive) of the subList * @param toIndex - high endpoint (exclusive) of the subList
* @return a view of the specified range within this list * @return a view of the specified range within this list
* @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex > * @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex >
* size || fromIndex > toIndex) * size || fromIndex > toIndex)
* @see java.util.List * @see java.util.List
*/ */
@Override @Override
public BetterStack<T> subList(int fromIndex, int toIndex) { public BetterStack<T> subList(int fromIndex, int toIndex) {
return (BetterStack<T>) super.subList(fromIndex, toIndex); return (BetterStack<T>) super.subList(fromIndex, toIndex);
} }
} }
@@ -1,109 +1,109 @@
package fr.klemek.betterlists; package fr.klemek.betterlists;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Vector; import java.util.Vector;
/** /**
* An extension of the java.util.Vector class which include some of the C# LINQ * An extension of the java.util.Vector class which include some of the C# LINQ
* useful functions. * useful functions.
* *
* @author Klemek * @author Klemek
* @see java.util.Vector * @see java.util.Vector
*/ */
public class BetterVector<T> extends Vector<T> implements BetterList<T> { public class BetterVector<T> extends Vector<T> implements BetterList<T> {
private static final long serialVersionUID = -704157461726911759L; private static final long serialVersionUID = -704157461726911759L;
/** /**
* Constructs a vector containing the elements of the specified collection, in * Constructs a vector containing the elements of the specified collection, in
* the order they are returned by the collection's iterator. * the order they are returned by the collection's iterator.
* *
* @param c - the collection whose elements are to be placed into this vector * @param c - the collection whose elements are to be placed into this vector
*/ */
public static <T> BetterVector<T> fromList(Collection<T> c) { public static <T> BetterVector<T> fromList(Collection<T> c) {
return new BetterVector<>(c); return new BetterVector<>(c);
} }
/** /**
* Constructs a vector containing the elements given in argument. * Constructs a vector containing the elements given in argument.
* *
* @param a - the elements to be placed into this vector * @param a - the elements to be placed into this vector
*/ */
public static <T> BetterVector<T> asVector(T... a) { public static <T> BetterVector<T> asVector(T... a) {
return new BetterVector<>(a); return new BetterVector<>(a);
} }
/** /**
* Constructs an empty vector so that its internal data array has size 10 and * Constructs an empty vector so that its internal data array has size 10 and
* its standard capacity increment is zero. * its standard capacity increment is zero.
*/ */
public BetterVector() { public BetterVector() {
super(); super();
} }
/** /**
* Constructs a vector containing the elements of the specified collection, in * Constructs a vector containing the elements of the specified collection, in
* the order they are returned by the collection's iterator. * the order they are returned by the collection's iterator.
* *
* @param c - the collection whose elements are to be placed into this vector * @param c - the collection whose elements are to be placed into this vector
*/ */
public BetterVector(Collection<? extends T> c) { public BetterVector(Collection<? extends T> c) {
super(c); super(c);
} }
/** /**
* Constructs a vector containing the elements given in argument. * Constructs a vector containing the elements given in argument.
* *
* @param a - the elements to be placed into this list * @param a - the elements to be placed into this list
*/ */
public BetterVector(T... a) { public BetterVector(T... a) {
super(Arrays.asList(a)); super(Arrays.asList(a));
} }
/** /**
* Constructs an empty vector with the specified initial capacity and with its * Constructs an empty vector with the specified initial capacity and with its
* capacity increment equal to zero. * capacity increment equal to zero.
* *
* @param initialCapacity - the initial capacity of the vector * @param initialCapacity - the initial capacity of the vector
*/ */
public BetterVector(int initialCapacity) { public BetterVector(int initialCapacity) {
super(initialCapacity); super(initialCapacity);
} }
/** /**
* Constructs an empty vector with the specified initial capacity and capacity * Constructs an empty vector with the specified initial capacity and capacity
* increment. * increment.
* *
* @param initialCapacity - the initial capacity of the vector * @param initialCapacity - the initial capacity of the vector
* @param capacityIncrement - the amount by which the capacity is increased when the vector * @param capacityIncrement - the amount by which the capacity is increased when the vector
* overflows * overflows
*/ */
public BetterVector(int initialCapacity, int capacityIncrement) { public BetterVector(int initialCapacity, int capacityIncrement) {
super(initialCapacity, capacityIncrement); super(initialCapacity, capacityIncrement);
} }
/** /**
* Returns a view of the portion of this list between the specified fromIndex, * Returns a view of the portion of this list between the specified fromIndex,
* inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the
* returned list is empty.) The returned list is backed by this list, so * 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 * 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 * vice-versa. The returned list supports all of the optional list operations
* supported by this list. This method eliminates the need for explicit range * supported by this list. This method eliminates the need for explicit range
* operations (of the sort that commonly exist for arrays). Any operation that * 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 * expects a list can be used as a range operation by passing a subList view
* instead of a whole list. (see List.subList) * instead of a whole list. (see List.subList)
* *
* @param fromIndex - low endpoint (inclusive) of the subList * @param fromIndex - low endpoint (inclusive) of the subList
* @param toIndex - high endpoint (exclusive) of the subList * @param toIndex - high endpoint (exclusive) of the subList
* @return a view of the specified range within this list * @return a view of the specified range within this list
* @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex > * @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex >
* size || fromIndex > toIndex) * size || fromIndex > toIndex)
* @see java.util.List * @see java.util.List
*/ */
@Override @Override
public BetterVector<T> subList(int fromIndex, int toIndex) { public BetterVector<T> subList(int fromIndex, int toIndex) {
return (BetterVector<T>) super.subList(fromIndex, toIndex); return (BetterVector<T>) super.subList(fromIndex, toIndex);
} }
} }
@@ -1,6 +1,5 @@
package fr.klemek.betterlists.test; package fr.klemek.betterlists;
import fr.klemek.betterlists.BetterArrayList;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;