moving object array extensions
diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index 50b02b4..5f00f32 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -20,10 +20,12 @@
import groovy.lang.Closure;
import groovy.lang.EmptyRange;
+import groovy.lang.GroovyRuntimeException;
import groovy.lang.IntRange;
import groovy.lang.MetaClass;
import groovy.lang.ObjectRange;
import groovy.lang.Range;
+import groovy.lang.SpreadMap;
import groovy.transform.stc.ClosureParams;
import groovy.transform.stc.FirstParam;
import groovy.transform.stc.FromString;
@@ -56,19 +58,23 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
+import java.util.Random;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.DoubleUnaryOperator;
+import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.IntUnaryOperator;
import java.util.function.LongConsumer;
@@ -784,18 +790,287 @@
return DefaultGroovyMethods.chop(new DoubleArrayIterator(self), chopSizes);
}
+ /**
+ * Chops the array into pieces, returning lists with sizes corresponding to the supplied chop sizes.
+ * If the array isn't large enough, truncated (possibly empty) pieces are returned.
+ * Using a chop size of -1 will cause that piece to contain all remaining items from the array.
+ *
+ * @param self an Array to be chopped
+ * @param chopSizes the sizes for the returned pieces
+ * @return a list of lists chopping the original array elements into pieces determined by chopSizes
+ * @see #collate(Object[], int) to chop a list into pieces of a fixed size
+ * @since 2.5.2
+ */
+ public static <T> List<List<T>> chop(T[] self, int... chopSizes) {
+ return DefaultGroovyMethods.chop(Arrays.asList(self), chopSizes);
+ }
+
//--------------------------------------------------------------------------
// collate
+ /**
+ * Collates an array.
+ *
+ * @param self an array
+ * @param size the length of each sub-list in the returned list
+ * @return a List containing the array values collated into sub-lists
+ * @see #collate(Iterable, int)
+ * @since 2.5.0
+ */
+ public static <T> List<List<T>> collate(T[] self, int size) {
+ return collate(self, size, true);
+ }
+
+ /**
+ * Collates an array into sub-lists.
+ *
+ * @param self an array
+ * @param size the length of each sub-list in the returned list
+ * @param step the number of elements to step through for each sub-list
+ * @return a List containing the array elements collated into sub-lists
+ * @see #collate(Iterable, int, int)
+ * @since 2.5.0
+ */
+ public static <T> List<List<T>> collate(T[] self, int size, int step) {
+ return collate(self, size, step, true);
+ }
+
+ /**
+ * Collates this array into sub-lists.
+ *
+ * @param self an array
+ * @param size the length of each sub-list in the returned list
+ * @param keepRemainder if true, any remaining elements are returned as sub-lists. Otherwise they are discarded
+ * @return a List containing the array elements collated into sub-lists
+ * @see #collate(Iterable, int, boolean)
+ * @since 2.5.0
+ */
+ public static <T> List<List<T>> collate(T[] self, int size, boolean keepRemainder) {
+ return collate(self, size, size, keepRemainder);
+ }
+
+ /**
+ * Collates this array into sub-lists.
+ *
+ * @param self an array
+ * @param size the length of each sub-list in the returned list
+ * @param step the number of elements to step through for each sub-list
+ * @param keepRemainder if true, any remaining elements are returned as sub-lists. Otherwise they are discarded
+ * @return a List containing the array elements collated into sub-lists
+ * @since 2.5.0
+ */
+ public static <T> List<List<T>> collate(T[] self, int size, int step, boolean keepRemainder) {
+ final List<List<T>> answer;
+ if (size <= 0) {
+ answer = new ArrayList<>(1);
+ answer.add(Arrays.asList(self));
+ } else {
+ if (step == 0) throw new IllegalArgumentException("step cannot be zero");
+ final int selfSize = self.length;
+ answer = new ArrayList<>(step < 0 ? 1 : (selfSize / step + 1));
+ for (int pos = 0; pos < selfSize && pos > -1; pos += step) {
+ if (!keepRemainder && pos > selfSize - size) {
+ break;
+ }
+ List<T> element = new ArrayList<>(size);
+ for (int offs = pos; offs < pos + size && offs < selfSize; offs++) {
+ element.add(self[offs]);
+ }
+ answer.add(element);
+ }
+ }
+ return answer;
+ }
+
//--------------------------------------------------------------------------
// collect
+ /**
+ * Iterates through this Array transforming each item into a new value using the
+ * <code>transform</code> closure, returning a list of transformed values.
+ *
+ * @param self an array
+ * @param transform the closure used to transform each item of the Array
+ * @return A list of the transformed values.
+ * @since 2.5.0
+ */
+ public static <E, T> List<T> collect(E[] self, @ClosureParams(FirstParam.Component.class) Closure<T> transform) {
+ return DefaultGroovyMethods.collect(new ArrayIterator<>(self), transform);
+ }
+
+ /**
+ * Iterates through this Array transforming each item into a new value using the <code>transform</code> closure
+ * and adding it to the supplied <code>collector</code>.
+ * <pre class="groovyTestCase">
+ * Integer[] nums = [1,2,3]
+ * List<Integer> answer = []
+ * nums.collect(answer) { it * 2 }
+ * assert [2,4,6] == answer
+ * </pre>
+ *
+ * @param self an array
+ * @param collector the Collection to which the transformed values are added
+ * @param transform the closure used to transform each item
+ * @return The collector with all transformed values added to it.
+ * @since 2.5.0
+ */
+ public static <E, T, C extends Collection<T>> C collect(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends T> transform) {
+ return DefaultGroovyMethods.collect(new ArrayIterator<>(self), collector, transform);
+ }
+
//--------------------------------------------------------------------------
// collectEntries
+ /**
+ * A variant of collectEntries using the identity closure as the transform.
+ *
+ * @param self an array
+ * @return the collector with all transformed values added to it
+ * @see #collectEntries(Object[], Closure)
+ * @since 1.8.5
+ */
+ public static <K, V, E> Map<K, V> collectEntries(E[] self) {
+ return collectEntries(self, Closure.IDENTITY);
+ }
+
+ /**
+ * A variant of collectEntries using the identity closure as the transform.
+ *
+ * @param self an array
+ * @param collector the Map into which the transformed entries are put
+ * @return the collector with all transformed values added to it
+ * @see #collectEntries(Object[], Map, Closure)
+ * @since 1.8.5
+ */
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector) {
+ return collectEntries(self, collector, Closure.IDENTITY);
+ }
+
+ /**
+ * Iterates through this array transforming each item using the <code>transform</code> closure
+ * and returning a map of the resulting transformed entries.
+ * <pre class="groovyTestCase">
+ * def letters = "abc"
+ * def nums = [0, 1, 2] as Integer[]
+ * // collect letters with index using list style
+ * assert nums.collectEntries { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
+ * // collect letters with index using map style
+ * assert nums.collectEntries { index {@code ->} [(index): letters[index]] } == [0:'a', 1:'b', 2:'c']
+ * </pre>
+ * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
+ * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
+ * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
+ *
+ * @param self a Collection
+ * @param transform the closure used for transforming, which has an item from self as the parameter and
+ * should return a Map.Entry, a Map or a two-element list containing the resulting key and value
+ * @return a Map of the transformed entries
+ * @see #collectEntries(Iterator, Map, Closure)
+ * @since 1.7.9
+ */
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+ return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), transform);
+ }
+
+ /**
+ * Iterates through this array transforming each item using the <code>transform</code> closure
+ * and returning a map of the resulting transformed entries.
+ * <pre class="groovyTestCase">
+ * def letters = "abc"
+ * def nums = [0, 1, 2] as Integer[]
+ * // collect letters with index
+ * assert nums.collectEntries( [:] ) { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
+ * assert nums.collectEntries( [4:'d'] ) { index {@code ->}
+ * [(index+1): letters[index]] } == [1:'a', 2:'b', 3:'c', 4:'d']
+ * </pre>
+ * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
+ * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
+ * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
+ * If your collector Map doesn't support null keys or values, you might get a runtime error, e.g. NullPointerException or IllegalArgumentException.
+ *
+ * @param self an array
+ * @param collector the Map into which the transformed entries are put
+ * @param transform the closure used for transforming, which has an item from self as the parameter and
+ * should return a Map.Entry, a Map or a two-element list containing the resulting key and value
+ * @return the collector with all transformed values added to it
+ * @see #collect(Map, Collection, Closure)
+ * @since 1.7.9
+ */
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+ return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), collector, transform);
+ }
+
+ /**
+ * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
+ * <pre class="groovyTestCase">
+ * String[] languages = ['Groovy', 'Java', 'Kotlin', 'Scala']
+ * def firstLetter = s {@code ->} s[0]
+ * assert languages.collectEntries(firstLetter, String::size) == [G:6, J:4, K:6, S:5]
+ * </pre>
+ *
+ * @param self an array
+ * @param keyTransform a function for transforming array elements into keys
+ * @param valueTransform a function for transforming array elements into values
+ * @return a Map of the transformed entries
+ * @since 5.0.0
+ */
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
+ return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), keyTransform, valueTransform);
+ }
+
+ /**
+ * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
+ * The supplied collector map is used as the destination for transformed entries.
+ *
+ * @param self an array
+ * @param collector the Map into which the transformed entries are put
+ * @param keyTransform a function for transforming array elements into keys
+ * @param valueTransform a function for transforming array elements into values
+ * @return the collector with all transformed values added to it
+ * @since 5.0.0
+ */
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
+ return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), collector, keyTransform, valueTransform);
+ }
+
//--------------------------------------------------------------------------
// collectMany
+ /**
+ * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
+ * <pre class="groovyTestCase">
+ * def nums = [1, 2, 3, 4, 5, 6] as Object[]
+ * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
+ * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
+ * </pre>
+ *
+ * @param self an array
+ * @param projection a projecting Closure returning a collection of items
+ * @return A list created from the projected collections concatenated (flattened) together.
+ * @since 1.8.1
+ */
+ public static <T, E> List<T> collectMany(E[] self, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+ return collectMany(self, new ArrayList<>(), projection);
+ }
+
+ /**
+ * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
+ * <pre class="groovyTestCase">
+ * def nums = [1, 2, 3, 4, 5, 6] as Object[]
+ * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
+ * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
+ * </pre>
+ *
+ * @param self an array
+ * @param collector an initial collection to add the projected items to
+ * @param projection a projecting Closure returning a collection of items
+ * @return The collector with the projected collections concatenated (flattened) to it.
+ * @since 1.8.1
+ */
+ public static <T, E, C extends Collection<T>> C collectMany(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+ return DefaultGroovyMethods.collectMany(new ArrayIterable<>(self), collector, projection);
+ }
+
//--------------------------------------------------------------------------
// contains
@@ -927,6 +1202,22 @@
return false;
}
+ /**
+ * Checks whether the array contains the given value.
+ *
+ * @param self the array we are searching
+ * @param value the value being searched for
+ * @return true if the array contains the value
+ * @since 1.8.6
+ */
+ public static boolean contains(Object[] self, Object value) {
+ Objects.requireNonNull(self);
+ for (Object next : self) {
+ if (DefaultTypeTransformation.compareEqual(value, next)) return true;
+ }
+ return false;
+ }
+
//--------------------------------------------------------------------------
// count
@@ -1127,19 +1418,115 @@
* @see DefaultGroovyMethods#countBy(Iterator, Closure)
* @since 1.8.0
*/
- public static <K,E> Map<K, Integer> countBy(E[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
+ public static <K, E> Map<K, Integer> countBy(E[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
return DefaultGroovyMethods.countBy(new ArrayIterator<>(self), closure);
}
//-------------------------------------------------------------------------
// drop
+ /**
+ * Drops the given number of elements from the head of this array
+ * if they are available.
+ * <pre class="groovyTestCase">
+ * String[] strings = [ 'a', 'b', 'c' ]
+ * assert strings.drop( 0 ) == [ 'a', 'b', 'c' ] as String[]
+ * assert strings.drop( 2 ) == [ 'c' ] as String[]
+ * assert strings.drop( 5 ) == [] as String[]
+ * </pre>
+ *
+ * @param self the original array
+ * @param num the number of elements to drop from this array
+ * @return An array consisting of all elements of this array except the
+ * first <code>num</code> ones, or else the empty array, if this
+ * array has less than <code>num</code> elements.
+ * @since 1.8.1
+ */
+ public static <T> T[] drop(T[] self, int num) {
+ if (self.length <= num) {
+ return createSimilarArray(self, 0);
+ }
+ if (num <= 0) {
+ T[] ret = createSimilarArray(self, self.length);
+ System.arraycopy(self, 0, ret, 0, self.length);
+ return ret;
+ }
+
+ T[] ret = createSimilarArray(self, self.length - num);
+ System.arraycopy(self, num, ret, 0, self.length - num);
+ return ret;
+ }
+
//--------------------------------------------------------------------------
// dropRight
+ /**
+ * Drops the given number of elements from the tail of this array
+ * if they are available.
+ * <pre class="groovyTestCase">
+ * String[] strings = [ 'a', 'b', 'c' ]
+ * assert strings.dropRight( 0 ) == [ 'a', 'b', 'c' ] as String[]
+ * assert strings.dropRight( 2 ) == [ 'a' ] as String[]
+ * assert strings.dropRight( 5 ) == [] as String[]
+ * </pre>
+ *
+ * @param self the original array
+ * @param num the number of elements to drop from this array
+ * @return An array consisting of all elements of this array except the
+ * last <code>num</code> ones, or else the empty array, if this
+ * array has less than <code>num</code> elements.
+ * @since 2.4.0
+ */
+ public static <T> T[] dropRight(T[] self, int num) {
+ if (self.length <= num) {
+ return createSimilarArray(self, 0);
+ }
+ if (num <= 0) {
+ T[] ret = createSimilarArray(self, self.length);
+ System.arraycopy(self, 0, ret, 0, self.length);
+ return ret;
+ }
+
+ T[] ret = createSimilarArray(self, self.length - num);
+ System.arraycopy(self, 0, ret, 0, self.length - num);
+ return ret;
+ }
+
//--------------------------------------------------------------------------
// dropWhile
+ /**
+ * Create a suffix of the given array by dropping as many elements as possible from the
+ * front of the original array such that calling the given closure condition evaluates to
+ * true when passed each of the dropped elements.
+ * <pre class="groovyTestCase">
+ * def nums = [ 1, 3, 2 ] as Integer[]
+ * assert nums.dropWhile{ it {@code <=} 3 } == [ ] as Integer[]
+ * assert nums.dropWhile{ it {@code <} 3 } == [ 3, 2 ] as Integer[]
+ * assert nums.dropWhile{ it != 2 } == [ 2 ] as Integer[]
+ * assert nums.dropWhile{ it == 0 } == [ 1, 3, 2 ] as Integer[]
+ * </pre>
+ *
+ * @param self the original array
+ * @param condition the closure that must evaluate to true to
+ * continue dropping elements
+ * @return The shortest suffix of the given array such that the given closure condition
+ * evaluates to true for each element dropped from the front of the array.
+ * @since 1.8.7
+ */
+ public static <T> T[] dropWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+ int num = 0;
+ BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
+ while (num < self.length) {
+ if (bcw.call(self[num])) {
+ num += 1;
+ } else {
+ break;
+ }
+ }
+ return drop(self, num);
+ }
+
//--------------------------------------------------------------------------
// each
@@ -1625,7 +2012,7 @@
// equals
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1645,7 +2032,7 @@
}
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1665,7 +2052,7 @@
}
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1685,7 +2072,7 @@
}
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1705,7 +2092,7 @@
}
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1725,7 +2112,7 @@
}
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1745,7 +2132,7 @@
}
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1765,7 +2152,7 @@
}
/**
- * Compare the contents of this array to the contents of the given array.
+ * Compares the contents of this array to the contents of the given array.
* <p>
* Example usage:
* <pre class="groovyTestCase">
@@ -1784,6 +2171,20 @@
return Arrays.equals(self, right);
}
+ /**
+ * Determines if the contents of this array are equal to the
+ * contents of the given list, in the same order. This returns
+ * <code>false</code> if either collection is <code>null</code>.
+ *
+ * @param left an array
+ * @param right the List being compared
+ * @return {@code true} if the contents of both collections are equal.
+ * @since 1.5.0
+ */
+ public static boolean equals(Object[] left, List<?> right) {
+ return DefaultGroovyMethods.equals(right, left);
+ }
+
//--------------------------------------------------------------------------
// every
@@ -2014,9 +2415,65 @@
//--------------------------------------------------------------------------
// find
+ /**
+ * Finds the first element in the array that matches the given closure condition.
+ * Example:
+ * <pre class="groovyTestCase">
+ * def list = [1,2,3] as Integer[]
+ * assert 2 == list.find { it {@code >} 1 }
+ * assert null == list.find { it {@code >} 5 }
+ * </pre>
+ *
+ * @param self an array
+ * @param condition a closure condition
+ * @return The first element from the array that matches the condition or null if no element matches.
+ * @since 2.0
+ */
+ public static <T> T find(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+ BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
+ for (T element : self) {
+ if (bcw.call(element)) {
+ return element;
+ }
+ }
+ return null;
+ }
+
//--------------------------------------------------------------------------
// findAll
+ /**
+ * Finds the elements of the array matching the IDENTITY Closure (i.e. matching Groovy truth).
+ * <pre class="groovyTestCase">
+ * def items = [1, 2, 0, false, true, '', 'foo', [], [4, 5], null] as Object[]
+ * assert items.findAll() == [1, 2, true, 'foo', [4, 5]]
+ * </pre>
+ *
+ * @param self an array
+ * @return A list of the truthy values.
+ * @see Closure#IDENTITY
+ * @since 2.0
+ */
+ public static <T> List<T> findAll(T[] self) {
+ return findAll(self, Closure.IDENTITY);
+ }
+
+ /**
+ * Finds all elements of the array matching the given Closure condition.
+ * <pre class="groovyTestCase">
+ * def items = [1,2,3,4] as Integer[]
+ * assert [2,4] == items.findAll { it % 2 == 0 }
+ * </pre>
+ *
+ * @param self an array
+ * @param condition a closure condition
+ * @return A list of the matching values.
+ * @since 2.0
+ */
+ public static <T> List<T> findAll(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+ return DefaultGroovyMethods.findMany(new ArrayList<>(), new ArrayIterator<>(self), condition);
+ }
+
//--------------------------------------------------------------------------
// findIndexOf
@@ -2114,9 +2571,85 @@
//--------------------------------------------------------------------------
// findResult
+ /**
+ * Iterates through the Array stopping once the first non-null
+ * result is found and returning that result. If all results are null, null is returned.
+ *
+ * @param self an array
+ * @return The first non-null result from calling the closure, or null.
+ * @since 4.0.9
+ */
+ public static <T> T findResult(T[] self) {
+ return DefaultGroovyMethods.findResult(new ArrayIterator<>(self));
+ }
+
+ /**
+ * Iterates through the Array stopping once the first non-null
+ * result is found and returning that result. If all are null, the defaultResult is returned.
+ *
+ * @param self an Array
+ * @param defaultResult an Object that should be returned if all elements are null
+ * @return the first non-null result from calling the closure, or the defaultValue
+ * @since 4.0.9
+ */
+ public static <T, U extends T, V extends T> T findResult(U[] self, V defaultResult) {
+ return DefaultGroovyMethods.findResult(new ArrayIterator<>(self), defaultResult);
+ }
+
+ /**
+ * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
+ * result is found and returning that result. If all results are null, null is returned.
+ *
+ * @param self an array
+ * @param condition a closure that returns a non-null value to indicate that processing should stop and the value should be returned
+ * @return The first non-null result from calling the closure, or null.
+ * @since 2.5.0
+ */
+ public static <S, T> T findResult(S[] self, @ClosureParams(FirstParam.Component.class) Closure<T> condition) {
+ return DefaultGroovyMethods.findResult(new ArrayIterator<>(self), condition);
+ }
+
+ /**
+ * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
+ * result is found and returning that result. If all are null, the defaultResult is returned.
+ *
+ * @param self an array
+ * @param defaultResult a value that should be returned if all closure results are null
+ * @param condition a closure that returns a non-null value to indicate that processing should stop and the value should be returned
+ * @return The first non-null result from calling the closure, or the defaultValue.
+ * @since 2.5.0
+ */
+ public static <S, T, U extends T, V extends T> T findResult(S[] self, U defaultResult, @ClosureParams(FirstParam.Component.class) Closure<V> condition) {
+ return DefaultGroovyMethods.findResult(new ArrayIterator<>(self), defaultResult, condition);
+ }
+
//--------------------------------------------------------------------------
// findResults
+ /**
+ * Iterates through the Array collecting any non-null results.
+ *
+ * @param self an array
+ * @return The list of non-null values.
+ * @since 4.0.9
+ */
+ public static <T> Collection<T> findResults(T[] self) {
+ return DefaultGroovyMethods.findResults(new ArrayIterator<>(self));
+ }
+
+ /**
+ * Iterates through the Array transforming items using the supplied closure
+ * and collecting any non-null results.
+ *
+ * @param self an array
+ * @param filteringTransform a closure that should return either a non-null transformed value or null for items which should be discarded
+ * @return The list of non-null transformed values.
+ * @since 2.5.0
+ */
+ public static <T, U> Collection<T> findResults(U[] self, @ClosureParams(FirstParam.Component.class) Closure<T> filteringTransform) {
+ return DefaultGroovyMethods.findResults(new ArrayIterator<>(self), filteringTransform);
+ }
+
//--------------------------------------------------------------------------
// first
@@ -2272,6 +2805,24 @@
return self[0];
}
+ /**
+ * Returns the first item from the array.
+ * <pre class="groovyTestCase">
+ * def array = [3, 4, 2].toArray()
+ * assert array.first() == 3
+ * </pre>
+ *
+ * @param self an array
+ * @return the first item from the array
+ * @throws NoSuchElementException if the array is empty
+ * @since 1.7.3
+ */
+ public static <T> T first(T[] self) {
+ Objects.requireNonNull(self);
+ throwNoSuchElementIfEmpty(self.length, "first");
+ return self[0];
+ }
+
//--------------------------------------------------------------------------
// flatten
@@ -2411,6 +2962,19 @@
return toList(self);
}
+ /**
+ * Flattens an array. This array and any nested arrays or
+ * collections have their contents (recursively) added to the new collection.
+ *
+ * @param self an Array to flatten
+ * @return S flattened Collection
+ * @since 1.6.0
+ */
+ @SuppressWarnings("unchecked")
+ public static List<Object> flatten(Object[] self) {
+ return (List<Object>) DefaultGroovyMethods.flatten(Arrays.asList(self));
+ }
+
//
/**
@@ -2601,7 +3165,7 @@
// getAt
/**
- * Support the subscript operator for a boolean array with a range giving the desired indices.
+ * Supports the subscript operator for a boolean array with a range giving the desired indices.
* <pre class="groovyTestCase">
* boolean[] array = [false, true, false, true, false, true]
* assert array[2..<2] == [] // EmptyRange
@@ -2620,7 +3184,7 @@
}
/**
- * Support the subscript operator for a byte array with a range giving the desired indices.
+ * Supports the subscript operator for a byte array with a range giving the desired indices.
* <pre class="groovyTestCase">
* byte[] array = [1, 3, 5, 7, 9, 11]
* assert array[2..<2] == [] // EmptyRange
@@ -2639,7 +3203,7 @@
}
/**
- * Support the subscript operator for a char array with a range giving the desired indices.
+ * Supports the subscript operator for a char array with a range giving the desired indices.
* <pre class="groovyTestCase">
* char[] array = 'abcdef'.chars
* assert array[2..<2] == [] // EmptyRange
@@ -2658,7 +3222,7 @@
}
/**
- * Support the subscript operator for a short array with a range giving the desired indices.
+ * Supports the subscript operator for a short array with a range giving the desired indices.
* <pre class="groovyTestCase">
* short[] array = [1, 3, 5, 7, 9, 11]
* assert array[2..<2] == [] // EmptyRange
@@ -2677,7 +3241,7 @@
}
/**
- * Support the subscript operator for an int array with a range giving the desired indices.
+ * Supports the subscript operator for an int array with a range giving the desired indices.
* <pre class="groovyTestCase">
* int[] array = [1, 3, 5, 7, 9, 11]
* assert array[2..<2] == [] // EmptyRange
@@ -2696,7 +3260,7 @@
}
/**
- * Support the subscript operator for a long array with a range giving the desired indices.
+ * Supports the subscript operator for a long array with a range giving the desired indices.
* <pre class="groovyTestCase">
* long[] array = [1L, 3L, 5L, 7L, 9L, 11L]
* assert array[2..<2] == [] // EmptyRange
@@ -2715,7 +3279,7 @@
}
/**
- * Support the subscript operator for a float array with a range giving the desired indices.
+ * Supports the subscript operator for a float array with a range giving the desired indices.
* <pre class="groovyTestCase">
* float[] array = [1.0f, 3.0f, 5.0f, 7.0f, 9.0f, 11.0f]
* assert array[2..<2] == [] // EmptyRange
@@ -2734,7 +3298,7 @@
}
/**
- * Support the subscript operator for a double array with a range giving the desired indices.
+ * Supports the subscript operator for a double array with a range giving the desired indices.
* <pre class="groovyTestCase">
* double[] array = [1.0d, 3.0d, 5.0d, 7.0d, 9.0d, 11.0d]
* assert array[2..<2] == [] // EmptyRange
@@ -2753,7 +3317,7 @@
}
/**
- * Support the subscript operator for an object array with a range giving the desired indices.
+ * Supports the subscript operator for an object array with a range giving the desired indices.
*
* @param array an Array of Objects
* @param range a Range
@@ -2768,7 +3332,7 @@
//
/**
- * Support the subscript operator for a boolean array with an IntRange giving the desired indices.
+ * Supports the subscript operator for a boolean array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* boolean[] array = [false, false, true, true, false]
* assert array[2..3] == [true, true]
@@ -2789,7 +3353,7 @@
}
/**
- * Support the subscript operator for a byte array with an IntRange giving the desired indices.
+ * Supports the subscript operator for a byte array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* byte[] array = [0, 10, 20, 30, 40]
* assert array[2..3] == [20, 30]
@@ -2810,7 +3374,7 @@
}
/**
- * Support the subscript operator for a char array with an IntRange giving the desired indices.
+ * Supports the subscript operator for a char array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* char[] array = 'abcdef'.chars
* assert array[2..3] == ['c', 'd']
@@ -2831,7 +3395,7 @@
}
/**
- * Support the subscript operator for a short array with an IntRange giving the desired indices.
+ * Supports the subscript operator for a short array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* short[] array = [0, 10, 20, 30, 40]
* assert array[2..3] == [20, 30]
@@ -2852,7 +3416,7 @@
}
/**
- * Support the subscript operator for an int array with an IntRange giving the desired indices.
+ * Supports the subscript operator for an int array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* int[] array = [0, 10, 20, 30, 40]
* assert array[2..3] == [20, 30]
@@ -2873,7 +3437,7 @@
}
/**
- * Support the subscript operator for a long array with an IntRange giving the desired indices.
+ * Supports the subscript operator for a long array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* long[] array = [0L, 10L, 20L, 30L, 40L]
* assert array[2..3] == [20L, 30L]
@@ -2894,7 +3458,7 @@
}
/**
- * Support the subscript operator for a float array with an IntRange giving the desired indices.
+ * Supports the subscript operator for a float array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* float[] array = [0.0f, 10.0f, 20.0f, 30.0f, 40.0f]
* assert array[2..3] == [20.0f, 30.0f]
@@ -2915,7 +3479,7 @@
}
/**
- * Support the subscript operator for a double array with an IntRange giving the desired indices.
+ * Supports the subscript operator for a double array with an IntRange giving the desired indices.
* <pre class="groovyTestCase">
* double[] array = [0.0d, 10.0d, 20.0d, 30.0d, 40.0d]
* assert array[2..3] == [20.0d, 30.0d]
@@ -2936,6 +3500,7 @@
}
/**
+ * Supports the subscript operator for an object array with an IntRange giving the desired indices.
*
* @param array an object array
* @param range an IntRange
@@ -2950,7 +3515,7 @@
//
/**
- * Support the subscript operator for a boolean array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for a boolean array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* boolean[] array = [false, false, true, true, false]
* def range = new ObjectRange(2, 3)
@@ -2968,7 +3533,7 @@
}
/**
- * Support the subscript operator for a byte array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for a byte array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* byte[] array = [0, 10, 20, 30, 40]
* def range = new ObjectRange(2, 3)
@@ -2986,7 +3551,7 @@
}
/**
- * Support the subscript operator for a boolean array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for a boolean array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* char[] array = 'abcdef'.chars
* def range = new ObjectRange(2, 3)
@@ -3004,7 +3569,7 @@
}
/**
- * Support the subscript operator for a short array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for a short array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* short[] array = [0, 10, 20, 30, 40]
* def range = new ObjectRange(2, 3)
@@ -3022,7 +3587,7 @@
}
/**
- * Support the subscript operator for an int array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for an int array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* int[] array = [0, 10, 20, 30, 40]
* def range = new ObjectRange(2, 3)
@@ -3040,7 +3605,7 @@
}
/**
- * Support the subscript operator for a long array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for a long array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* long[] array = [0L, 10L, 20L, 30L, 40L]
* def range = new ObjectRange(2, 3)
@@ -3058,7 +3623,7 @@
}
/**
- * Support the subscript operator for a float array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for a float array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* float[] array = [0.0f, 10.0f, 20.0f, 30.0f, 40.0f]
* def range = new ObjectRange(2, 3)
@@ -3076,7 +3641,7 @@
}
/**
- * Support the subscript operator for a double array with an ObjectRange giving the desired indices.
+ * Supports the subscript operator for a double array with an ObjectRange giving the desired indices.
* <pre class="groovyTestCase">
* double[] array = [0.0d, 10.0d, 20.0d, 30.0d, 40.0d]
* def range = new ObjectRange(2, 3)
@@ -3094,6 +3659,8 @@
}
/**
+ * Supports the subscript operator for an object array with an ObjectRange giving the desired indices.
+ *
* @param array an Array of Objects
* @param range an ObjectRange
* @return a range of a list from the range's from index up to but not
@@ -3107,6 +3674,7 @@
//
/**
+ * Supports the subscript operator for an object array with an EmptyRange.
*
* @param array an Array of Objects
* @param range an EmptyRange
@@ -3120,7 +3688,7 @@
//
/**
- * Support the subscript operator for a boolean array
+ * Supports the subscript operator for a boolean array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* boolean[] array = [false, false, true, true, false]
@@ -3139,7 +3707,7 @@
}
/**
- * Support the subscript operator for a byte array
+ * Supports the subscript operator for a byte array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* byte[] array = [0, 2, 4, 6, 8]
@@ -3158,7 +3726,7 @@
}
/**
- * Support the subscript operator for a char array
+ * Supports the subscript operator for a char array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* char[] array = 'abcde'.chars
@@ -3177,7 +3745,7 @@
}
/**
- * Support the subscript operator for a short array
+ * Supports the subscript operator for a short array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* short[] array = [0, 2, 4, 6, 8]
@@ -3196,7 +3764,7 @@
}
/**
- * Support the subscript operator for an int array
+ * Supports the subscript operator for an int array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* int[] array = [0, 2, 4, 6, 8]
@@ -3215,7 +3783,7 @@
}
/**
- * Support the subscript operator for a long array
+ * Supports the subscript operator for a long array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* long[] array = [0L, 2L, 4L, 6L, 8L]
@@ -3234,7 +3802,7 @@
}
/**
- * Support the subscript operator for a float array
+ * Supports the subscript operator for a float array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* float[] array = [0.0f, 2.0f, 4.0f, 6.0f, 8.0f]
@@ -3253,7 +3821,7 @@
}
/**
- * Support the subscript operator for a double array
+ * Supports the subscript operator for a double array
* with a (potentially nested) collection giving the desired indices.
* <pre class="groovyTestCase">
* double[] array = [0.0d, 2.0d, 4.0d, 6.0d, 8.0d]
@@ -3272,7 +3840,7 @@
}
/**
- * Select a List of items from an array using a Collection to
+ * Selects a List of items from an array using a Collection to
* identify the indices to be selected.
*
* @param array an object array
@@ -3490,6 +4058,53 @@
//--------------------------------------------------------------------------
// groupBy
+ /**
+ * Sorts all array members into groups determined by the supplied mapping closure.
+ * The closure should return the key that this item should be grouped by. The returned
+ * LinkedHashMap will have an entry for each distinct key returned from the closure,
+ * with each value being a list of items for that group.
+ * <p>
+ * Example usage:
+ * <pre class="groovyTestCase">
+ * Integer[] items = [1,2,3,4,5,6]
+ * assert [0:[2,4,6], 1:[1,3,5]] == items.groupBy { it % 2 }
+ * </pre>
+ *
+ * @param self an array to group
+ * @param closure a closure mapping entries on keys
+ * @return A map grouped by keys.
+ * @since 2.2.0
+ */
+ public static <K, T> Map<K, List<T>> groupBy(T[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
+ return DefaultGroovyMethods.groupBy(Arrays.asList(self), closure);
+ }
+
+ /**
+ * Sorts all array members into (sub)groups determined by the supplied
+ * mapping closures as per the Iterable variant of this method.
+ *
+ * @param self an array to group
+ * @param closures an array of closures, each mapping entries on keys
+ * @return A map grouped by keys on each criterion.
+ * @since 2.2.0
+ */
+ public static Map groupBy(Object[] self, Object... closures) {
+ return DefaultGroovyMethods.groupBy(new ArrayIterable<>(self), closures);
+ }
+
+ /**
+ * Sorts all array members into (sub)groups determined by the supplied
+ * mapping closures as per the list variant of this method.
+ *
+ * @param self an array to group
+ * @param closures a list of closures, each mapping entries on keys
+ * @return A map grouped by keys on each criterion.
+ * @since 2.2.0
+ */
+ public static Map groupBy(Object[] self, List<Closure<?>> closures) {
+ return DefaultGroovyMethods.groupBy(new ArrayIterable<>(self), closures);
+ }
+
//--------------------------------------------------------------------------
// head
@@ -3645,6 +4260,22 @@
return self[0];
}
+ /**
+ * Returns the first item from the Object array.
+ * <pre class="groovyTestCase">def array = [3, 4, 2].toArray()
+ * assert array.head() == 3</pre>
+ *
+ * @param self an array
+ * @return the first item from the Object array
+ * @throws NoSuchElementException if the array is empty
+ * @since 1.7.3
+ */
+ public static <T> T head(T[] self) {
+ Objects.requireNonNull(self);
+ throwNoSuchElementIfEmpty(self.length, "head");
+ return self[0];
+ }
+
//--------------------------------------------------------------------------
// indexed
@@ -3919,6 +4550,26 @@
return Arrays.copyOfRange(self, 0, self.length - 1);
}
+ /**
+ * Returns the items from the Object array excluding the last item.
+ * <pre class="groovyTestCase">
+ * String[] strings = ["a", "b", "c"]
+ * def result = strings.init()
+ * assert result.length == 2
+ * assert strings.class.componentType == String
+ * </pre>
+ *
+ * @param self an array
+ * @return an array without its last element
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 2.4.0
+ */
+ public static <T> T[] init(T[] self) {
+ Objects.requireNonNull(self);
+ throwNoSuchElementIfEmpty(self.length, "init");
+ return Arrays.copyOfRange(self, 0, self.length - 1);
+ }
+
//--------------------------------------------------------------------------
// inject
@@ -3934,7 +4585,7 @@
* @see #inject(Object[], Object, Closure)
* @since 1.8.7
*/
- public static <E,T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
+ public static <E, T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
return DefaultGroovyMethods.inject((Object) self, closure);
}
@@ -3968,16 +4619,14 @@
// iterator
/**
- * Attempts to create an Iterator for the given object by first
- * converting it to a Collection.
+ * Returns an Iterator for the given array.
*
* @param self an array
* @return an Iterator for the given Array.
- * @see org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation#asCollection(java.lang.Object[])
* @since 1.6.4
*/
public static <T> Iterator<T> iterator(final T[] self) {
- return DefaultTypeTransformation.asCollection(self).iterator();
+ return Arrays.asList(self).iterator();
}
//--------------------------------------------------------------------------
@@ -4248,6 +4897,25 @@
return self[self.length - 1];
}
+ /**
+ * Returns the last item from the array.
+ * <pre class="groovyTestCase">
+ * def array = [3, 4, 2].toArray()
+ * assert array.last() == 2
+ * </pre>
+ *
+ * @param self an array
+ * @return the last item from the array
+ * @throws NoSuchElementException if you try to access last() for an empty array
+ * @since 1.7.3
+ */
+ public static <T> T last(T[] self) {
+ if (self.length == 0) {
+ throw new NoSuchElementException("Cannot access last() element from an empty Array");
+ }
+ return self[self.length - 1];
+ }
+
//--------------------------------------------------------------------------
// max
@@ -5204,9 +5872,233 @@
//--------------------------------------------------------------------------
// minus
+ /**
+ * Creates a new array composed of the elements of the first array minus the
+ * elements of the given Iterable.
+ * <pre class="groovyTestCase">
+ * Integer[] ints = [1, 2, 3, 1]
+ * List<Integer> nope = [1, 3]
+ * def result = ints - nope
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{2}
+ *
+ * Integer[] none = []
+ * result = none - 123
+ * assert result !== none
+ * assert result.length == 0
+ * assert result.class == Integer[]
+ * </pre>
+ *
+ * @param self an array
+ * @param removeMe an Iterable of elements to remove
+ * @return An array with the supplied elements removed.
+ * @since 1.5.5
+ */
+ public static <T> T[] minus(T[] self, Iterable<?> removeMe) {
+ Collection<T> temp = DefaultGroovyMethods.minus((Iterable<T>) toList(self), removeMe);
+ return temp.toArray(createSimilarArray(self, temp.size()));
+ }
+
+ /**
+ * Creates a new array composed of the elements of the first array minus the
+ * elements of the given array.
+ * <pre class="groovyTestCase">
+ * Integer[] ints = [1, 2, 3, 1]
+ * Integer[] nope = [1, 3]
+ * def result = ints - nope
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{2}
+ *
+ * Integer[] none = []
+ * result = none - 123
+ * assert result !== none
+ * assert result.length == 0
+ * assert result.class == Integer[]
+ * </pre>
+ *
+ * @param self an array
+ * @param removeMe an array of elements to remove
+ * @return An array with the supplied elements removed.
+ * @since 1.5.5
+ */
+ public static <T> T[] minus(T[] self, Object[] removeMe) {
+ switch (removeMe.length) {
+ case 0:
+ return self.clone();
+ case 1:
+ return DefaultGroovyMethods.minus(self, removeMe[0]);
+ default:
+ Collection<T> temp = DefaultGroovyMethods.minus((Collection<T>) toList(self), Arrays.asList(removeMe));
+ return temp.toArray(createSimilarArray(self, temp.size()));
+ }
+ }
+
+ /**
+ * Creates a new array composed of the elements of the given array minus every occurrence the given object.
+ * <pre class="groovyTestCase">
+ * Integer[] ints = [1, 2, 3, 1]
+ * def result = ints - 1
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{2, 3}
+ *
+ * Integer[] none = []
+ * result = none - '1'
+ * assert result !== none
+ * assert result.length == 0
+ * assert result.class == Integer[]
+ * </pre>
+ *
+ * @param self an array
+ * @param removeMe an element to remove from the array
+ * @return a new array with the operand removed
+ * @since 1.5.5
+ */
+ public static <T> T[] minus(T[] self, Object removeMe) {
+ int i = 0, n = self.length;
+ T[] result = createSimilarArray(self, n);
+ for (T t : self) {
+ if (!DefaultGroovyMethods.coercedEquals(t, removeMe)) {
+ result[i] = t;
+ i += 1;
+ }
+ }
+ if (i != n) {
+ result = Arrays.copyOfRange(result, 0, i);
+ }
+ return result;
+ }
+
//--------------------------------------------------------------------------
// plus
+ /**
+ * Creates an array containing elements from an original array plus those from a Collection.
+ * <pre class="groovyTestCase">
+ * Integer[] a = [1, 2, 3]
+ * def result = a + [4, 5, 6]
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
+ *
+ * Number[] c = [-1, 0.9, null]
+ * result = c + [1, 2, 3]
+ * assert result.class == Number[]
+ * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
+ *
+ * result = a + [-1, 0.9, null]
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{1, 2, 3, -1, 0, null}
+ *
+ * // improper type arguments; Date can't be coerced to Integer
+ * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + [new Date()] }
+ * </pre>
+ *
+ * @param left the array
+ * @param right a Collection to be appended
+ * @return A new array containing left with right appended to it.
+ * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+ * @since 1.8.7
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] plus(T[] left, Collection<?> right) {
+ T[] result = Arrays.copyOf(left, left.length + right.size());
+ int i = left.length;
+ Class<?> leftType = left.getClass().getComponentType();
+ for (Object t : right) {
+ result[i] = (T) DefaultTypeTransformation.castToType(t, leftType);
+ i += 1;
+ }
+ return result;
+ }
+
+ /**
+ * Creates an array containing elements from an original array plus those from an Iterable.
+ * <pre class="groovyTestCase">
+ * class AbcIterable implements Iterable<String> {
+ * Iterator<String> iterator() { "abc".iterator() }
+ * }
+ * String[] array = ['x', 'y', 'z']
+ * def result = array + new AbcIterable()
+ * assert result.class == String[]
+ * assert result == new String[]{'x', 'y', 'z', 'a', 'b', 'c'}
+ * </pre>
+ *
+ * @param left the array
+ * @param right an Iterable to be appended
+ * @return A new array containing elements from left with those from right appended.
+ * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+ * @see #union(Object[], Iterable)
+ * @since 1.8.7
+ */
+ public static <T> T[] plus(T[] left, Iterable<?> right) {
+ return plus(left, DefaultGroovyMethods.toList(right));
+ }
+
+ /**
+ * Creates an array as a union of two arrays.
+ * <pre class="groovyTestCase">
+ * Integer[] a = [1, 2, 3]
+ * Integer[] b = [4, 5, 6]
+ * def result = a + b
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
+ *
+ * Number[] c = [-1, 0.9, null]
+ * result = c + a
+ * assert result.class == Number[]
+ * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
+ *
+ * result = a + c
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{1, 2, 3, -1, 0, null}
+ *
+ * Date[] d = [new Date()]
+ * // improper type arguments; Date can't be coerced to Integer
+ * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + d }
+ * </pre>
+ *
+ * @param left the left Array
+ * @param right the right Array
+ * @return A new array containing right appended to left.
+ * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+ * @since 1.8.7
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] plus(T[] left, Object[] right) {
+ T[] result = Arrays.copyOf(left, left.length + right.length);
+ T[] temp = (T[]) DefaultTypeTransformation.castToType(right, left.getClass());
+ System.arraycopy(temp, 0, result, left.length, temp.length);
+ return result;
+ }
+
+ /**
+ * Creates an array containing elements from an original array plus an additional appended element.
+ * <pre class="groovyTestCase">
+ * Integer[] a = [1, 2, 3]
+ * def result = a + 4
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{1, 2, 3, 4}
+ *
+ * result = a + 5.5d
+ * assert result.class == Integer[]
+ * assert result == new Integer[]{1, 2, 3, 5}
+ *
+ * // improper type arguments; Date can't be coerced to Integer
+ * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + new Date() }
+ * </pre>
+ *
+ * @param left the array
+ * @param right the value to append
+ * @return A new array containing left with right appended to it.
+ * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+ * @since 1.8.7
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] plus(T[] left, Object right) {
+ T[] result = Arrays.copyOf(left, left.length + 1);
+ result[left.length] = (T) DefaultTypeTransformation.castToType(right, left.getClass().getComponentType());
+ return result;
+ }
+
//--------------------------------------------------------------------------
// reverse
@@ -5227,7 +6119,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* boolean[] array = [false, true, true]
@@ -5271,7 +6163,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* byte[] array = 1..3
@@ -5315,7 +6207,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* char[] array = ['a', 'b', 'c']
@@ -5359,7 +6251,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* short[] array = 1..3
@@ -5403,7 +6295,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* int[] array = 1..3
@@ -5447,7 +6339,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* long[] array = 1L..3L
@@ -5491,7 +6383,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* float[] array = 1f..3f
@@ -5535,7 +6427,7 @@
}
/**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
* Otherwise, a new array containing the reversed items is produced.
* <pre class="groovyTestCase">
* double[] array = 1d..3d
@@ -5562,6 +6454,44 @@
return self;
}
+ /**
+ * Creates a new array containing items which are the same as this array but in reverse order.
+ *
+ * @param self an array
+ * @return An array containing the reversed items.
+ * @see #reverse(Object[], boolean)
+ * @since 1.5.5
+ */
+ public static <T> T[] reverse(T[] self) {
+ return reverse(self, false);
+ }
+
+ /**
+ * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
+ * Otherwise, a new array containing the reversed items is produced.
+ *
+ * <pre class="groovyTestCase">
+ * def array = new Object[] {1,2,3}
+ * def yarra = array.reverse(true)
+ * assert array == 3..1
+ * assert yarra == 3..1
+ *
+ * yarra = array.reverse(false)
+ * assert array == 3..1
+ * assert yarra == 1..3
+ * </pre>
+ *
+ * @param self an array
+ * @param mutate {@code true} if the array itself should be reversed in place, {@code false} if a new array should be created
+ * @return An array containing the reversed items.
+ * @since 1.8.1
+ */
+ public static <T> T[] reverse(T[] self, boolean mutate) {
+ if (!mutate) self = self.clone();
+ Collections.reverse(Arrays.asList(self));
+ return self;
+ }
+
//--------------------------------------------------------------------------
// reverseEach
@@ -5742,7 +6672,7 @@
}
/**
- * Iterate over each element of the array in the reverse order.
+ * Iterates over each element of the array in the reverse order.
*
* @param self an array
* @param closure a closure to which each item is passed
@@ -5760,14 +6690,105 @@
//--------------------------------------------------------------------------
// shuffle
+ private static Random r;
+
+ /**
+ * Randomly reorders the elements of the specified array.
+ * <pre class="groovyTestCase">
+ * Integer[] array = [10, 5, 20]
+ * def origSize = array.size()
+ * def items = array.toList()
+ * array.shuffle()
+ * assert array.size() == origSize
+ * assert items.every{ array.contains(it) }
+ * </pre>
+ *
+ * @param self an array
+ * @since 3.0.0
+ */
+ public static <T> void shuffle(T[] self) {
+ Random rnd = r;
+ if (rnd == null)
+ r = rnd = new Random(); // harmless race.
+ shuffle(self, rnd);
+ }
+
+ /**
+ * Randomly reorders the elements of the specified array using the
+ * specified random instance as the source of randomness.
+ * <pre class="groovyTestCase">
+ * def r = new Random()
+ * Integer[] array = [10, 5, 20]
+ * def origSize = array.size()
+ * def items = array.toList()
+ * array.shuffle(r)
+ * assert array.size() == origSize
+ * assert items.every{ array.contains(it) }
+ * </pre>
+ *
+ * @param self an array
+ * @since 3.0.0
+ */
+ public static <T> void shuffle(T[] self, Random rnd) {
+ for (int i = 0; i < self.length-1; i++) {
+ int nextIndex = rnd.nextInt(self.length);
+ T tmp = self[i];
+ self[i] = self[nextIndex];
+ self[nextIndex] = tmp;
+ }
+ }
+
//--------------------------------------------------------------------------
// shuffled
+ /**
+ * Creates a new array containing the elements of the specified array but in a random order.
+ * <pre class="groovyTestCase">
+ * Integer[] orig = [10, 5, 20]
+ * def array = orig.shuffled()
+ * assert orig.size() == array.size()
+ * assert orig.every{ array.contains(it) }
+ * </pre>
+ *
+ * @param self an array
+ * @return the shuffled array
+ * @since 3.0.0
+ */
+ public static <T> T[] shuffled(T[] self) {
+ Random rnd = r;
+ if (rnd == null)
+ r = rnd = new Random(); // harmless race.
+ return shuffled(self, rnd);
+ }
+
+ /**
+ * Creates a new array containing the elements of the specified array but in a random
+ * order using the specified random instance as the source of randomness.
+ * <pre class="groovyTestCase">
+ * def r = new Random()
+ * Integer[] orig = [10, 5, 20]
+ * def array = orig.shuffled(r)
+ * assert orig.size() == array.size()
+ * assert orig.every{ array.contains(it) }
+ * </pre>
+ *
+ * @param self an array
+ * @return the shuffled array
+ * @since 3.0.0
+ */
+ public static <T> T[] shuffled(T[] self, Random rnd) {
+ T[] result = self.clone();
+ List<T> items = Arrays.asList(self);
+ Collections.shuffle(items, rnd);
+ System.arraycopy(items.toArray(), 0, result, 0, items.size());
+ return result;
+ }
+
//--------------------------------------------------------------------------
// size
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
* <pre class="groovyTestCase">
* boolean[] array = [true, false, true]
* assert array.size() == 3
@@ -5782,7 +6803,7 @@
}
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
*
* @param self a byte array
* @return the length of the array
@@ -5793,7 +6814,7 @@
}
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
*
* @param self a char array
* @return the length of the array
@@ -5804,7 +6825,7 @@
}
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
*
* @param self a short array
* @return the length of the array
@@ -5815,7 +6836,7 @@
}
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
*
* @param self an int array
* @return the length of the array
@@ -5826,7 +6847,7 @@
}
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
*
* @param self a long array
* @return the length of the array
@@ -5837,7 +6858,7 @@
}
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
*
* @param self a float array
* @return the length of the array
@@ -5848,7 +6869,7 @@
}
/**
- * Provide arrays with a {@code size} method similar to collections.
+ * Provides arrays with a {@code size} method similar to collections.
*
* @param self a double array
* @return the length of the array
@@ -5859,7 +6880,7 @@
}
/**
- * Provide the standard Groovy <code>size()</code> method for an array.
+ * Provides the standard Groovy <code>size()</code> method for an array.
*
* @param self an object array
* @return the length of the array
@@ -5872,9 +6893,150 @@
//--------------------------------------------------------------------------
// sort
+ /**
+ * Modifies this array so that its elements are in sorted order.
+ * The array items are assumed to be comparable.
+ *
+ * @param self the array to be sorted
+ * @return the sorted array
+ * @since 1.5.5
+ */
+ public static <T> T[] sort(T[] self) {
+ Arrays.sort(self, new NumberAwareComparator<>());
+ return self;
+ }
+
+ /**
+ * Sorts the given array into sorted order.
+ * The array items are assumed to be comparable.
+ * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
+ * array is returned and the original array remains unchanged.
+ * <pre class="groovyTestCase">
+ * def orig = ["hello","hi","Hey"] as String[]
+ * def sorted = orig.sort(false)
+ * assert orig == ["hello","hi","Hey"] as String[]
+ * assert sorted == ["Hey","hello","hi"] as String[]
+ * orig.sort(true)
+ * assert orig == ["Hey","hello","hi"] as String[]
+ * </pre>
+ *
+ * @param self the array to be sorted
+ * @param mutate false will always cause a new array to be created, true will mutate the array in place
+ * @return the sorted array
+ * @since 1.8.1
+ */
+ public static <T> T[] sort(T[] self, boolean mutate) {
+ T[] answer = mutate ? self : self.clone();
+ Arrays.sort(answer, new NumberAwareComparator<>());
+ return answer;
+ }
+
+ /**
+ * Sorts the given array into sorted order using the given comparator.
+ *
+ * @param self the array to be sorted
+ * @param comparator a Comparator used for the comparison
+ * @return the sorted array
+ * @since 1.5.5
+ */
+ public static <T> T[] sort(T[] self, Comparator<? super T> comparator) {
+ return sort(self, true, comparator);
+ }
+
+ /**
+ * Modifies this array so that its elements are in sorted order as determined by the given comparator.
+ * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
+ * array is returned and the original array remains unchanged.
+ * <pre class="groovyTestCase">
+ * def orig = ["hello","hi","Hey"] as String[]
+ * def sorted = orig.sort(false, String.CASE_INSENSITIVE_ORDER)
+ * assert orig == ["hello","hi","Hey"] as String[]
+ * assert sorted == ["hello","Hey","hi"] as String[]
+ * orig.sort(true, String.CASE_INSENSITIVE_ORDER)
+ * assert orig == ["hello","Hey","hi"] as String[]
+ * </pre>
+ *
+ * @param self the array containing elements to be sorted
+ * @param mutate false will always cause a new array to be created, true will mutate arrays in place
+ * @param comparator a Comparator used for the comparison
+ * @return a sorted array
+ * @since 1.8.1
+ */
+ public static <T> T[] sort(T[] self, boolean mutate, Comparator<? super T> comparator) {
+ T[] answer = mutate ? self : self.clone();
+ Arrays.sort(answer, comparator);
+ return answer;
+ }
+
+ /**
+ * Sorts the elements from this array into a newly created array using
+ * the Closure to determine the correct ordering.
+ * <p>
+ * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
+ * its two parameters for order, returning a negative integer, zero, or a positive integer when the
+ * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
+ * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
+ * which is then used for further comparison.
+ *
+ * @param self the array containing the elements to be sorted
+ * @param closure a Closure used to determine the correct ordering
+ * @return the sorted array
+ * @since 1.5.5
+ */
+ public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+ return sort(self, false, closure);
+ }
+
+ /**
+ * Modifies this array so that its elements are in sorted order using the Closure to determine the correct ordering.
+ * If mutate is false, a new array is returned and the original array remains unchanged.
+ * Otherwise, the original array is sorted in place and returned.
+ * <p>
+ * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
+ * its two parameters for order, returning a negative integer, zero, or a positive integer when the
+ * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
+ * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
+ * which is then used for further comparison.
+ * <pre class="groovyTestCase">
+ * def orig = ["hello","hi","Hey"] as String[]
+ * def sorted = orig.sort(false) { it.size() }
+ * assert orig == ["hello","hi","Hey"] as String[]
+ * assert sorted == ["hi","Hey","hello"] as String[]
+ * orig.sort(true) { it.size() }
+ * assert orig == ["hi","Hey","hello"] as String[]
+ * </pre>
+ *
+ * @param self the array to be sorted
+ * @param mutate false will always cause a new array to be created, true will mutate arrays in place
+ * @param closure a Closure used to determine the correct ordering
+ * @return the sorted array
+ * @since 1.8.1
+ */
+ public static <T> T[] sort(T[] self, boolean mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+ if (!mutate) self = self.clone();
+ Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
+ Arrays.sort(self, c);
+ return self;
+ }
+
//--------------------------------------------------------------------------
// split
+ /**
+ * Splits all items into two collections based on the closure condition.
+ * The first list contains all items which match the closure expression.
+ * The second list all those that don't.
+ *
+ * @param self an Array
+ * @param closure a closure condition
+ * @return a List whose first item is the accepted values and whose second item is the rejected values
+ * @since 2.5.0
+ */
+ public static <T> Collection<Collection<T>> split(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> closure) {
+ List<T> accept = new ArrayList<>(), reject = new ArrayList<>();
+ return DefaultGroovyMethods.split(closure, accept, reject, new ArrayIterator<>(self));
+ }
+
//--------------------------------------------------------------------------
// sum
@@ -6507,17 +7669,128 @@
return Arrays.copyOfRange(self, 1, self.length);
}
+ /**
+ * Returns the items from the array excluding the first item.
+ * <pre class="groovyTestCase">
+ * String[] strings = ["a", "b", "c"]
+ * def result = strings.tail()
+ * assert result.class.componentType == String
+ * String[] expected = ["b", "c"]
+ * assert result == expected
+ * </pre>
+ *
+ * @param self an array
+ * @return an array without its first element
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 1.7.3
+ */
+ public static <T> T[] tail(T[] self) {
+ Objects.requireNonNull(self);
+ throwNoSuchElementIfEmpty(self.length, "tail");
+ return Arrays.copyOfRange(self, 1, self.length);
+ }
+
//--------------------------------------------------------------------------
// take
+ /**
+ * Returns the first <code>num</code> elements from the head of this array.
+ * <pre class="groovyTestCase">
+ * String[] strings = [ 'a', 'b', 'c' ]
+ * assert strings.take( 0 ) == [] as String[]
+ * assert strings.take( 2 ) == [ 'a', 'b' ] as String[]
+ * assert strings.take( 5 ) == [ 'a', 'b', 'c' ] as String[]
+ * </pre>
+ *
+ * @param self the original array
+ * @param num the number of elements to take from this array
+ * @return an array consisting of the first <code>num</code> elements of this array,
+ * or else the whole array if it has less than <code>num</code> elements.
+ * @since 1.8.1
+ */
+ public static <T> T[] take(T[] self, int num) {
+ if (self.length == 0 || num <= 0) {
+ return createSimilarArray(self, 0);
+ }
+
+ if (self.length <= num) {
+ T[] ret = createSimilarArray(self, self.length);
+ System.arraycopy(self, 0, ret, 0, self.length);
+ return ret;
+ }
+
+ T[] ret = createSimilarArray(self, num);
+ System.arraycopy(self, 0, ret, 0, num);
+ return ret;
+ }
+
//--------------------------------------------------------------------------
// takeRight
+ /**
+ * Returns the last <code>num</code> elements from the tail of this array.
+ * <pre class="groovyTestCase">
+ * String[] strings = [ 'a', 'b', 'c' ]
+ * assert strings.takeRight( 0 ) == [] as String[]
+ * assert strings.takeRight( 2 ) == [ 'b', 'c' ] as String[]
+ * assert strings.takeRight( 5 ) == [ 'a', 'b', 'c' ] as String[]
+ * </pre>
+ *
+ * @param self the original array
+ * @param num the number of elements to take from this array
+ * @return an array consisting of the last <code>num</code> elements of this array,
+ * or else the whole array if it has less than <code>num</code> elements.
+ * @since 2.4.0
+ */
+ public static <T> T[] takeRight(T[] self, int num) {
+ if (self.length == 0 || num <= 0) {
+ return createSimilarArray(self, 0);
+ }
+
+ if (self.length <= num) {
+ T[] ret = createSimilarArray(self, self.length);
+ System.arraycopy(self, 0, ret, 0, self.length);
+ return ret;
+ }
+
+ T[] ret = createSimilarArray(self, num);
+ System.arraycopy(self, self.length - num, ret, 0, num);
+ return ret;
+ }
+
//--------------------------------------------------------------------------
// takeWhile
- //--------------------------------------------------------------------------
- // toArrayString
+ /**
+ * Returns the longest prefix of this array where each element
+ * passed to the given closure evaluates to true.
+ * <pre class="groovyTestCase">
+ * def nums = [ 1, 3, 2 ] as Integer[]
+ * assert nums.takeWhile{ it {@code <} 1 } == [] as Integer[]
+ * assert nums.takeWhile{ it {@code <} 3 } == [ 1 ] as Integer[]
+ * assert nums.takeWhile{ it {@code <} 4 } == [ 1, 3, 2 ] as Integer[]
+ * </pre>
+ *
+ * @param self the original array
+ * @param condition the closure that must evaluate to true to
+ * continue taking elements
+ * @return A prefix of the given array where each element passed to
+ * the given closure evaluates to true.
+ * @since 1.8.7
+ */
+ public static <T> T[] takeWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+ int num = 0;
+ BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
+ while (num < self.length) {
+ T value = self[num];
+ if (bcw.call(value)) {
+ num += 1;
+ } else {
+ break;
+ }
+ }
+ return take(self, num);
+ }
//--------------------------------------------------------------------------
// toList
@@ -6627,10 +7900,11 @@
}
/**
- * Allows conversion of arrays into a mutable List.
+ * Converts this array to a List of the same size, with each element
+ * added to the list.
*
* @param self an object array
- * @return A list containing the contents of this array.
+ * @return A mutable list containing the contents of this array.
* @since 1.0
*/
public static <T> List<T> toList(T[] self) {
@@ -6790,6 +8064,79 @@
//--------------------------------------------------------------------------
// toSorted
+ /**
+ * Returns a sorted version of the given array using the supplied comparator.
+ *
+ * @param self the array to be sorted
+ * @return the sorted array
+ * @see #toSorted(Object[], Comparator)
+ * @since 2.4.0
+ */
+ public static <T> T[] toSorted(T[] self) {
+ return toSorted(self, new NumberAwareComparator<>());
+ }
+
+ /**
+ * Returns a sorted version of the given array using the supplied comparator to determine the resulting order.
+ * <pre class="groovyTestCase">
+ * def sumDigitsComparator = [compare: { num1, num2 {@code ->} num1.toString().toList()*.toInteger().sum() {@code <=>} num2.toString().toList()*.toInteger().sum() }] as Comparator
+ * Integer[] nums = [9, 44, 222, 7000]
+ * def result = nums.toSorted(sumDigitsComparator)
+ * assert result instanceof Integer[]
+ * assert result == [222, 7000, 44, 9]
+ * </pre>
+ *
+ * @param self the array to be sorted
+ * @param comparator a Comparator used for the comparison
+ * @return the sorted array
+ * @since 2.4.0
+ */
+ public static <T> T[] toSorted(T[] self, Comparator<? super T> comparator) {
+ T[] answer = self.clone();
+ Arrays.sort(answer, comparator);
+ return answer;
+ }
+
+ /**
+ * Sorts the elements from this array into a newly created array using
+ * the Closure to determine the correct ordering.
+ * <p>
+ * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
+ * its two parameters for order, returning a negative integer, zero, or a positive integer when the
+ * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
+ * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
+ * which is then used for further comparison.
+ *
+ * @param self the array containing the elements to be sorted
+ * @param closure a Closure used to determine the correct ordering
+ * @return a sorted array
+ * @see #toSorted(Object[], Comparator)
+ * @since 2.4.0
+ */
+ public static <T> T[] toSorted(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+ return sort(self, false, closure);
+ }
+
+ //--------------------------------------------------------------------------
+ // toSpreadMap
+
+ /**
+ * Creates a spreadable map from this array.
+ * <p>
+ * @param self an object array
+ * @return a newly created SpreadMap
+ * @see groovy.lang.SpreadMap#SpreadMap(java.lang.Object[])
+ * @since 1.0
+ */
+ public static SpreadMap toSpreadMap(Object[] self) {
+ if (self == null)
+ throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because it is null.");
+ else if (self.length % 2 != 0)
+ throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because its size is not even.");
+ else
+ return new SpreadMap(self);
+ }
+
//--------------------------------------------------------------------------
// toString
@@ -6914,6 +8261,16 @@
return FormatHelper.toString(self);
}
+ /**
+ * Returns the string representation of the given array.
+ *
+ * @param self an array
+ * @return the string representation
+ * @since 1.0
+ */
+ public static String toString(Object[] self) {
+ return FormatHelper.toArrayString(self);
+ }
//--------------------------------------------------------------------------
// toUnique
@@ -7202,20 +8559,163 @@
//--------------------------------------------------------------------------
// union
+ /**
+ * Creates an object array containing elements from an original array plus those from a Collection.
+ * This is similar to {@link #plus(Object[], Collection)} but always return an Object array
+ * and so might be more applicable when adding heterogeneous arrays.
+ * <pre class="groovyTestCase">
+ * Integer[] a = [1, 2, 3]
+ * def result = a.union(['foo', 'bar'])
+ * assert result.class == Object[]
+ * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
+ * </pre>
+ *
+ * @param left the array
+ * @param right a Collection to be appended
+ * @return A new Object array containing left with right appended to it.
+ * @since 4.0.0
+ */
+ public static Object[] union(Object[] left, Collection<?> right) {
+ Object[] result = new Object[left.length + right.size()];
+ System.arraycopy(left, 0, result, 0, left.length);
+ int i = left.length;
+ for (Object t : right) {
+ result[i] = t;
+ i += 1;
+ }
+ return result;
+ }
+
+ /**
+ * Creates an Object array containing elements from an original array plus those from an Iterable.
+ * This is similar to {@link #plus(Object[], Iterable)} but always return an Object array
+ * and so might be more applicable when adding heterogeneous arrays.
+ * <pre class="groovyTestCase">
+ * class AbcIterable implements Iterable<String> {
+ * Iterator<String> iterator() { "abc".iterator() }
+ * }
+ * String[] array = ['x', 'y', 'z']
+ * def result = array.union(new AbcIterable())
+ * assert result.class == Object[]
+ * assert result == new Object[]{'x', 'y', 'z', 'a', 'b', 'c'}
+ * </pre>
+ *
+ * @param left the array
+ * @param right an Iterable to be appended
+ * @return A new Object array containing elements from left with those from right appended.
+ * @since 4.0.0
+ */
+ public static Object[] union(Object[] left, Iterable<?> right) {
+ return union(left, DefaultGroovyMethods.toList(right));
+ }
+
+ /**
+ * Creates an Object array as a union of two arrays.
+ * This is similar to {@link #plus(Object[], Object[])} but always return an Object array
+ * and so might be more applicable when adding heterogeneous arrays.
+ * <pre class="groovyTestCase">
+ * Integer[] a = [1, 2, 3]
+ * String[] b = ['foo', 'bar']
+ * def result = a.union(b)
+ * assert result.class == Object[]
+ * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
+ * </pre>
+ *
+ * @param left the left Array
+ * @param right the right Array
+ * @return A new Object array containing right appended to left.
+ * @since 4.0.0
+ */
+ public static Object[] union(Object[] left, Object[] right) {
+ Object[] result = new Object[left.length + right.length];
+ System.arraycopy(left, 0, result, 0, left.length);
+ System.arraycopy(right, 0, result, left.length, right.length);
+ return result;
+ }
+
+ /**
+ * Creates an Object array containing elements from an original array plus an additional appended element.
+ * This is similar to {@link #plus(Object[], Object)} but always return an Object array
+ * and so might be more applicable when adding heterogeneous arrays.
+ * <pre class="groovyTestCase">
+ * Integer[] a = [1, 2, 3]
+ * def result = a.union('foo')
+ * assert result.class == Object[]
+ * assert result == new Object[]{1, 2, 3, 'foo'}
+ * </pre>
+ *
+ * @param left the array
+ * @param right the value to append
+ * @return A new Object array containing left with right appended to it.
+ * @since 4.0.0
+ */
+ public static Object[] union(Object[] left, Object right) {
+ Object[] result = new Object[left.length + 1];
+ System.arraycopy(left, 0, result, 0, left.length);
+ result[left.length] = right;
+ return result;
+ }
+
//--------------------------------------------------------------------------
+ // withCollectedKeys
- private static void throwNoSuchElementIfEmpty(final int size, final String method) {
- if (size == 0) {
- throw new NoSuchElementException("Cannot access " + method + "() for an empty array");
- }
+ /**
+ * A variant of withCollectedKeys for arrays.
+ *
+ * @param values an array
+ * @param keyTransform a function for transforming array elements into values
+ * @return the collector with all transformed values added to it
+ * @see #withCollectedKeys(Iterable, Function)
+ * @since 5.0.0
+ */
+ public static <K, V> Map<K, V> withCollectedKeys(V[] values, Function<? super V, K> keyTransform) {
+ return DefaultGroovyMethods.withCollectedKeys(new ArrayIterator<>(values), new LinkedHashMap<>(), keyTransform);
}
- private static void throwUnsupportedOperationIfEmpty(final int size, final String method) {
- if (size == 0) {
- throw new UnsupportedOperationException("Accessing " + method + "() is unsupported for an empty array");
- }
+ /**
+ * A variant of withCollectedKeys for arrays.
+ *
+ * @param values an array
+ * @param collector the Map into which the transformed entries are put
+ * @param keyTransform a function for transforming array elements into values
+ * @return the collector with all transformed values added to it
+ * @see #withCollectedKeys(Iterable, Map, Function)
+ * @since 5.0.0
+ */
+ public static <K, V> Map<K, V> withCollectedKeys(V[] values, Map<K, V> collector, Function<? super V, K> keyTransform) {
+ return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(values), collector, keyTransform, Function.identity());
}
+ //--------------------------------------------------------------------------
+ // withCollectedValues
+
+ /**
+ * A variant of withCollectedValues for arrays.
+ *
+ * @param keys an array
+ * @param valueTransform a function for transforming array elements into values
+ * @return A map of the transformed entries.
+ * @since 5.0.0
+ */
+ public static <K, V> Map<K, V> withCollectedValues(K[] keys, Function<? super K, V> valueTransform) {
+ return DefaultGroovyMethods.withCollectedValues(new ArrayIterator<>(keys), new LinkedHashMap<>(), valueTransform);
+ }
+
+ /**
+ * A variant of withCollectedValues for arrays.
+ *
+ * @param keys an array
+ * @param collector the Map into which the transformed entries are put
+ * @param valueTransform a function for transforming array elements into values
+ * @return The collector with all transformed values added to it.
+ * @since 5.0.0
+ */
+ public static <K, V> Map<K, V> withCollectedValues(K[] keys, Map<K, V> collector, Function<? super K, V> valueTransform) {
+ return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(keys), collector, Function.identity(), valueTransform);
+ }
+
+ //--------------------------------------------------------------------------
+
/**
* Implements the getAt(int) method for primitive type arrays.
*
@@ -7271,4 +8771,16 @@
}
return answer;
}
+
+ private static void throwNoSuchElementIfEmpty(final int size, final String method) {
+ if (size == 0) {
+ throw new NoSuchElementException("Cannot access " + method + "() for an empty array");
+ }
+ }
+
+ private static void throwUnsupportedOperationIfEmpty(final int size, final String method) {
+ if (size == 0) {
+ throw new UnsupportedOperationException("Accessing " + method + "() is unsupported for an empty array");
+ }
+ }
}
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 82dc020..ae42b8a 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -96,7 +96,6 @@
import org.codehaus.groovy.runtime.typehandling.NumberMath;
import org.codehaus.groovy.tools.RootLoader;
import org.codehaus.groovy.transform.trait.Traits;
-import org.codehaus.groovy.util.ArrayIterable;
import org.codehaus.groovy.util.ArrayIterator;
import org.codehaus.groovy.util.IteratorBufferedIterator;
import org.codehaus.groovy.util.ListBufferedIterator;
@@ -3026,19 +3025,6 @@
}
/**
- * Collates an array.
- *
- * @param self an array
- * @param size the length of each sub-list in the returned list
- * @return a List containing the array values collated into sub-lists
- * @see #collate(Iterable, int)
- * @since 2.5.0
- */
- public static <T> List<List<T>> collate(T[] self, int size) {
- return collate(self, size, true);
- }
-
- /**
* Collates this iterable into sub-lists of length <code>size</code> stepping through the code <code>step</code>
* elements for each subList.
* Example:
@@ -3057,20 +3043,6 @@
}
/**
- * Collates an array into sub-lists.
- *
- * @param self an array
- * @param size the length of each sub-list in the returned list
- * @param step the number of elements to step through for each sub-list
- * @return a List containing the array elements collated into sub-lists
- * @see #collate(Iterable, int, int)
- * @since 2.5.0
- */
- public static <T> List<List<T>> collate(T[] self, int size, int step) {
- return collate(self, size, step, true);
- }
-
- /**
* Collates this iterable into sub-lists of length <code>size</code>. Any remaining elements in
* the iterable after the subdivision will be dropped if <code>keepRemainder</code> is false.
* Example:
@@ -3089,20 +3061,6 @@
}
/**
- * Collates this array into sub-lists.
- *
- * @param self an array
- * @param size the length of each sub-list in the returned list
- * @param keepRemainder if true, any remaining elements are returned as sub-lists. Otherwise they are discarded
- * @return a List containing the array elements collated into sub-lists
- * @see #collate(Iterable, int, boolean)
- * @since 2.5.0
- */
- public static <T> List<List<T>> collate(T[] self, int size, boolean keepRemainder) {
- return collate(self, size, size, keepRemainder);
- }
-
- /**
* Collates this iterable into sub-lists of length <code>size</code> stepping through the code <code>step</code>
* elements for each sub-list. Any remaining elements in the iterable after the subdivision will be dropped if
* <code>keepRemainder</code> is false.
@@ -3147,39 +3105,6 @@
}
/**
- * Collates this array into sub-lists.
- *
- * @param self an array
- * @param size the length of each sub-list in the returned list
- * @param step the number of elements to step through for each sub-list
- * @param keepRemainder if true, any remaining elements are returned as sub-lists. Otherwise they are discarded
- * @return a List containing the array elements collated into sub-lists
- * @since 2.5.0
- */
- public static <T> List<List<T>> collate(T[] self, int size, int step, boolean keepRemainder) {
- final List<List<T>> answer;
- if (size <= 0) {
- answer = new ArrayList<>(1);
- answer.add(Arrays.asList(self));
- } else {
- if (step == 0) throw new IllegalArgumentException("step cannot be zero");
- final int selfSize = self.length;
- answer = new ArrayList<>(step < 0 ? 1 : (selfSize / step + 1));
- for (int pos = 0; pos < selfSize && pos > -1; pos += step) {
- if (!keepRemainder && pos > selfSize - size) {
- break;
- }
- List<T> element = new ArrayList<>(size);
- for (int offs = pos; offs < pos + size && offs < selfSize; offs++) {
- element.add(self[offs]);
- }
- answer.add(element);
- }
- }
- return answer;
- }
-
- /**
* Iterates through this aggregate Object transforming each item into a new value using Closure.IDENTITY
* as a transformer, basically returning a list of items copied from the original object.
* <pre class="groovyTestCase">assert [1,2,3] == [1,2,3].iterator().collect()</pre>
@@ -3226,39 +3151,6 @@
}
/**
- * Iterates through this Array transforming each item into a new value using the
- * <code>transform</code> closure, returning a list of transformed values.
- *
- * @param self an Array
- * @param transform the closure used to transform each item of the Array
- * @return a List of the transformed values
- * @since 2.5.0
- */
- public static <E, T> List<T> collect(E[] self, @ClosureParams(FirstParam.Component.class) Closure<T> transform) {
- return collect(new ArrayIterator<>(self), transform);
- }
-
- /**
- * Iterates through this Array transforming each item into a new value using the <code>transform</code> closure
- * and adding it to the supplied <code>collector</code>.
- * <pre class="groovyTestCase">
- * Integer[] nums = [1,2,3]
- * List<Integer> answer = []
- * nums.collect(answer) { it * 2 }
- * assert [2,4,6] == answer
- * </pre>
- *
- * @param self an Array
- * @param collector the Collection to which the transformed values are added
- * @param transform the closure used to transform each item
- * @return the collector with all transformed values added to it
- * @since 2.5.0
- */
- public static <E, T, C extends Collection<T>> C collect(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends T> transform) {
- return collect(new ArrayIterator<>(self), collector, transform);
- }
-
- /**
* Iterates through this Iterator transforming each item into a new value using the
* <code>transform</code> closure, returning a list of transformed values.
*
@@ -3505,45 +3397,6 @@
}
/**
- * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
- * <p>
- * <pre class="groovyTestCase">
- * def nums = [1, 2, 3, 4, 5, 6] as Object[]
- * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
- * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
- * </pre>
- *
- * @param self an array
- * @param projection a projecting Closure returning a collection of items
- * @return a list created from the projected collections concatenated (flattened) together
- * @see #sum(Object[], groovy.lang.Closure)
- * @since 1.8.1
- */
- public static <T, E> List<T> collectMany(E[] self, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
- return collectMany(self, new ArrayList<>(), projection);
- }
-
- /**
- * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
- * <p>
- * <pre class="groovyTestCase">
- * def nums = [1, 2, 3, 4, 5, 6] as Object[]
- * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
- * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
- * </pre>
- *
- * @param self an array
- * @param collector an initial collection to add the projected items to
- * @param projection a projecting Closure returning a collection of items
- * @return the collector with the projected collections concatenated (flattened) to it
- * @see #sum(Object[], groovy.lang.Closure)
- * @since 1.8.1
- */
- public static <T, E, C extends Collection<T>> C collectMany(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
- return collectMany(new ArrayIterable<>(self), collector, projection);
- }
-
- /**
* Projects each item from a source iterator to a collection and concatenates (flattens) the resulting collections into a single list.
* <p>
* <pre class="groovyTestCase">
@@ -3833,39 +3686,6 @@
}
/**
- * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
- * The supplied collector map is used as the destination for transformed entries.
- *
- * @param self an array
- * @param collector the Map into which the transformed entries are put
- * @param keyTransform a function for transforming array elements into keys
- * @param valueTransform a function for transforming array elements into values
- * @return the collector with all transformed values added to it
- * @since 5.0.0
- */
- public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
- return collectEntries(new ArrayIterator<>(self), collector, keyTransform, valueTransform);
- }
-
- /**
- * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
- * <pre class="groovyTestCase">
- * String[] languages = ['Groovy', 'Java', 'Kotlin', 'Scala']
- * def firstLetter = s {@code ->} s[0]
- * assert languages.collectEntries(firstLetter, String::size) == [G:6, J:4, K:6, S:5]
- * </pre>
- *
- * @param self an array
- * @param keyTransform a function for transforming array elements into keys
- * @param valueTransform a function for transforming array elements into values
- * @return a Map of the transformed entries
- * @since 5.0.0
- */
- public static <K, V, E> Map<K, V> collectEntries(E[] self, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
- return collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), keyTransform, valueTransform);
- }
-
- /**
* A variant of collectEntries for Maps with separate functions for transforming the keys and values.
* The supplied collector map is used as the destination for transformed entries.
*
@@ -3966,31 +3786,6 @@
}
/**
- * A variant of withCollectedValues for arrays.
- *
- * @param keys an array
- * @param collector the Map into which the transformed entries are put
- * @param valueTransform a function for transforming array elements into values
- * @return the collector with all transformed values added to it
- * @since 5.0.0
- */
- public static <K, V> Map<K, V> withCollectedValues(K[] keys, Map<K, V> collector, Function<? super K, V> valueTransform) {
- return collectEntries(new ArrayIterator<>(keys), collector, Function.identity(), valueTransform);
- }
-
- /**
- * A variant of withCollectedValues for arrays.
- *
- * @param keys an array
- * @param valueTransform a function for transforming array elements into values
- * @return a Map of the transformed entries
- * @since 5.0.0
- */
- public static <K, V> Map<K, V> withCollectedValues(K[] keys, Function<? super K, V> valueTransform) {
- return withCollectedValues(new ArrayIterator<>(keys), new LinkedHashMap<>(), valueTransform);
- }
-
- /**
* Transform a Maps' values leaving the keys unchanged.
* Similar to {@link #withCollectedValues(Iterable, Map, Function)} but for Maps.
* <pre class="groovyTestCase">
@@ -4103,33 +3898,6 @@
}
/**
- * A variant of withCollectedKeys for arrays.
- *
- * @param values an array
- * @param collector the Map into which the transformed entries are put
- * @param keyTransform a function for transforming array elements into values
- * @return the collector with all transformed values added to it
- * @see #withCollectedKeys(Iterable, Map, Function)
- * @since 5.0.0
- */
- public static <K, V> Map<K, V> withCollectedKeys(V[] values, Map<K, V> collector, Function<? super V, K> keyTransform) {
- return collectEntries(new ArrayIterator<>(values), collector, keyTransform, Function.identity());
- }
-
- /**
- * A variant of withCollectedKeys for arrays.
- *
- * @param values an array
- * @param keyTransform a function for transforming array elements into values
- * @return the collector with all transformed values added to it
- * @see #withCollectedKeys(Iterable, Function)
- * @since 5.0.0
- */
- public static <K, V> Map<K, V> withCollectedKeys(V[] values, Function<? super V, K> keyTransform) {
- return withCollectedKeys(new ArrayIterator<>(values), new LinkedHashMap<>(), keyTransform);
- }
-
- /**
* Transform a Maps' keys leaving the values unchanged.
* Similar to {@link #withCollectedKeys(Iterable, Map, Function)} but for Maps.
* <pre class="groovyTestCase">
@@ -4224,86 +3992,6 @@
return collectEntries(self.iterator(), collector);
}
- /**
- * Iterates through this array transforming each item using the <code>transform</code> closure
- * and returning a map of the resulting transformed entries.
- * <pre class="groovyTestCase">
- * def letters = "abc"
- * def nums = [0, 1, 2] as Integer[]
- * // collect letters with index
- * assert nums.collectEntries( [:] ) { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
- * assert nums.collectEntries( [4:'d'] ) { index {@code ->}
- * [(index+1): letters[index]] } == [1:'a', 2:'b', 3:'c', 4:'d']
- * </pre>
- * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
- * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
- * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
- * If your collector Map doesn't support null keys or values, you might get a runtime error, e.g. NullPointerException or IllegalArgumentException.
- *
- * @param self an array
- * @param collector the Map into which the transformed entries are put
- * @param transform the closure used for transforming, which has an item from self as the parameter and
- * should return a Map.Entry, a Map or a two-element list containing the resulting key and value
- * @return the collector with all transformed values added to it
- * @see #collect(Map, Collection, Closure)
- * @since 1.7.9
- */
- @SuppressWarnings("unchecked")
- public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
- return collectEntries(new ArrayIterator<>(self), collector, transform);
- }
-
- /**
- * A variant of collectEntries using the identity closure as the transform.
- *
- * @param self an array
- * @param collector the Map into which the transformed entries are put
- * @return the collector with all transformed values added to it
- * @see #collectEntries(Object[], Map, Closure)
- * @since 1.8.5
- */
- public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector) {
- return collectEntries(self, collector, Closure.IDENTITY);
- }
-
- /**
- * Iterates through this array transforming each item using the <code>transform</code> closure
- * and returning a map of the resulting transformed entries.
- * <pre class="groovyTestCase">
- * def letters = "abc"
- * def nums = [0, 1, 2] as Integer[]
- * // collect letters with index using list style
- * assert nums.collectEntries { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
- * // collect letters with index using map style
- * assert nums.collectEntries { index {@code ->} [(index): letters[index]] } == [0:'a', 1:'b', 2:'c']
- * </pre>
- * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
- * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
- * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
- *
- * @param self a Collection
- * @param transform the closure used for transforming, which has an item from self as the parameter and
- * should return a Map.Entry, a Map or a two-element list containing the resulting key and value
- * @return a Map of the transformed entries
- * @see #collectEntries(Iterator, Map, Closure)
- * @since 1.7.9
- */
- public static <K, V, E> Map<K, V> collectEntries(E[] self, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
- return collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), transform);
- }
-
- /**
- * A variant of collectEntries using the identity closure as the transform.
- *
- * @param self an array
- * @return the collector with all transformed values added to it
- * @see #collectEntries(Object[], Closure)
- * @since 1.8.5
- */
- public static <K, V, E> Map<K, V> collectEntries(E[] self) {
- return collectEntries(self, Closure.IDENTITY);
- }
-
@SuppressWarnings("unchecked")
private static <K, V> void addEntry(Map<K, V> result, Object newEntry) {
if (newEntry instanceof Map) {
@@ -4393,30 +4081,6 @@
}
/**
- * Finds the first element in the array that matches the given closure condition.
- * Example:
- * <pre class="groovyTestCase">
- * def list = [1,2,3] as Integer[]
- * assert 2 == list.find { it {@code >} 1 }
- * assert null == list.find { it {@code >} 5 }
- * </pre>
- *
- * @param self an Array
- * @param condition a closure condition
- * @return the first element from the array that matches the condition or null if no element matches
- * @since 2.0
- */
- public static <T> T find(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
- BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
- for (T element : self) {
- if (bcw.call(element)) {
- return element;
- }
- }
- return null;
- }
-
- /**
* Finds the first item matching the IDENTITY Closure (i.e. matching Groovy truth).
* <p>
* Example:
@@ -4672,58 +4336,6 @@
}
/**
- * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
- * result is found and returning that result. If all are null, the defaultResult is returned.
- *
- * @param self an Array
- * @param defaultResult an Object that should be returned if all closure results are null
- * @param condition a closure that returns a non-null value to indicate that processing should stop and the value should be returned
- * @return the first non-null result from calling the closure, or the defaultValue
- * @since 2.5.0
- */
- public static <S, T, U extends T, V extends T> T findResult(S[] self, U defaultResult, @ClosureParams(FirstParam.Component.class) Closure<V> condition) {
- return findResult(new ArrayIterator<>(self), defaultResult, condition);
- }
-
- /**
- * Iterates through the Array stopping once the first non-null
- * result is found and returning that result. If all are null, the defaultResult is returned.
- *
- * @param self an Array
- * @param defaultResult an Object that should be returned if all elements are null
- * @return the first non-null result from calling the closure, or the defaultValue
- * @since 4.0.9
- */
- public static <T, U extends T, V extends T> T findResult(U[] self, V defaultResult) {
- return (T) findResult(new ArrayIterator<>(self), defaultResult, Closure.IDENTITY);
- }
-
- /**
- * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
- * result is found and returning that result. If all results are null, null is returned.
- *
- * @param self an Array
- * @param condition a closure that returns a non-null value to indicate that processing should stop and the value should be returned
- * @return the first non-null result from calling the closure, or null
- * @since 2.5.0
- */
- public static <S, T> T findResult(S[] self, @ClosureParams(FirstParam.Component.class) Closure<T> condition) {
- return findResult(new ArrayIterator<>(self), condition);
- }
-
- /**
- * Iterates through the Array stopping once the first non-null
- * result is found and returning that result. If all results are null, null is returned.
- *
- * @param self an Array
- * @return the first non-null result from calling the closure, or null
- * @since 4.0.9
- */
- public static <T> T findResult(T[] self) {
- return (T) findResult(new ArrayIterator<>(self), Closure.IDENTITY);
- }
-
- /**
* Returns the first non-null closure result found by passing each map entry to the closure, otherwise null is returned.
* If the closure takes two parameters, the entry key and value are passed.
* If the closure takes one parameter, the Map.Entry object is passed.
@@ -4839,30 +4451,6 @@
}
/**
- * Iterates through the Array transforming items using the supplied closure
- * and collecting any non-null results.
- *
- * @param self an Array
- * @param filteringTransform a Closure that should return either a non-null transformed value or null for items which should be discarded
- * @return the list of non-null transformed values
- * @since 2.5.0
- */
- public static <T, U> Collection<T> findResults(U[] self, @ClosureParams(FirstParam.Component.class) Closure<T> filteringTransform) {
- return findResults(new ArrayIterator<>(self), filteringTransform);
- }
-
- /**
- * Iterates through the Array collecting any non-null results.
- *
- * @param self an Array
- * @return the list of non-null values
- * @since 4.0.9
- */
- public static <T> Collection<T> findResults(T[] self) {
- return findResults(self, Closure.IDENTITY);
- }
-
- /**
* Iterates through the map transforming items using the supplied closure
* and collecting any non-null results.
* If the closure takes two parameters, the entry key and value are passed.
@@ -4986,22 +4574,6 @@
}
/**
- * Finds all elements of the array matching the given Closure condition.
- * <pre class="groovyTestCase">
- * def items = [1,2,3,4] as Integer[]
- * assert [2,4] == items.findAll { it % 2 == 0 }
- * </pre>
- *
- * @param self an array
- * @param condition a closure condition
- * @return a list of matching values
- * @since 2.0
- */
- public static <T> List<T> findAll(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
- return findMany(new ArrayList<>(), new ArrayIterator<>(self), condition);
- }
-
- /**
* Finds the items matching the IDENTITY Closure (i.e. matching Groovy truth).
* <p>
* Example:
@@ -5056,24 +4628,6 @@
}
/**
- * Finds the elements of the array matching the IDENTITY Closure (i.e. matching Groovy truth).
- * <p>
- * Example:
- * <pre class="groovyTestCase">
- * def items = [1, 2, 0, false, true, '', 'foo', [], [4, 5], null] as Object[]
- * assert items.findAll() == [1, 2, true, 'foo', [4, 5]]
- * </pre>
- *
- * @param self an array
- * @return a List of the truthy values
- * @see Closure#IDENTITY
- * @since 2.0
- */
- public static <T> List<T> findAll(T[] self) {
- return findAll(self, Closure.IDENTITY);
- }
-
- /**
* Finds all items matching the closure condition.
*
* @param self an Object with an Iterator returning its values
@@ -5104,7 +4658,7 @@
return findAll(self, Closure.IDENTITY);
}
- private static <T, C extends Collection<T>> C findMany(C collector, Iterator<? extends T> iter, Closure<?> closure) {
+ static <T, C extends Collection<T>> C findMany(C collector, Iterator<? extends T> iter, Closure<?> closure) {
BooleanClosureWrapper test = new BooleanClosureWrapper(closure);
while (iter.hasNext()) {
T value = iter.next();
@@ -5376,24 +4930,7 @@
return split(closure, accept, reject, iter);
}
- /**
- * Splits all items into two collections based on the closure condition.
- * The first list contains all items which match the closure expression.
- * The second list all those that don't.
- *
- * @param self an Array
- * @param closure a closure condition
- * @return a List whose first item is the accepted values and whose second item is the rejected values
- * @since 2.5.0
- */
- public static <T> Collection<Collection<T>> split(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
- List<T> accept = new ArrayList<>();
- List<T> reject = new ArrayList<>();
- Iterator<T> iter = new ArrayIterator<>(self);
- return split(closure, accept, reject, iter);
- }
-
- private static <T> Collection<Collection<T>> split(Closure closure, Collection<T> accept, Collection<T> reject, Iterator<T> iter) {
+ static <T> Collection<Collection<T>> split(Closure closure, Collection<T> accept, Collection<T> reject, Iterator<T> iter) {
List<Collection<T>> answer = new ArrayList<>();
BooleanClosureWrapper bcw = new BooleanClosureWrapper(closure);
while (iter.hasNext()) {
@@ -5619,28 +5156,6 @@
}
/**
- * Sorts all array members into groups determined by the supplied mapping closure.
- * The closure should return the key that this item should be grouped by. The returned
- * LinkedHashMap will have an entry for each distinct key returned from the closure,
- * with each value being a list of items for that group.
- * <p>
- * Example usage:
- * <pre class="groovyTestCase">
- * Integer[] items = [1,2,3,4,5,6]
- * assert [0:[2,4,6], 1:[1,3,5]] == items.groupBy { it % 2 }
- * </pre>
- *
- * @param self an array to group
- * @param closure a closure mapping entries on keys
- * @return a new Map grouped by keys
- * @see #groupBy(Iterable, Closure)
- * @since 2.2.0
- */
- public static <K, T> Map<K, List<T>> groupBy(T[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
- return groupBy(Arrays.asList(self), closure);
- }
-
- /**
* Sorts all Iterable members into (sub)groups determined by the supplied
* mapping closures. Each closure should return the key that this item
* should be grouped by. The returned LinkedHashMap will have an entry for each
@@ -5691,21 +5206,6 @@
}
/**
- * Sorts all array members into (sub)groups determined by the supplied
- * mapping closures as per the Iterable variant of this method.
- *
- * @param self an array to group
- * @param closures an array of closures, each mapping entries on keys
- * @return a new Map grouped by keys on each criterion
- * @see #groupBy(Iterable, Object...)
- * @see Closure#IDENTITY
- * @since 2.2.0
- */
- public static Map groupBy(Object[] self, Object... closures) {
- return groupBy(new ArrayIterable<>(self), closures);
- }
-
- /**
* Sorts all Iterable members into (sub)groups determined by the supplied
* mapping closures. Each closure should return the key that this item
* should be grouped by. The returned LinkedHashMap will have an entry for each
@@ -5744,21 +5244,6 @@
}
/**
- * Sorts all array members into (sub)groups determined by the supplied
- * mapping closures as per the list variant of this method.
- *
- * @param self an array to group
- * @param closures a list of closures, each mapping entries on keys
- * @return a new Map grouped by keys on each criterion
- * @see Closure#IDENTITY
- * @see #groupBy(Iterable, List)
- * @since 2.2.0
- */
- public static Map groupBy(Object[] self, List<Closure> closures) {
- return groupBy(new ArrayIterable<>(self), closures);
- }
-
- /**
* Sorts all collection members into groups determined by the supplied mapping
* closure and counts the group size. The closure should return the key that each
* item should be grouped by. The returned Map will have an entry for each
@@ -7824,24 +7309,6 @@
}
/**
- * Creates a spreadable map from this array.
- * <p>
- * @param self an object array
- * @return a newly created SpreadMap
- * @see groovy.lang.SpreadMap#SpreadMap(java.lang.Object[])
- * @see #toSpreadMap(java.util.Map)
- * @since 1.0
- */
- public static SpreadMap toSpreadMap(Object[] self) {
- if (self == null)
- throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because it is null.");
- else if (self.length % 2 != 0)
- throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because its size is not even.");
- else
- return new SpreadMap(self);
- }
-
- /**
* Creates a spreadable map from this list.
* <p>
* @param self a list
@@ -8361,44 +7828,6 @@
}
/**
- * Modifies this array so that its elements are in sorted order.
- * The array items are assumed to be comparable.
- *
- * @param self the array to be sorted
- * @return the sorted array
- * @since 1.5.5
- */
- public static <T> T[] sort(T[] self) {
- Arrays.sort(self, new NumberAwareComparator<>());
- return self;
- }
-
- /**
- * Sorts the given array into sorted order.
- * The array items are assumed to be comparable.
- * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
- * array is returned and the original array remains unchanged.
- * <pre class="groovyTestCase">
- * def orig = ["hello","hi","Hey"] as String[]
- * def sorted = orig.sort(false)
- * assert orig == ["hello","hi","Hey"] as String[]
- * assert sorted == ["Hey","hello","hi"] as String[]
- * orig.sort(true)
- * assert orig == ["Hey","hello","hi"] as String[]
- * </pre>
- *
- * @param self the array to be sorted
- * @param mutate false will always cause a new array to be created, true will mutate the array in place
- * @return the sorted array
- * @since 1.8.1
- */
- public static <T> T[] sort(T[] self, boolean mutate) {
- T[] answer = mutate ? self : self.clone();
- Arrays.sort(answer, new NumberAwareComparator<>());
- return answer;
- }
-
- /**
* Sorts the given iterator items into a sorted iterator. The items are
* assumed to be comparable. The original iterator will become
* exhausted of elements after completing this method call.
@@ -8453,43 +7882,6 @@
}
/**
- * Sorts the given array into sorted order using the given comparator.
- *
- * @param self the array to be sorted
- * @param comparator a Comparator used for the comparison
- * @return the sorted array
- * @since 1.5.5
- */
- public static <T> T[] sort(T[] self, Comparator<? super T> comparator) {
- return sort(self, true, comparator);
- }
-
- /**
- * Modifies this array so that its elements are in sorted order as determined by the given comparator.
- * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
- * array is returned and the original array remains unchanged.
- * <pre class="groovyTestCase">
- * def orig = ["hello","hi","Hey"] as String[]
- * def sorted = orig.sort(false, String.CASE_INSENSITIVE_ORDER)
- * assert orig == ["hello","hi","Hey"] as String[]
- * assert sorted == ["hello","Hey","hi"] as String[]
- * orig.sort(true, String.CASE_INSENSITIVE_ORDER)
- * assert orig == ["hello","Hey","hi"] as String[]
- * </pre>
- *
- * @param self the array containing elements to be sorted
- * @param mutate false will always cause a new array to be created, true will mutate arrays in place
- * @param comparator a Comparator used for the comparison
- * @return a sorted array
- * @since 1.8.1
- */
- public static <T> T[] sort(T[] self, boolean mutate, Comparator<? super T> comparator) {
- T[] answer = mutate ? self : self.clone();
- Arrays.sort(answer, comparator);
- return answer;
- }
-
- /**
* Sorts the given iterator items into a sorted iterator using the Closure to determine the correct ordering.
* The original iterator will be fully processed after the method call.
* <p>
@@ -8510,57 +7902,6 @@
}
/**
- * Sorts the elements from this array into a newly created array using
- * the Closure to determine the correct ordering.
- * <p>
- * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
- * its two parameters for order, returning a negative integer, zero, or a positive integer when the
- * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
- * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
- * which is then used for further comparison.
- *
- * @param self the array containing the elements to be sorted
- * @param closure a Closure used to determine the correct ordering
- * @return the sorted array
- * @since 1.5.5
- */
- public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
- return sort(self, false, closure);
- }
-
- /**
- * Modifies this array so that its elements are in sorted order using the Closure to determine the correct ordering.
- * If mutate is false, a new array is returned and the original array remains unchanged.
- * Otherwise, the original array is sorted in place and returned.
- * <p>
- * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
- * its two parameters for order, returning a negative integer, zero, or a positive integer when the
- * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
- * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
- * which is then used for further comparison.
- * <pre class="groovyTestCase">
- * def orig = ["hello","hi","Hey"] as String[]
- * def sorted = orig.sort(false) { it.size() }
- * assert orig == ["hello","hi","Hey"] as String[]
- * assert sorted == ["hi","Hey","hello"] as String[]
- * orig.sort(true) { it.size() }
- * assert orig == ["hi","Hey","hello"] as String[]
- * </pre>
- *
- * @param self the array to be sorted
- * @param mutate false will always cause a new array to be created, true will mutate arrays in place
- * @param closure a Closure used to determine the correct ordering
- * @return the sorted array
- * @since 1.8.1
- */
- public static <T> T[] sort(T[] self, boolean mutate, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
- if (!mutate) self = self.clone();
- Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
- Arrays.sort(self, c);
- return self;
- }
-
- /**
* Sorts this Iterable using the given Closure to determine the correct ordering. If the Iterable is a List,
* it is sorted in place and returned. Otherwise, the elements are first placed
* into a new list which is then sorted and returned - leaving the original Iterable unchanged.
@@ -8772,59 +8113,6 @@
}
/**
- * Returns a sorted version of the given array using the supplied comparator.
- *
- * @param self the array to be sorted
- * @return the sorted array
- * @see #toSorted(Object[], Comparator)
- * @since 2.4.0
- */
- public static <T> T[] toSorted(T[] self) {
- return toSorted(self, new NumberAwareComparator<>());
- }
-
- /**
- * Returns a sorted version of the given array using the supplied comparator to determine the resulting order.
- * <pre class="groovyTestCase">
- * def sumDigitsComparator = [compare: { num1, num2 {@code ->} num1.toString().toList()*.toInteger().sum() {@code <=>} num2.toString().toList()*.toInteger().sum() }] as Comparator
- * Integer[] nums = [9, 44, 222, 7000]
- * def result = nums.toSorted(sumDigitsComparator)
- * assert result instanceof Integer[]
- * assert result == [222, 7000, 44, 9]
- * </pre>
- *
- * @param self the array to be sorted
- * @param comparator a Comparator used for the comparison
- * @return the sorted array
- * @since 2.4.0
- */
- public static <T> T[] toSorted(T[] self, Comparator<? super T> comparator) {
- T[] answer = self.clone();
- Arrays.sort(answer, comparator);
- return answer;
- }
-
- /**
- * Sorts the elements from this array into a newly created array using
- * the Closure to determine the correct ordering.
- * <p>
- * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
- * its two parameters for order, returning a negative integer, zero, or a positive integer when the
- * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
- * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
- * which is then used for further comparison.
- *
- * @param self the array containing the elements to be sorted
- * @param closure a Closure used to determine the correct ordering
- * @return a sorted array
- * @see #toSorted(Object[], Comparator)
- * @since 2.4.0
- */
- public static <T> T[] toSorted(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
- return sort(self, false, closure);
- }
-
- /**
* Sorts the elements from the given map into a new ordered map using
* a {@link NumberAwareComparator} on map entry values to determine the resulting order.
* {@code NumberAwareComparator} has special treatment for numbers but otherwise uses the
@@ -9097,25 +8385,6 @@
}
/**
- * Returns the last item from the array.
- * <pre class="groovyTestCase">
- * def array = [3, 4, 2].toArray()
- * assert array.last() == 2
- * </pre>
- *
- * @param self an array
- * @return the last item from the array
- * @throws NoSuchElementException if you try to access last() for an empty array
- * @since 1.7.3
- */
- public static <T> T last(T[] self) {
- if (self.length == 0) {
- throw new NoSuchElementException("Cannot access last() element from an empty Array");
- }
- return self[self.length - 1];
- }
-
- /**
* Returns the first item from the List.
* <pre class="groovyTestCase">
* def list = [3, 4, 2]
@@ -9162,25 +8431,6 @@
}
/**
- * Returns the first item from the array.
- * <pre class="groovyTestCase">
- * def array = [3, 4, 2].toArray()
- * assert array.first() == 3
- * </pre>
- *
- * @param self an array
- * @return the first item from the array
- * @throws NoSuchElementException if you try to access first() for an empty array
- * @since 1.7.3
- */
- public static <T> T first(T[] self) {
- if (self.length == 0) {
- throw new NoSuchElementException("Cannot access first() element from an empty array");
- }
- return self[0];
- }
-
- /**
* Returns the first item from the Iterable.
* <pre class="groovyTestCase">
* def set = [3, 4, 2] as LinkedHashSet
@@ -9217,20 +8467,6 @@
}
/**
- * Returns the first item from the Object array.
- * <pre class="groovyTestCase">def array = [3, 4, 2].toArray()
- * assert array.head() == 3</pre>
- *
- * @param self an array
- * @return the first item from the Object array
- * @throws NoSuchElementException if you try to access head() for an empty array
- * @since 1.7.3
- */
- public static <T> T head(T[] self) {
- return first(self);
- }
-
- /**
* Returns the items from the List excluding the first item.
* <pre class="groovyTestCase">
* def list = [3, 4, 2]
@@ -9301,28 +8537,6 @@
}
/**
- * Returns the items from the array excluding the first item.
- * <pre class="groovyTestCase">
- * String[] strings = ["a", "b", "c"]
- * def result = strings.tail()
- * assert result.class.componentType == String
- * String[] expected = ["b", "c"]
- * assert result == expected
- * </pre>
- *
- * @param self an array
- * @return an array without its first element
- * @throws NoSuchElementException if you try to access tail() for an empty array
- * @since 1.7.3
- */
- public static <T> T[] tail(T[] self) {
- if (self.length == 0) {
- throw new NoSuchElementException("Cannot access tail() for an empty array");
- }
- return Arrays.copyOfRange(self, 1, self.length);
- }
-
- /**
* Returns the original iterator after throwing away the first element.
*
* @param self the original iterator
@@ -9470,27 +8684,6 @@
}
/**
- * Returns the items from the Object array excluding the last item.
- * <pre class="groovyTestCase">
- * String[] strings = ["a", "b", "c"]
- * def result = strings.init()
- * assert result.length == 2
- * assert strings.class.componentType == String
- * </pre>
- *
- * @param self an array
- * @return an array without its last element
- * @throws NoSuchElementException if you try to access init() for an empty array
- * @since 2.4.0
- */
- public static <T> T[] init(T[] self) {
- if (self.length == 0) {
- throw new NoSuchElementException("Cannot access init() for an empty Object array");
- }
- return Arrays.copyOfRange(self, 0, self.length - 1);
- }
-
- /**
* Returns the first <code>num</code> elements from the head of this List.
* <pre class="groovyTestCase">
* def strings = [ 'a', 'b', 'c' ]
@@ -9529,37 +8722,6 @@
}
/**
- * Returns the first <code>num</code> elements from the head of this array.
- * <pre class="groovyTestCase">
- * String[] strings = [ 'a', 'b', 'c' ]
- * assert strings.take( 0 ) == [] as String[]
- * assert strings.take( 2 ) == [ 'a', 'b' ] as String[]
- * assert strings.take( 5 ) == [ 'a', 'b', 'c' ] as String[]
- * </pre>
- *
- * @param self the original array
- * @param num the number of elements to take from this array
- * @return an array consisting of the first <code>num</code> elements of this array,
- * or else the whole array if it has less than <code>num</code> elements.
- * @since 1.8.1
- */
- public static <T> T[] take(T[] self, int num) {
- if (self.length == 0 || num <= 0) {
- return createSimilarArray(self, 0);
- }
-
- if (self.length <= num) {
- T[] ret = createSimilarArray(self, self.length);
- System.arraycopy(self, 0, ret, 0, self.length);
- return ret;
- }
-
- T[] ret = createSimilarArray(self, num);
- System.arraycopy(self, 0, ret, 0, num);
- return ret;
- }
-
- /**
* Returns the first <code>num</code> elements from the head of this Iterable.
* <pre class="groovyTestCase">
* def strings = [ 'a', 'b', 'c' ]
@@ -9705,37 +8867,6 @@
}
/**
- * Returns the last <code>num</code> elements from the tail of this array.
- * <pre class="groovyTestCase">
- * String[] strings = [ 'a', 'b', 'c' ]
- * assert strings.takeRight( 0 ) == [] as String[]
- * assert strings.takeRight( 2 ) == [ 'b', 'c' ] as String[]
- * assert strings.takeRight( 5 ) == [ 'a', 'b', 'c' ] as String[]
- * </pre>
- *
- * @param self the original array
- * @param num the number of elements to take from this array
- * @return an array consisting of the last <code>num</code> elements of this array,
- * or else the whole array if it has less than <code>num</code> elements.
- * @since 2.4.0
- */
- public static <T> T[] takeRight(T[] self, int num) {
- if (self.length == 0 || num <= 0) {
- return createSimilarArray(self, 0);
- }
-
- if (self.length <= num) {
- T[] ret = createSimilarArray(self, self.length);
- System.arraycopy(self, 0, ret, 0, self.length);
- return ret;
- }
-
- T[] ret = createSimilarArray(self, num);
- System.arraycopy(self, self.length - num, ret, 0, num);
- return ret;
- }
-
- /**
* Returns the last <code>num</code> elements from the tail of this Iterable.
* <pre class="groovyTestCase">
* def strings = [ 'a', 'b', 'c' ]
@@ -9881,38 +9012,6 @@
}
/**
- * Drops the given number of elements from the head of this array
- * if they are available.
- * <pre class="groovyTestCase">
- * String[] strings = [ 'a', 'b', 'c' ]
- * assert strings.drop( 0 ) == [ 'a', 'b', 'c' ] as String[]
- * assert strings.drop( 2 ) == [ 'c' ] as String[]
- * assert strings.drop( 5 ) == [] as String[]
- * </pre>
- *
- * @param self the original array
- * @param num the number of elements to drop from this array
- * @return an array consisting of all elements of this array except the
- * first <code>num</code> ones, or else the empty array, if this
- * array has less than <code>num</code> elements.
- * @since 1.8.1
- */
- public static <T> T[] drop(T[] self, int num) {
- if (self.length <= num) {
- return createSimilarArray(self, 0);
- }
- if (num <= 0) {
- T[] ret = createSimilarArray(self, self.length);
- System.arraycopy(self, 0, ret, 0, self.length);
- return ret;
- }
-
- T[] ret = createSimilarArray(self, self.length - num);
- System.arraycopy(self, num, ret, 0, self.length - num);
- return ret;
- }
-
- /**
* Drops the given number of key/value pairs from the head of this map if they are available.
* <pre class="groovyTestCase">
* def strings = [ 'a':10, 'b':20, 'c':30 ]
@@ -10122,38 +9221,6 @@
}
/**
- * Drops the given number of elements from the tail of this array
- * if they are available.
- * <pre class="groovyTestCase">
- * String[] strings = [ 'a', 'b', 'c' ]
- * assert strings.dropRight( 0 ) == [ 'a', 'b', 'c' ] as String[]
- * assert strings.dropRight( 2 ) == [ 'a' ] as String[]
- * assert strings.dropRight( 5 ) == [] as String[]
- * </pre>
- *
- * @param self the original array
- * @param num the number of elements to drop from this array
- * @return an array consisting of all elements of this array except the
- * last <code>num</code> ones, or else the empty array, if this
- * array has less than <code>num</code> elements.
- * @since 2.4.0
- */
- public static <T> T[] dropRight(T[] self, int num) {
- if (self.length <= num) {
- return createSimilarArray(self, 0);
- }
- if (num <= 0) {
- T[] ret = createSimilarArray(self, self.length);
- System.arraycopy(self, 0, ret, 0, self.length);
- return ret;
- }
-
- T[] ret = createSimilarArray(self, self.length - num);
- System.arraycopy(self, 0, ret, 0, self.length - num);
- return ret;
- }
-
- /**
* Returns the longest prefix of this list where each element
* passed to the given closure condition evaluates to true.
* Similar to {@link #takeWhile(Iterable, groovy.lang.Closure)}
@@ -10266,37 +9333,6 @@
}
/**
- * Returns the longest prefix of this array where each element
- * passed to the given closure evaluates to true.
- * <pre class="groovyTestCase">
- * def nums = [ 1, 3, 2 ] as Integer[]
- * assert nums.takeWhile{ it {@code <} 1 } == [] as Integer[]
- * assert nums.takeWhile{ it {@code <} 3 } == [ 1 ] as Integer[]
- * assert nums.takeWhile{ it {@code <} 4 } == [ 1, 3, 2 ] as Integer[]
- * </pre>
- *
- * @param self the original array
- * @param condition the closure that must evaluate to true to
- * continue taking elements
- * @return a prefix of the given array where each element passed to
- * the given closure evaluates to true
- * @since 1.8.7
- */
- public static <T> T[] takeWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
- int num = 0;
- BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
- while (num < self.length) {
- T value = self[num];
- if (bcw.call(value)) {
- num += 1;
- } else {
- break;
- }
- }
- return take(self, num);
- }
-
- /**
* Returns the longest prefix of elements in this iterator where
* each element passed to the given condition closure evaluates to true.
* <p>
@@ -10478,38 +9514,6 @@
}
/**
- * Create a suffix of the given array by dropping as many elements as possible from the
- * front of the original array such that calling the given closure condition evaluates to
- * true when passed each of the dropped elements.
- * <pre class="groovyTestCase">
- * def nums = [ 1, 3, 2 ] as Integer[]
- * assert nums.dropWhile{ it {@code <=} 3 } == [ ] as Integer[]
- * assert nums.dropWhile{ it {@code <} 3 } == [ 3, 2 ] as Integer[]
- * assert nums.dropWhile{ it != 2 } == [ 2 ] as Integer[]
- * assert nums.dropWhile{ it == 0 } == [ 1, 3, 2 ] as Integer[]
- * </pre>
- *
- * @param self the original array
- * @param condition the closure that must evaluate to true to
- * continue dropping elements
- * @return the shortest suffix of the given array such that the given closure condition
- * evaluates to true for each element dropped from the front of the array
- * @since 1.8.7
- */
- public static <T> T[] dropWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
- int num = 0;
- BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
- while (num < self.length) {
- if (bcw.call(self[num])) {
- num += 1;
- } else {
- break;
- }
- }
- return drop(self, num);
- }
-
- /**
* Creates an Iterator that returns a suffix of the elements from an original Iterator. As many elements
* as possible are dropped from the front of the original Iterator such that calling the given closure
* condition evaluates to true when passed each of the dropped elements.
@@ -10997,97 +10001,6 @@
}
/**
- * Randomly reorders the elements of the specified array.
- * <pre class="groovyTestCase">
- * Integer[] array = [10, 5, 20]
- * def origSize = array.size()
- * def items = array.toList()
- * array.shuffle()
- * assert array.size() == origSize
- * assert items.every{ array.contains(it) }
- * </pre>
- *
- * @param self an array
- * @since 3.0.0
- */
- public static <T> void shuffle(T[] self) {
- Random rnd = r;
- if (rnd == null)
- r = rnd = new Random(); // harmless race.
- shuffle(self, rnd);
- }
-
- private static Random r;
-
- /**
- * Randomly reorders the elements of the specified array using the
- * specified random instance as the source of randomness.
- * <pre class="groovyTestCase">
- * def r = new Random()
- * Integer[] array = [10, 5, 20]
- * def origSize = array.size()
- * def items = array.toList()
- * array.shuffle(r)
- * assert array.size() == origSize
- * assert items.every{ array.contains(it) }
- * </pre>
- *
- * @param self an array
- * @since 3.0.0
- */
- public static <T> void shuffle(T[] self, Random rnd) {
- for (int i = 0; i < self.length-1; i++) {
- int nextIndex = rnd.nextInt(self.length);
- T tmp = self[i];
- self[i] = self[nextIndex];
- self[nextIndex] = tmp;
- }
- }
-
- /**
- * Creates a new array containing the elements of the specified array but in a random order.
- * <pre class="groovyTestCase">
- * Integer[] orig = [10, 5, 20]
- * def array = orig.shuffled()
- * assert orig.size() == array.size()
- * assert orig.every{ array.contains(it) }
- * </pre>
- *
- * @param self an array
- * @return the shuffled array
- * @since 3.0.0
- */
- public static <T> T[] shuffled(T[] self) {
- Random rnd = r;
- if (rnd == null)
- r = rnd = new Random(); // harmless race.
- return shuffled(self, rnd);
- }
-
- /**
- * Creates a new array containing the elements of the specified array but in a random
- * order using the specified random instance as the source of randomness.
- * <pre class="groovyTestCase">
- * def r = new Random()
- * Integer[] orig = [10, 5, 20]
- * def array = orig.shuffled(r)
- * assert orig.size() == array.size()
- * assert orig.every{ array.contains(it) }
- * </pre>
- *
- * @param self an array
- * @return the shuffled array
- * @since 3.0.0
- */
- public static <T> T[] shuffled(T[] self, Random rnd) {
- T[] result = self.clone();
- List<T> items = Arrays.asList(self);
- Collections.shuffle(items, rnd);
- System.arraycopy(items.toArray(), 0, result, 0, items.size());
- return result;
- }
-
- /**
* Creates a view list with reversed order, and the order of original list will not change.
* <pre class="groovyTestCase">
* def list = ["a", 6, true]
@@ -11169,45 +10082,6 @@
}
/**
- * Creates a new array containing items which are the same as this array but in reverse order.
- *
- * @param self an array
- * @return an array containing the reversed items
- * @see #reverse(Object[], boolean)
- * @since 1.5.5
- */
- public static <T> T[] reverse(T[] self) {
- return reverse(self, false);
- }
-
- /**
- * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
- * Otherwise, a new array containing the reversed items is produced.
- *
- * <pre class="groovyTestCase">
- * def array = new Object[] {1,2,3}
- * def yarra = array.reverse(true)
- * assert array == 3..1
- * assert yarra == 3..1
- *
- * yarra = array.reverse(false)
- * assert array == 3..1
- * assert yarra == 1..3
- * </pre>
- *
- * @param self an array
- * @param mutate {@code true} if the array itself should be reversed in place, {@code false} if a new array should be created
- * @return an array containing the reversed items
- *
- * @since 1.8.1
- */
- public static <T> T[] reverse(T[] self, boolean mutate) {
- if (!mutate) self = self.clone();
- Collections.reverse(Arrays.asList(self));
- return self;
- }
-
- /**
* Reverses the iterator. The original iterator will become
* exhausted of elements after determining the reversed values.
* A new iterator for iterating through the reversed values is returned.
@@ -11221,231 +10095,6 @@
}
/**
- * Create an array as a union of two arrays.
- * <pre class="groovyTestCase">
- * Integer[] a = [1, 2, 3]
- * Integer[] b = [4, 5, 6]
- * def result = a + b
- * assert result.class == Integer[]
- * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
- *
- * Number[] c = [-1, 0.9, null]
- * result = c + a
- * assert result.class == Number[]
- * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
- *
- * result = a + c
- * assert result.class == Integer[]
- * assert result == new Integer[]{1, 2, 3, -1, 0, null}
- *
- * Date[] d = [new Date()]
- * // improper type arguments; Date can't be coerced to Integer
- * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + d }
- * </pre>
- *
- * @param left the left Array
- * @param right the right Array
- * @return A new array containing right appended to left.
- * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
- * @since 1.8.7
- */
- @SuppressWarnings("unchecked")
- public static <T> T[] plus(final T[] left, final Object[] right) {
- T[] result = Arrays.copyOf(left, left.length + right.length);
- T[] temp = (T[]) DefaultTypeTransformation.castToType(right, left.getClass());
- System.arraycopy(temp, 0, result, left.length, temp.length);
- return result;
- }
-
- /**
- * Create an array containing elements from an original array plus an additional appended element.
- * <pre class="groovyTestCase">
- * Integer[] a = [1, 2, 3]
- * def result = a + 4
- * assert result.class == Integer[]
- * assert result == new Integer[]{1, 2, 3, 4}
- *
- * result = a + 5.5d
- * assert result.class == Integer[]
- * assert result == new Integer[]{1, 2, 3, 5}
- *
- * // improper type arguments; Date can't be coerced to Integer
- * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + new Date() }
- * </pre>
- *
- * @param left the array
- * @param right the value to append
- * @return A new array containing left with right appended to it.
- * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
- * @since 1.8.7
- */
- @SuppressWarnings("unchecked")
- public static <T> T[] plus(final T[] left, final Object right) {
- T[] result = Arrays.copyOf(left, left.length + 1);
- result[left.length] = (T) DefaultTypeTransformation.castToType(right, left.getClass().getComponentType());
- return result;
- }
-
- /**
- * Create an array containing elements from an original array plus those from a Collection.
- * <pre class="groovyTestCase">
- * Integer[] a = [1, 2, 3]
- * def result = a + [4, 5, 6]
- * assert result.class == Integer[]
- * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
- *
- * Number[] c = [-1, 0.9, null]
- * result = c + [1, 2, 3]
- * assert result.class == Number[]
- * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
- *
- * result = a + [-1, 0.9, null]
- * assert result.class == Integer[]
- * assert result == new Integer[]{1, 2, 3, -1, 0, null}
- *
- * // improper type arguments; Date can't be coerced to Integer
- * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + [new Date()] }
- * </pre>
- *
- * @param left the array
- * @param right a Collection to be appended
- * @return A new array containing left with right appended to it.
- * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
- * @since 1.8.7
- */
- @SuppressWarnings("unchecked")
- public static <T> T[] plus(final T[] left, final Collection<?> right) {
- T[] result = Arrays.copyOf(left, left.length + right.size());
- int i = left.length;
- Class<?> leftType = left.getClass().getComponentType();
- for (Object t : right) {
- result[i] = (T) DefaultTypeTransformation.castToType(t, leftType);
- i += 1;
- }
- return result;
- }
-
- /**
- * Create an array containing elements from an original array plus those from an Iterable.
- * <pre class="groovyTestCase">
- * class AbcIterable implements Iterable<String> {
- * Iterator<String> iterator() { "abc".iterator() }
- * }
- * String[] array = ['x', 'y', 'z']
- * def result = array + new AbcIterable()
- * assert result.class == String[]
- * assert result == new String[]{'x', 'y', 'z', 'a', 'b', 'c'}
- * </pre>
- *
- * @param left the array
- * @param right an Iterable to be appended
- * @return A new array containing elements from left with those from right appended.
- * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
- * @see #union(Object[], Iterable)
- * @since 1.8.7
- */
- public static <T> T[] plus(final T[] left, final Iterable<?> right) {
- return plus(left, toList(right));
- }
-
- /**
- * Create an Object array as a union of two arrays.
- * This is similar to {@link #plus(Object[], Object[])} but always return an Object array
- * and so might be more applicable when adding heterogeneous arrays.
- * <pre class="groovyTestCase">
- * Integer[] a = [1, 2, 3]
- * String[] b = ['foo', 'bar']
- * def result = a.union(b)
- * assert result.class == Object[]
- * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
- * </pre>
- *
- * @param left the left Array
- * @param right the right Array
- * @return A new Object array containing right appended to left.
- * @since 4.0.0
- */
- public static Object[] union(final Object[] left, final Object[] right) {
- Object[] result = new Object[left.length + right.length];
- System.arraycopy(left, 0, result, 0, left.length);
- System.arraycopy(right, 0, result, left.length, right.length);
- return result;
- }
-
- /**
- * Create an Object array containing elements from an original array plus an additional appended element.
- * This is similar to {@link #plus(Object[], Object)} but always return an Object array
- * and so might be more applicable when adding heterogeneous arrays.
- * <pre class="groovyTestCase">
- * Integer[] a = [1, 2, 3]
- * def result = a.union('foo')
- * assert result.class == Object[]
- * assert result == new Object[]{1, 2, 3, 'foo'}
- * </pre>
- *
- * @param left the array
- * @param right the value to append
- * @return A new Object array containing left with right appended to it.
- * @since 4.0.0
- */
- public static Object[] union(final Object[] left, final Object right) {
- Object[] result = new Object[left.length + 1];
- System.arraycopy(left, 0, result, 0, left.length);
- result[left.length] = right;
- return result;
- }
-
- /**
- * Create an object array containing elements from an original array plus those from a Collection.
- * This is similar to {@link #plus(Object[], Collection)} but always return an Object array
- * and so might be more applicable when adding heterogeneous arrays.
- * <pre class="groovyTestCase">
- * Integer[] a = [1, 2, 3]
- * def result = a.union(['foo', 'bar'])
- * assert result.class == Object[]
- * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
- * </pre>
- *
- * @param left the array
- * @param right a Collection to be appended
- * @return A new Object array containing left with right appended to it.
- * @since 4.0.0
- */
- public static Object[] union(final Object[] left, final Collection<?> right) {
- Object[] result = new Object[left.length + right.size()];
- System.arraycopy(left, 0, result, 0, left.length);
- int i = left.length;
- for (Object t : right) {
- result[i] = t;
- i += 1;
- }
- return result;
- }
-
- /**
- * Create an Object array containing elements from an original array plus those from an Iterable.
- * This is similar to {@link #plus(Object[], Iterable)} but always return an Object array
- * and so might be more applicable when adding heterogeneous arrays.
- * <pre class="groovyTestCase">
- * class AbcIterable implements Iterable<String> {
- * Iterator<String> iterator() { "abc".iterator() }
- * }
- * String[] array = ['x', 'y', 'z']
- * def result = array.union(new AbcIterable())
- * assert result.class == Object[]
- * assert result == new Object[]{'x', 'y', 'z', 'a', 'b', 'c'}
- * </pre>
- *
- * @param left the array
- * @param right an Iterable to be appended
- * @return A new Object array containing elements from left with those from right appended.
- * @since 4.0.0
- */
- public static Object[] union(final Object[] left, final Iterable<?> right) {
- return union(left, toList(right));
- }
-
- /**
* Create a Collection as a union of two collections. If the left collection
* is a Set, then the returned collection will be a Set otherwise a List.
* This operation will always create a new object for the result,
@@ -12073,21 +10722,6 @@
}
/**
- * Chops the array into pieces, returning lists with sizes corresponding to the supplied chop sizes.
- * If the array isn't large enough, truncated (possibly empty) pieces are returned.
- * Using a chop size of -1 will cause that piece to contain all remaining items from the array.
- *
- * @param self an Array to be chopped
- * @param chopSizes the sizes for the returned pieces
- * @return a list of lists chopping the original array elements into pieces determined by chopSizes
- * @see #collate(Object[], int) to chop a list into pieces of a fixed size
- * @since 2.5.2
- */
- public static <T> List<List<T>> chop(T[] self, int... chopSizes) {
- return chop(Arrays.asList(self), chopSizes);
- }
-
- /**
* Chops the Iterable into pieces, returning lists with sizes corresponding to the supplied chop sizes.
* If the Iterable isn't large enough, truncated (possibly empty) pieces are returned.
* Using a chop size of -1 will cause that piece to contain all remaining items from the Iterable.
@@ -12137,20 +10771,6 @@
}
/**
- * Determines if the contents of this array are equal to the
- * contents of the given list, in the same order. This returns
- * <code>false</code> if either collection is <code>null</code>.
- *
- * @param left an array
- * @param right the List being compared
- * @return true if the contents of both collections are equal
- * @since 1.5.0
- */
- public static boolean equals(Object[] left, List right) {
- return coercedEquals(left, right);
- }
-
- /**
* Determines if the contents of this list are equal to the
* contents of the given array in the same order. This returns
* <code>false</code> if either collection is <code>null</code>.
@@ -12187,7 +10807,7 @@
return true;
}
- private static boolean coercedEquals(Object o1, Object o2) {
+ static boolean coercedEquals(Object o1, Object o2) {
if (o1 instanceof Comparable) {
if (!(o2 instanceof Comparable && numberAwareCompareTo((Comparable) o1, (Comparable) o2) == 0)) {
return false;
@@ -12434,67 +11054,6 @@
}
/**
- * Create a new array composed of the elements of the first array minus the
- * elements of the given Iterable.
- * <pre class="groovyTestCase">
- * Integer[] ints = [1, 2, 3, 1]
- * List<Integer> nope = [1, 3]
- * def result = ints - nope
- * assert result.class == Integer[]
- * assert result == new Integer[]{2}
- *
- * Integer[] none = []
- * result = none - 123
- * assert result !== none
- * assert result.length == 0
- * assert result.class == Integer[]
- * </pre>
- *
- * @param self an array
- * @param removeMe an Iterable of elements to remove
- * @return an array with the supplied elements removed
- * @since 1.5.5
- */
- public static <T> T[] minus(final T[] self, final Iterable removeMe) {
- Collection<T> temp = minus((Iterable<T>) toList(self), removeMe);
- return temp.toArray(createSimilarArray(self, temp.size()));
- }
-
- /**
- * Create a new array composed of the elements of the first array minus the
- * elements of the given array.
- * <pre class="groovyTestCase">
- * Integer[] ints = [1, 2, 3, 1]
- * Integer[] nope = [1, 3]
- * def result = ints - nope
- * assert result.class == Integer[]
- * assert result == new Integer[]{2}
- *
- * Integer[] none = []
- * result = none - 123
- * assert result !== none
- * assert result.length == 0
- * assert result.class == Integer[]
- * </pre>
- *
- * @param self an array
- * @param removeMe an array of elements to remove
- * @return an array with the supplied elements removed
- * @since 1.5.5
- */
- public static <T> T[] minus(final T[] self, final Object[] removeMe) {
- switch (removeMe.length) {
- case 0:
- return self.clone();
- case 1:
- return minus(self, removeMe[0]);
- default:
- Collection<T> temp = minus((Collection<T>) toList(self), Arrays.asList(removeMe));
- return (T[]) temp.toArray(createSimilarArray(self, temp.size()));
- }
- }
-
- /**
* Create a List composed of the elements of the first list minus
* every occurrence of elements of the given Collection.
* <pre class="groovyTestCase">assert [1, "a", true, true, false, 5.3] - [true, 5.3] == [1, "a", false]</pre>
@@ -12684,43 +11243,6 @@
}
/**
- * Create a new array composed of the elements of the given array minus every occurrence the given object.
- * <pre class="groovyTestCase">
- * Integer[] ints = [1, 2, 3, 1]
- * def result = ints - 1
- * assert result.class == Integer[]
- * assert result == new Integer[]{2, 3}
- *
- * Integer[] none = []
- * result = none - '1'
- * assert result !== none
- * assert result.length == 0
- * assert result.class == Integer[]
- * </pre>
- *
- * @param self an array
- * @param removeMe an element to remove from the array
- * @return a new array with the operand removed
- * @since 1.5.5
- */
- public static <T> T[] minus(final T[] self, final Object removeMe) {
- int i = 0, n = self.length;
- T[] result = createSimilarArray(self, n);
-
- for (T t : self) {
- if (!coercedEquals(t, removeMe)) {
- result[i] = t;
- i += 1;
- }
- }
- if (i != n) {
- result = Arrays.copyOfRange(result, 0, i);
- }
-
- return result;
- }
-
- /**
* Create a Map composed of the entries of the first map minus the
* entries of the given map.
*
@@ -12814,19 +11336,6 @@
return (SortedSet<?>) flatten((Collection<?>) self);
}
- /**
- * Flatten an array. This array and any nested arrays or
- * collections have their contents (recursively) added to the new collection.
- *
- * @param self an Array to flatten
- * @return a flattened Collection
- * @since 1.6.0
- */
- public static Collection flatten(Object[] self) {
- return flatten(toList(self), new ArrayList());
- }
-
- @SuppressWarnings("unchecked")
private static Collection flatten(Iterable elements, Collection addTo) {
for (Object element : elements) {
if (element instanceof Collection) {
@@ -13207,21 +11716,6 @@
}
/**
- * Checks whether the array contains the given value.
- *
- * @param self the array we are searching
- * @param value the value being searched for
- * @return true if the array contains the value
- * @since 1.8.6
- */
- public static boolean contains(Object[] self, Object value) {
- for (Object next : self) {
- if (DefaultTypeTransformation.compareEqual(value, next)) return true;
- }
- return false;
- }
-
- /**
* Returns the string representation of the given map.
*
* @param self a Map
@@ -13300,31 +11794,6 @@
}
/**
- * Returns the string representation of this array's contents.
- *
- * @param self an Object[]
- * @return the string representation
- * @see #toArrayString(java.lang.Object[])
- * @since 1.0
- */
- public static String toString(Object[] self) {
- return toArrayString(self);
- }
-
- /**
- * Returns the string representation of the given array. The string
- * displays the contents of the array, similar to an array literal, i.e.
- * <code>{1, 2, "a"}</code>.
- *
- * @param self an Object[]
- * @return the string representation
- * @since 1.0
- */
- public static String toArrayString(Object[] self) {
- return (self == null) ? "null" : FormatHelper.toArrayString(self);
- }
-
- /**
* Create a String representation of this object.
* @param value an object
* @return a string.
@@ -16178,6 +14647,71 @@
return ArrayGroovyMethods.average(self, closure);
}
+ @Deprecated(since = "5.0.0")
+ public static <T> List<List<T>> chop(T[] self, int... chopSizes) {
+ return ArrayGroovyMethods.chop(self, chopSizes);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> List<List<T>> collate(T[] self, int size) {
+ return ArrayGroovyMethods.collate(self, size);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> List<List<T>> collate(T[] self, int size, int step) {
+ return ArrayGroovyMethods.collate(self, size, step);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> List<List<T>> collate(T[] self, int size, boolean keepRemainder) {
+ return ArrayGroovyMethods.collate(self, size, keepRemainder);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> List<List<T>> collate(T[] self, int size, int step, boolean keepRemainder) {
+ return ArrayGroovyMethods.collate(self, size, step, keepRemainder);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <E, T> List<T> collect(E[] self, @ClosureParams(FirstParam.Component.class) Closure<T> transform) {
+ return ArrayGroovyMethods.collect(self, transform);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <E, T, C extends Collection<T>> C collect(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends T> transform) {
+ return ArrayGroovyMethods.collect(self, collector, transform);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <K, V, E> Map<K, V> collectEntries(E[] self) {
+ return ArrayGroovyMethods.collectEntries(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector) {
+ return ArrayGroovyMethods.collectEntries(self, collector);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+ return ArrayGroovyMethods.collectEntries(self, transform);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+ return ArrayGroovyMethods.collectEntries(self, collector, transform);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T, E> List<T> collectMany(E[] self, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+ return ArrayGroovyMethods.collectMany(self, projection);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T, E, C extends Collection<T>> C collectMany(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+ return ArrayGroovyMethods.collectMany(self, collector, projection);
+ }
+
@Deprecated
public static <T, K, V> Collection<T> collectMany$$bridge(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<? extends Collection<? extends T>> projection) {
return collectMany(self, projection);
@@ -16224,6 +14758,11 @@
}
@Deprecated(since = "5.0.0")
+ public static boolean contains(Object[] self, Object value) {
+ return ArrayGroovyMethods.contains(self, value);
+ }
+
+ @Deprecated(since = "5.0.0")
public static Number count(boolean[] self, Object value) {
return ArrayGroovyMethods.count(self, value);
}
@@ -16279,6 +14818,21 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T[] drop(T[] self, int num) {
+ return ArrayGroovyMethods.drop(self, num);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] dropRight(T[] self, int num) {
+ return ArrayGroovyMethods.dropRight(self, num);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] dropWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+ return ArrayGroovyMethods.dropWhile(self, condition);
+ }
+
+ @Deprecated(since = "5.0.0")
public static <T> T[] each(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
return ArrayGroovyMethods.each(self, closure);
}
@@ -16304,10 +14858,30 @@
}
@Deprecated(since = "5.0.0")
+ public static boolean equals(Object[] left, List right) {
+ return coercedEquals(left, right);
+ }
+
+ @Deprecated(since = "5.0.0")
public static <T> boolean every(T[] self, @ClosureParams(FirstParam.Component.class) Closure predicate) {
return ArrayGroovyMethods.every(self, predicate);
}
+ @Deprecated(since = "5.0.0")
+ public static <T> T find(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
+ return ArrayGroovyMethods.find(self, condition);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> List<T> findAll(T[] self) {
+ return ArrayGroovyMethods.findAll(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> List<T> findAll(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
+ return ArrayGroovyMethods.findAll(self, condition);
+ }
+
@Deprecated
public static Collection findAll$$bridge(Object self) {
return findAll(self);
@@ -16360,6 +14934,41 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T findResult(T[] self) {
+ return ArrayGroovyMethods.findResult(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T, U extends T, V extends T> T findResult(U[] self, V defaultResult) {
+ return ArrayGroovyMethods.findResult(self, defaultResult);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <S, T> T findResult(S[] self, @ClosureParams(FirstParam.Component.class) Closure<T> condition) {
+ return ArrayGroovyMethods.findResult(self, condition);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <S, T, U extends T, V extends T> T findResult(S[] self, U defaultResult, @ClosureParams(FirstParam.Component.class) Closure<V> condition) {
+ return ArrayGroovyMethods.findResult(self, defaultResult, condition);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> Collection<T> findResults(T[] self) {
+ return ArrayGroovyMethods.findResults(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T, U> Collection<T> findResults(U[] self, @ClosureParams(FirstParam.Component.class) Closure<T> filteringTransform) {
+ return ArrayGroovyMethods.findResults(self, filteringTransform);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T first(T[] self) {
+ return ArrayGroovyMethods.first(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static Collection flatten(boolean[] self) {
return ArrayGroovyMethods.flatten(self);
}
@@ -16400,6 +15009,11 @@
}
@Deprecated(since = "5.0.0")
+ public static Collection flatten(Object[] self) {
+ return ArrayGroovyMethods.flatten(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static List<Boolean> getAt(boolean[] self, Range range) {
return ArrayGroovyMethods.getAt(self, range);
}
@@ -16640,6 +15254,26 @@
}
@Deprecated(since = "5.0.0")
+ public static <K, T> Map<K, List<T>> groupBy(T[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
+ return ArrayGroovyMethods.groupBy(self, closure);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static Map groupBy(Object[] self, Object... closures) {
+ return ArrayGroovyMethods.groupBy(self, closures);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static Map groupBy(Object[] self, List<Closure> closures) {
+ return ArrayGroovyMethods.groupBy(self, closures);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T head(T[] self) {
+ return ArrayGroovyMethods.head(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static Map<Integer, Integer> indexed(int[] self) {
return ArrayGroovyMethods.indexed(self);
}
@@ -16670,6 +15304,11 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T[] init(T[] self) {
+ return ArrayGroovyMethods.init(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static <E,T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
return ArrayGroovyMethods.inject(self, closure);
}
@@ -16730,6 +15369,11 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T last(T[] self) {
+ return ArrayGroovyMethods.last(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static int max(int[] self) {
return ArrayGroovyMethods.max(self);
}
@@ -16789,6 +15433,41 @@
return ArrayGroovyMethods.min(self, closure);
}
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] minus(T[] self, Iterable removeMe) {
+ return ArrayGroovyMethods.minus(self, removeMe);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] minus(T[] self, Object[] removeMe) {
+ return ArrayGroovyMethods.minus(self, removeMe);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] minus(T[] self, Object removeMe) {
+ return ArrayGroovyMethods.minus(self, removeMe);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] plus(T[] left, Collection<?> right) {
+ return ArrayGroovyMethods.plus(left, right);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] plus(T[] left, Iterable<?> right) {
+ return ArrayGroovyMethods.plus(left, right);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] plus(T[] left, Object[] right) {
+ return ArrayGroovyMethods.plus(left, right);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] plus(T[] left, Object right) {
+ return ArrayGroovyMethods.plus(left, right);
+ }
+
/**
* Implements the getAt(int) method for primitive type arrays.
*
@@ -16847,11 +15526,41 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T[] reverse(T[] self) {
+ return ArrayGroovyMethods.reverse(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] reverse(T[] self, boolean mutate) {
+ return ArrayGroovyMethods.reverse(self, mutate);
+ }
+
+ @Deprecated(since = "5.0.0")
public static <T> T[] reverseEach(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
return ArrayGroovyMethods.reverseEach(self, closure);
}
@Deprecated(since = "5.0.0")
+ public static <T> void shuffle(T[] self) {
+ ArrayGroovyMethods.shuffle(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> void shuffle(T[] self, Random rnd) {
+ ArrayGroovyMethods.shuffle(self, rnd);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] shuffled(T[] self) {
+ return ArrayGroovyMethods.shuffled(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] shuffled(T[] self, Random rnd) {
+ return ArrayGroovyMethods.shuffled(self, rnd);
+ }
+
+ @Deprecated(since = "5.0.0")
public static int size(boolean[] self) {
return self.length;
}
@@ -16897,6 +15606,41 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T[] sort(T[] self) {
+ return ArrayGroovyMethods.sort(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] sort(T[] self, boolean mutate) {
+ return ArrayGroovyMethods.sort(self, mutate);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] sort(T[] self, Comparator<? super T> comparator) {
+ return ArrayGroovyMethods.sort(self, comparator);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] sort(T[] self, boolean mutate, Comparator<? super T> comparator) {
+ return ArrayGroovyMethods.sort(self, mutate, comparator);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure closure) {
+ return ArrayGroovyMethods.sort(self, closure);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] sort(T[] self, boolean mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure closure) {
+ return ArrayGroovyMethods.sort(self, mutate, closure);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> Collection<Collection<T>> split(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
+ return ArrayGroovyMethods.split(self, closure);
+ }
+
+ @Deprecated(since = "5.0.0")
public static byte sum(byte[] self) {
return ArrayGroovyMethods.sum(self);
}
@@ -17032,6 +15776,31 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T[] tail(T[] self) {
+ return ArrayGroovyMethods.tail(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] take(T[] self, int num) {
+ return ArrayGroovyMethods.take(self, num);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] takeRight(T[] self, int num) {
+ return ArrayGroovyMethods.takeRight(self, num);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] takeWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
+ return ArrayGroovyMethods.takeWhile(self, condition);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static String toArrayString(Object[] self) {
+ return FormatHelper.toArrayString(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static List<Boolean> toList(boolean[] self) {
return ArrayGroovyMethods.toList(self);
}
@@ -17117,6 +15886,26 @@
}
@Deprecated(since = "5.0.0")
+ public static <T> T[] toSorted(T[] self) {
+ return ArrayGroovyMethods.toSorted(self);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] toSorted(T[] self, Comparator<? super T> comparator) {
+ return ArrayGroovyMethods.toSorted(self, comparator);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static <T> T[] toSorted(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure closure) {
+ return ArrayGroovyMethods.toSorted(self, closure);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static SpreadMap toSpreadMap(Object[] self) {
+ return ArrayGroovyMethods.toSpreadMap(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static String toString(boolean[] self) {
return ArrayGroovyMethods.toString(self);
}
@@ -17157,6 +15946,11 @@
}
@Deprecated(since = "5.0.0")
+ public static String toString(Object[] self) {
+ return ArrayGroovyMethods.toString(self);
+ }
+
+ @Deprecated(since = "5.0.0")
public static <T> T[] toUnique(T[] self) {
return ArrayGroovyMethods.toUnique(self);
}
@@ -17186,6 +15980,26 @@
return ArrayGroovyMethods.transpose(self);
}
+ @Deprecated(since = "5.0.0")
+ public static Object[] union(final Object[] left, final Collection<?> right) {
+ return ArrayGroovyMethods.union(left, right);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static Object[] union(final Object[] left, final Iterable<?> right) {
+ return ArrayGroovyMethods.union(left, right);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static Object[] union(final Object[] left, final Object[] right) {
+ return ArrayGroovyMethods.union(left, right);
+ }
+
+ @Deprecated(since = "5.0.0")
+ public static Object[] union(final Object[] left, final Object right) {
+ return ArrayGroovyMethods.union(left, right);
+ }
+
@Deprecated
public static <T> List<T> withDefault$$bridge(List<T> self, @ClosureParams(value=SimpleType.class, options = "int") Closure<T> init) {
return withDefault(self, init);