This is an automated email from the ASF dual-hosted git repository.

paulk-asert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 167034dab7 minor refactor: improved consistency with other recent 
method signatures
167034dab7 is described below

commit 167034dab7ed20d43d763520a40d916cac3fe648
Author: Paul King <[email protected]>
AuthorDate: Mon May 18 15:56:43 2026 +1000

    minor refactor: improved consistency with other recent method signatures
---
 .../groovy/runtime/ArrayGroovyMethods.java         | 26 ++++----
 .../groovy/runtime/DefaultGroovyMethods.java       | 78 ++++++++++++----------
 2 files changed, 54 insertions(+), 50 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java 
b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index 42f6b5db24..222bc9b6ba 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -4403,7 +4403,7 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      */
     public static <T, K> Map<K, List<T>> groupByMany(
         T[] self,
-        @ClosureParams(FirstParam.Component.class) Closure<? extends 
Iterable<? extends K>> keyFn
+        Function<? super T, ? extends Iterable<? extends K>> keyFn
     ) {
         return DefaultGroovyMethods.groupByMany(Arrays.asList(self), keyFn);
     }
@@ -4421,8 +4421,8 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
      */
     public static <T, U, K> Map<K, List<U>> groupByMany(
         T[] self,
-        @ClosureParams(FirstParam.Component.class) Closure<? extends U> 
valueFn,
-        @ClosureParams(FirstParam.Component.class) Closure<? extends 
Iterable<? extends K>> keyFn
+        Function<? super T, ? extends U> valueFn,
+        Function<? super T, ? extends Iterable<? extends K>> keyFn
     ) {
         return DefaultGroovyMethods.groupByMany(Arrays.asList(self), valueFn, 
keyFn);
     }
@@ -5298,20 +5298,20 @@ public class ArrayGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Determines if the array is sorted using the given Closure to determine 
order.
-     * <p>
-     * If the Closure has two parameters it is used like a traditional 
Comparator.
-     * Otherwise, the Closure is assumed to take a single parameter and return 
a
-     * Comparable (typically an Integer) which is then used for further 
comparison.
+     * Determines if the array is sorted in non-descending order of the keys
+     * returned by the given key extractor. Keys are compared number-aware.
+     * For a custom ordering use {@link #isSorted(Object[], Comparator)} (a
+     * two-arg closure coerces to a Comparator).
      *
-     * @param self    the array to check
-     * @param closure a 1 or 2 arg Closure used to determine the ordering
-     * @return true if the array elements are sorted according to the closure
+     * @param self         the array to check
+     * @param keyExtractor extracts the sort key from each element
+     * @return true if the array elements are sorted by key in non-descending 
order
      * @see #isSorted(Object[], Comparator)
      * @since 6.0.0
      */
