@@ -4094,6 +4094,31 @@ public static void downto(BigDecimal self, Number to, @ClosureParams(FirstParam.
40944094 ") to downto() cannot be greater than the value (" + self + ") it's called on."); }
40954095 }
40964096
4097+ //--------------------------------------------------------------------------
4098+ // drain
4099+
4100+ /**
4101+ * Drain the queue of elements, returning them as a list.
4102+ * <pre class="groovyTestCase">
4103+ * def letters = new PriorityQueue(String.CASE_INSENSITIVE_ORDER)
4104+ * letters.addAll(['Z', 'y', 'X', 'a', 'B', 'c'])
4105+ * assert letters.toList() == ['a', 'B', 'c', 'Z', 'X', 'y']
4106+ * assert letters.drain() == ['a', 'B', 'c', 'X', 'y', 'Z']
4107+ * assert letters.empty
4108+ * </pre>
4109+ *
4110+ * @param self a Queue
4111+ * @return a List of elements removed from the head of the queue
4112+ * @since 5.0.0
4113+ */
4114+ public static <T> List<T> drain(Queue<T> self) {
4115+ List<T> answer = new ArrayList<>();
4116+ while (!self.isEmpty()) {
4117+ answer.add(self.poll());
4118+ }
4119+ return answer;
4120+ }
4121+
40974122 //--------------------------------------------------------------------------
40984123 // drop
40994124
@@ -13430,7 +13455,7 @@ public static <T> Iterator<T> sort(Iterator<T> self, Comparator<? super T> compa
1343013455 * </pre>
1343113456 *
1343213457 * @param self the Iterable to be sorted
13433- * @param mutate false will always cause a new list to be created, true will mutate lists in place
13458+ * @param mutate false causes a new list to be created, true will mutate lists in place
1343413459 * @param comparator a Comparator used for the comparison
1343513460 * @return a sorted List
1343613461 * @since 2.2.0
@@ -13441,6 +13466,78 @@ public static <T> List<T> sort(Iterable<T> self, boolean mutate, Comparator<? su
1344113466 return list;
1344213467 }
1344313468
13469+ /**
13470+ * Sorts elements in the given index range using the given Closure to determine the ordering.
13471+ * If mutate is true, it is sorted in place and returned. Otherwise, the elements are first placed
13472+ * into a new list which is then sorted and returned, leaving the original List unchanged.
13473+ *
13474+ * <pre class="groovyTestCase">
13475+ * // a list with some odd then even numbers
13476+ * def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
13477+ *
13478+ * // sort odds ascending, evens descending
13479+ * assert nums.sort(0..4, false) { it }.sort(5..9, false) { -it }
13480+ * == [1, 3, 5, 7, 9, 8, 6, 4, 2, 0]
13481+ * // sort odds descending, evens descending
13482+ * assert nums.sort(0..<5, false) { -it }.sort(4<..<10, false) { -it }
13483+ * == [9, 7, 5, 3, 1, 8, 6, 4, 2, 0]
13484+ * // sort odds descending, evens ascending
13485+ * assert nums.sort(0..<5, false) { -it }.sort(5..-1, false) { it }
13486+ * == [9, 7, 5, 3, 1, 0, 2, 4, 6, 8]
13487+ * // leave first and last numbers, sort remaining odds ascending, remaining evens descending
13488+ * assert nums.sort(1..4, false) { it }.sort(5..-2, false) { -it }
13489+ * == [5, 1, 3, 7, 9, 8, 6, 4, 0, 2]
13490+ * // leave first and last numbers, sort remaining odds descending, remaining evens ascending
13491+ * assert nums.sort(1..4, false) { -it }.sort(5..-2, false) { it }
13492+ * == [5, 9, 7, 3, 1, 0, 4, 6, 8, 2]
13493+ * // leave first and last odds and evens, sort remaining odds ascending, remaining evens descending
13494+ * assert nums.sort(0<..<4, false) { it }.sort(5<..<9, false) { -it }
13495+ * == [5, 1, 7, 9, 3, 4, 8, 6, 0, 2]
13496+ * // leave first and last odds and evens, sort remaining odds descending, remaining evens ascending
13497+ * assert nums.sort(0<..<4, false) { -it }.sort(5<..<-1, false) { it }
13498+ * == [5, 9, 7, 1, 3, 4, 0, 6, 8, 2]
13499+ * </pre>
13500+ *
13501+ * @param self the List to be sorted
13502+ * @param range the inclusive range of index values over which to sort
13503+ * @param mutate false causes a new list to be created, true will mutate lists in place
13504+ * @param closure a Closure used to determine the correct ordering
13505+ * @return a sorted List
13506+ * @since 5.0.0
13507+ */
13508+ public static <T> List<T> sort(List<T> self, IntRange range, boolean mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
13509+ Objects.requireNonNull(self);
13510+ RangeInfo info = range.subListBorders(self.size());
13511+ Objects.checkFromToIndex(info.from, info.to, self.size());
13512+ T[] a = (T[]) self.toArray();
13513+ Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
13514+ Arrays.sort(a, info.from, info.to, c);
13515+ if (!mutate) {
13516+ return Arrays.asList(a);
13517+ }
13518+ ListIterator<T> i = self.listIterator();
13519+ for (T e : a) {
13520+ i.next();
13521+ i.set(e);
13522+ }
13523+ return self;
13524+ }
13525+
13526+ /**
13527+ * A sort variant that takes an index range and always mutates the original list.
13528+ * <pre class="groovyTestCase">
13529+ * def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
13530+ * nums.sort(0..4) { it }
13531+ * assert nums == [1, 3, 5, 7, 9, 4, 8, 6, 0, 2]
13532+ * </pre>
13533+ *
13534+ * @see #sort(List, IntRange, boolean, Closure)
13535+ * @return the sorted list
13536+ */
13537+ public static <T> List<T> sort(List<T> self, IntRange range, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
13538+ return sort(self, range, true, closure);
13539+ }
13540+
1344413541 /**
1344513542 * Sorts the given iterator items into a sorted iterator using the Closure to determine the correct ordering.
1344613543 * The original iterator will be fully processed after the method call.
@@ -15202,6 +15299,20 @@ public static <T> Iterator<T> toSorted(Iterator<T> self, @ClosureParams(value=Fr
1520215299 return toSorted(self, comparator);
1520315300 }
1520415301
15302+ /**
15303+ * A sort variant that takes an index range and never modifies the original list.
15304+ * <pre class="groovyTestCase">
15305+ * def nums = [5, 9, 1, 7, 3, 4, 8, 6, 0, 2]
15306+ * assert nums.toSorted(0..4) { it } == [1, 3, 5, 7, 9, 4, 8, 6, 0, 2]
15307+ * </pre>
15308+ *
15309+ * @see #sort(List, IntRange, boolean, Closure)
15310+ * @return the sorted list
15311+ */
15312+ public static <T> List<T> toSorted(List<T> self, IntRange range, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
15313+ return sort(self, range, false, closure);
15314+ }
15315+
1520515316 /**
1520615317 * Sorts the elements from the given map into a new ordered map using
1520715318 * a {@link NumberAwareComparator} on map entry values to determine the resulting order.
0 commit comments