You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2023/01/28 23:08:19 UTC
[groovy] 02/02: GROOVY-7319: Add primitive optimised array min() and max() Inspiration from Yu Kobayashi (https://github.com/groovy/groovy-core/pull/616 from 2015)
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 1ce68128e7a7cc15a9cdf0ae43cac648b19205a7
Author: Paul King <pa...@asert.com.au>
AuthorDate: Thu Jan 26 22:45:31 2023 +1000
GROOVY-7319: Add primitive optimised array min() and max()
Inspiration from Yu Kobayashi (https://github.com/groovy/groovy-core/pull/616 from 2015)
---
.../groovy/runtime/ArrayGroovyMethods.java | 397 +++++++++++++++++++++
1 file changed, 397 insertions(+)
diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index ab0712cd50..9d6346996f 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -25,6 +25,10 @@ import groovy.lang.Range;
import groovy.transform.stc.ClosureParams;
import groovy.transform.stc.FirstParam;
import groovy.transform.stc.FromString;
+import groovy.util.function.DoubleComparator;
+import groovy.util.function.IntComparator;
+import groovy.util.function.LongComparator;
+import org.apache.groovy.lang.annotation.Incubating;
import org.codehaus.groovy.runtime.callsite.BooleanClosureWrapper;
import org.codehaus.groovy.runtime.dgmimpl.NumberNumberDiv;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
@@ -50,6 +54,9 @@ import java.util.Map;
import java.util.Objects;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.function.DoubleUnaryOperator;
+import java.util.function.IntUnaryOperator;
+import java.util.function.LongUnaryOperator;
/**
* This class defines new groovy methods which appear on primitive arrays inside the Groovy environment.
@@ -3584,6 +3591,71 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
return answer;
}
+ /**
+ * Selects the maximum value found from the int array
+ * using the supplier IntBinaryOperator as a comparator to determine the maximum of any two values.
+ * <p>
+ * <pre class="groovyTestCase">
+ * int[] nums = [10, 20, -30]
+ * assert 20 == nums.max{ n, m {@code ->} n {@code <=>} m }
+ * assert -30 == nums.max{ n, m {@code ->} n.abs() {@code <=>} m.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self an int array
+ * @param comparator a comparator, i.e. returns a negative value if the first parameter is less than the second
+ * @return the maximum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static int max(int[] self, IntComparator comparator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "max");
+
+ int maxV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ int v = self[i];
+ if (comparator.compare(v, maxV) > 0) {
+ maxV = v;
+ }
+ }
+ return maxV;
+ }
+
+ /**
+ * Selects the maximum value found from the int array
+ * using the supplier IntUnaryOperator to determine the maximum of any two values.
+ * The operator is applied to each array element and the results are compared.
+ * <p>
+ * <pre class="groovyTestCase">
+ * int[] nums = [10, 20, -30]
+ * assert 20 == nums.max{ it }
+ * assert -30 == nums.max{ it.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self an int array
+ * @param operator an operator that returns an int used for comparing values
+ * @return the maximum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static int max(int[] self, IntUnaryOperator operator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "max");
+
+ int maxV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ int v = self[i];
+ if (operator.applyAsInt(v) > operator.applyAsInt(maxV)) {
+ maxV = v;
+ }
+ }
+ return maxV;
+ }
+
/**
* Adds max() method to long arrays.
* <p/>
@@ -3608,6 +3680,71 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
return answer;
}
+ /**
+ * Selects the maximum value found from the long array
+ * using the supplier LongBinaryOperator as a comparator to determine the maximum of any two values.
+ * <p>
+ * <pre class="groovyTestCase">
+ * long[] nums = [10L, 20L, -30L]
+ * assert 20L == nums.max{ n, m {@code ->} n {@code <=>} m }
+ * assert -30L == nums.max{ n, m {@code ->} n.abs() {@code <=>} m.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self a long array
+ * @param comparator a comparator, i.e. returns a negative value if the first parameter is less than the second
+ * @return the maximum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static long max(long[] self, LongComparator comparator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "max");
+
+ long maxV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ long v = self[i];
+ if (comparator.compare(v, maxV) > 0) {
+ maxV = v;
+ }
+ }
+ return maxV;
+ }
+
+ /**
+ * Selects the maximum value found from the long array
+ * using the supplier LongUnaryOperator to determine the maximum of any two values.
+ * The operator is applied to each array element and the results are compared.
+ * <p>
+ * <pre class="groovyTestCase">
+ * long[] nums = [10L, 20L, -30L]
+ * assert 20L == nums.max{ it }
+ * assert -30L == nums.max{ it.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self a long array
+ * @param operator an operator that returns a long used for comparing values
+ * @return the maximum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static long max(long[] self, LongUnaryOperator operator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "max");
+
+ long maxV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ long v = self[i];
+ if (operator.applyAsLong(v) > operator.applyAsLong(maxV)) {
+ maxV = v;
+ }
+ }
+ return maxV;
+ }
+
/**
* Adds max() method to double arrays.
* <p/>
@@ -3632,6 +3769,71 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
return answer;
}
+ /**
+ * Selects the maximum value found from the double array
+ * using the supplier DoubleComparator to determine the maximum of any two values.
+ * <p>
+ * <pre class="groovyTestCase">
+ * double[] nums = [10d, 20d, -30d]
+ * assert 20d == nums.max{ n, m {@code ->} n {@code <=>} m }
+ * assert -30d == nums.max{ n, m {@code ->} n.abs() {@code <=>} m.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self a double array
+ * @param comparator a comparator, i.e. returns a negative value if the first parameter is less than the second
+ * @return the maximum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static double max(double[] self, DoubleComparator comparator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "max");
+
+ double maxV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ double v = self[i];
+ if (comparator.compare(v, maxV) > 0) {
+ maxV = v;
+ }
+ }
+ return maxV;
+ }
+
+ /**
+ * Selects the maximum value found from the double array
+ * using the supplier DoubleUnaryOperator to determine the maximum of any two values.
+ * The operator is applied to each array element and the results are compared.
+ * <p>
+ * <pre class="groovyTestCase">
+ * double[] nums = [10d, 20d, -30d]
+ * assert -30d == nums.max{ it.abs() }
+ * assert 20d == nums.max{ it }
+ * </pre>
+ * <p>
+ *
+ * @param self a double array
+ * @param operator an operator that returns a double used for comparing values
+ * @return the maximum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static double max(double[] self, DoubleUnaryOperator operator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "max");
+
+ double maxV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ double v = self[i];
+ if (operator.applyAsDouble(v) > operator.applyAsDouble(maxV)) {
+ maxV = v;
+ }
+ }
+ return maxV;
+ }
+
//-------------------------------------------------------------------------
// min
@@ -3659,6 +3861,71 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
return answer;
}
+ /**
+ * Selects the minimum value found from the int array
+ * using the supplier IntComparator to determine the minimum of any two values.
+ * <p>
+ * <pre class="groovyTestCase">
+ * int[] nums = [10, -20, 30]
+ * assert -20 == nums.min{ n, m {@code ->} n {@code <=>} m }
+ * assert 10 == nums.min{ n, m {@code ->} n.abs() {@code <=>} m.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self an int array
+ * @param comparator a comparator, i.e. returns a negative value if the first parameter is less than the second
+ * @return the minimum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static int min(int[] self, IntComparator comparator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "min");
+
+ int minV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ int v = self[i];
+ if (comparator.compare(v, minV) < 0) {
+ minV = v;
+ }
+ }
+ return minV;
+ }
+
+ /**
+ * Selects the minimum value found from the int array
+ * using the supplier IntUnaryOperator to determine the minimum of any two values.
+ * The operator is applied to each array element and the results are compared.
+ * <p>
+ * <pre class="groovyTestCase">
+ * int[] nums = [10, -20, 30]
+ * assert -20L == nums.min{ n {@code ->} n }
+ * assert 10L == nums.min{ n {@code ->} n.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self an int array
+ * @param operator an operator that returns an int used for comparing values
+ * @return the minimum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static int min(int[] self, IntUnaryOperator operator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "min");
+
+ int minV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ int v = self[i];
+ if (operator.applyAsInt(v) < operator.applyAsInt(minV)) {
+ minV = v;
+ }
+ }
+ return minV;
+ }
+
/**
* Adds min() method to long arrays.
* <p/>
@@ -3683,6 +3950,71 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
return answer;
}
+ /**
+ * Selects the minimum value found from the long array
+ * using the supplier LongBinaryOperator as a comparator to determine the minimum of any two values.
+ * <p>
+ * <pre class="groovyTestCase">
+ * long[] nums = [10L, -20L, 30L]
+ * assert -20L == nums.min{ n, m {@code ->} n {@code <=>} m }
+ * assert 10L == nums.min{ n, m {@code ->} n.abs() {@code <=>} m.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self a long array
+ * @param comparator a comparator, i.e. returns a negative value if the first parameter is less than the second
+ * @return the minimum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static long min(long[] self, LongComparator comparator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "min");
+
+ long minV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ long v = self[i];
+ if (comparator.compare(v, minV) < 0) {
+ minV = v;
+ }
+ }
+ return minV;
+ }
+
+ /**
+ * Selects the minimum value found from the long array
+ * using the supplier LongUnaryOperator to determine the minimum of any two values.
+ * The operator is applied to each array element and the results are compared.
+ * <p>
+ * <pre class="groovyTestCase">
+ * long[] nums = [10L, -20L, 30L]
+ * assert -20L == nums.min{ it }
+ * assert 10L == nums.min{ it.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self a long array
+ * @param operator an operator that returns a long used for comparing values
+ * @return the minimum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static long min(long[] self, LongUnaryOperator operator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "min");
+
+ long minV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ long v = self[i];
+ if (operator.applyAsLong(v) < operator.applyAsLong(minV)) {
+ minV = v;
+ }
+ }
+ return minV;
+ }
+
/**
* Adds min() method to double arrays.
* <p/>
@@ -3707,6 +4039,71 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
return answer;
}
+ /**
+ * Selects the minimum value found from the double array
+ * using the supplier DoubleBinaryOperator as a comparator to determine the minimum of any two values.
+ * <p>
+ * <pre class="groovyTestCase">
+ * double[] nums = [10d, -20d, 30d]
+ * assert -20d == nums.min{ n, m {@code ->} n {@code <=>} m }
+ * assert 10d == nums.min{ n, m {@code ->} n.abs() {@code <=>} m.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self a double array
+ * @param comparator a comparator, i.e. returns a negative value if the first parameter is less than the second
+ * @return the minimum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static double min(double[] self, DoubleComparator comparator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "min");
+
+ double minV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ double v = self[i];
+ if (comparator.compare(v, minV) < 0) {
+ minV = v;
+ }
+ }
+ return minV;
+ }
+
+ /**
+ * Selects the minimum value found from the double array
+ * using the supplier DoubleUnaryOperator to determine the minimum of any two values.
+ * The operator is applied to each array element and the results are compared.
+ * <p>
+ * <pre class="groovyTestCase">
+ * double[] nums = [10d, -20d, 30d]
+ * assert -20d == nums.min{ it }
+ * assert 10d == nums.min{ it.abs() }
+ * </pre>
+ * <p>
+ *
+ * @param self a double array
+ * @param operator an operator that returns a double used for comparing values
+ * @return the minimum value
+ * @throws UnsupportedOperationException if the array is empty
+ * @since 5.0.0
+ */
+ @Incubating
+ public static double min(double[] self, DoubleUnaryOperator operator) {
+ Objects.requireNonNull(self);
+ throwUnsupportedOperationIfEmpty(self.length, "min");
+
+ double minV = self[0];
+ for (int i = 1; i < self.length; i++) {
+ double v = self[i];
+ if (operator.applyAsDouble(v) < operator.applyAsDouble(minV)) {
+ minV = v;
+ }
+ }
+ return minV;
+ }
+
//-------------------------------------------------------------------------
// minus
//-------------------------------------------------------------------------