-    public static <T> boolean isSorted(T[] self, 
@ClosureParams(value=FromString.class, options={"T","T,T"}) Closure<?> closure) 
{
-        Comparator<T> comparator = (closure.getMaximumNumberOfParameters() == 
1) ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
+    public static <T> boolean isSorted(T[] self, Function<? super T, ?> 
keyExtractor) {
+        Comparator<Object> byKey = new NumberAwareComparator<>();
+        Comparator<T> comparator = (a, b) -> 
byKey.compare(keyExtractor.apply(a), keyExtractor.apply(b));
         return isSorted(self, comparator);
     }
 
diff --git 
a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java 
b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 5817e8b0dd..c37dc18969 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -8092,12 +8092,12 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
      */
     public static <T, K> Map<K, List<T>> groupByMany(
         Iterable<T> self,
-        @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends 
Iterable<? extends K>> keyFn
+        Function<? super T, ? extends Iterable<? extends K>> keyFn
     ) {
         Map<K, List<T>> result = new HashMap<>();
 
         for (T item : self) {
-            Iterable<? extends K> keys = keyFn.call(item);
+            Iterable<? extends K> keys = keyFn.apply(item);
             if (keys == null) continue;
 
             for (K key : keys) {
@@ -8141,18 +8141,18 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
      */
     public static <T, U, K> Map<K, List<U>> groupByMany(
         Iterable<T> self,
-        @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends U> 
valueFn,
-        @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends 
Iterable<? extends K>> keyFn
+        Function<? super T, ? extends U> valueFn,
+        Function<? super T, ? extends Iterable<? extends K>> keyFn
     ) {
         Map<K, List<U>> result = new HashMap<>();
 
         for (T item : self) {
-            Iterable<? extends K> keys = keyFn.call(item);
+            Iterable<? extends K> keys = keyFn.apply(item);
             if (keys == null) continue;
 
             for (K key : keys) {
                 result.computeIfAbsent(key, k -> new ArrayList<>())
-                    .add(valueFn.call(item));
+                    .add(valueFn.apply(item));
             }
         }
 
@@ -9881,25 +9881,26 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Determines if the Iterable is sorted using the given Closure to 
determine order.
-     * <p>
-     * If the Closure has two parameters it is used like a traditional 
Comparator.
-     * Otherwise, the Closure is assumed to take a single parameter and return 
a
-     * Comparable (typically an Integer) which is then used for further 
comparison.
+     * Determines if the Iterable is sorted in non-descending order of the
+     * keys returned by the given key extractor. Keys are compared
+     * number-aware, consistent with {@link #isSorted(Iterable)}. For a
+     * custom ordering use {@link #isSorted(Iterable, Comparator)} (a
+     * two-arg closure coerces to a Comparator).
      * <pre class="language-groovy groovyTestCase">
      * assert ["hi","hey","hello"].isSorted { it.length() }
      * assert !["hello","hi","hey"].isSorted { it.length() }
-     * assert ["hi","hey","hello"].isSorted { a, b {@code ->} a.length() 
{@code <=>} b.length() }
+     * assert ["hi","hey","hello"].isSorted { a, b {@code ->} a.length() 
{@code <=>} b.length() } // Comparator overload
      * </pre>
      *
-     * @param self    the Iterable to check
-     * @param closure a 1 or 2 arg Closure used to determine the ordering
-     * @return true if the elements are sorted according to the closure
+     * @param self         the Iterable to check
+     * @param keyExtractor extracts the sort key from each element
+     * @return true if the elements are sorted by key in non-descending order
      * @see #isSorted(Iterable, Comparator)
      * @since 6.0.0
      */
-    public static <T> boolean isSorted(Iterable<T> self, 
@ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        Comparator<T> comparator = (closure.getMaximumNumberOfParameters() == 
1) ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
+    public static <T> boolean isSorted(Iterable<T> self, Function<? super T, 
?> keyExtractor) {
+        Comparator<Object> byKey = new NumberAwareComparator<>();
+        Comparator<T> comparator = (a, b) -> 
byKey.compare(keyExtractor.apply(a), keyExtractor.apply(b));
         return isSorted(self, comparator);
     }
 
@@ -9940,22 +9941,23 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Determines if the Iterator elements are sorted using the given Closure 
to determine order.
-     * <p>
-     * If the Closure has two parameters it is used like a traditional 
Comparator.
-     * Otherwise, the Closure is assumed to take a single parameter and return 
a
-     * Comparable which is then used for further comparison.
+     * Determines if the Iterator elements are sorted in non-descending order
+     * of the keys returned by the given key extractor. Keys are compared
+     * number-aware. For a custom ordering use
+     * {@link #isSorted(Iterator, Comparator)} (a two-arg closure coerces to
+     * a Comparator).
      * <p>
      * The iterator will be exhausted of elements after determining the sorted 
status.
      *
-     * @param self    the Iterator to check
-     * @param closure a 1 or 2 arg Closure used to determine the ordering
-     * @return true if the elements are sorted according to the closure
+     * @param self         the Iterator to check
+     * @param keyExtractor extracts the sort key from each element
+     * @return true if the elements are sorted by key in non-descending order
      * @see #isSorted(Iterator, Comparator)
      * @since 6.0.0
      */
-    public static <T> boolean isSorted(Iterator<T> self, 
@ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        Comparator<T> comparator = (closure.getMaximumNumberOfParameters() == 
1) ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
+    public static <T> boolean isSorted(Iterator<T> self, Function<? super T, 
?> keyExtractor) {
+        Comparator<Object> byKey = new NumberAwareComparator<>();
+        Comparator<T> comparator = (a, b) -> 
byKey.compare(keyExtractor.apply(a), keyExtractor.apply(b));
         return isSorted(self, comparator);
     }
 
@@ -9992,19 +9994,21 @@ public class DefaultGroovyMethods extends 
DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Determines if the Map entries are sorted using the given Closure to 
determine order.
-     * <p>
-     * If the Closure has two parameters it is used like a traditional 
Comparator on entries.
-     * Otherwise, the Closure is assumed to take a single entry parameter and 
return a
-     * Comparable which is then used for further comparison.
+     * Determines if the Map entries are sorted in non-descending order of the
+     * keys returned by the given entry key extractor. Keys are compared
+     * number-aware. For a custom ordering use
+     * {@link #isSorted(Map, Comparator)} (a two-arg closure over entries
+     * coerces to a Comparator).
      *
-     * @param self      the Map to check
-     * @param condition a Closure used as a comparator
-     * @return true if the map entries are sorted according to the closure
+     * @param self         the Map to check
+     * @param keyExtractor extracts the sort key from each Map.Entry
+     * @return true if the map entries are sorted by key in non-descending 
order
+     * @see #isSorted(Map, Comparator)
      * @since 6.0.0
      */
-    public static <K, V> boolean isSorted(Map<K, V> self, 
@ClosureParams(value=FromString.class, 
options={"Map.Entry<K,V>","Map.Entry<K,V>,Map.Entry<K,V>"}) Closure condition) {
-        Comparator<Map.Entry<K,V>> comparator = 
(condition.getMaximumNumberOfParameters() == 1) ? new OrderBy<>(condition) : 
new ClosureComparator<>(condition);
+    public static <K, V> boolean isSorted(Map<K, V> self, Function<? super 
Map.Entry<K, V>, ?> keyExtractor) {
+        Comparator<Object> byKey = new NumberAwareComparator<>();
+        Comparator<Map.Entry<K, V>> comparator = (a, b) -> 
byKey.compare(keyExtractor.apply(a), keyExtractor.apply(b));
         return isSorted(self, comparator);
     }
 

Reply via email to