This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git
The following commit(s) were added to refs/heads/master by this push:
new b2e66fe50 Add EnumUtils.getFirstEnum(Class<E>, int, ToIntFunction<E>,
E)
b2e66fe50 is described below
commit b2e66fe50ba8af3986edc3d06a9dd3c8489cfd36
Author: Gary D. Gregory <[email protected]>
AuthorDate: Sat Feb 22 14:11:45 2025 -0500
Add EnumUtils.getFirstEnum(Class<E>, int, ToIntFunction<E>, E)
---
src/changes/changes.xml | 1 +
.../java/org/apache/commons/lang3/EnumUtils.java | 39 ++++++++++++++++++----
.../org/apache/commons/lang3/EnumUtilsTest.java | 38 ++++++++++++++++-----
3 files changed, 64 insertions(+), 14 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ca18c3c90..53300a6f4 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -101,6 +101,7 @@ The <action> type attribute can be add,update,fix,remove.
<action type="add" dev="ggregory" due-to="Gary
Gregory">Add IterableStringTokenizer.</action>
<action type="add" dev="ggregory" due-to="Gary
Gregory">Add FailableIntToFloatFunction.</action>
<action type="add" dev="ggregory" due-to="Gary
Gregory">Add Validate.isTrue(boolean, Supplier<String>).</action>
+ <action type="add" dev="ggregory" due-to="Gary
Gregory">Add EnumUtils.getFirstEnum(Class<E>, int,
ToIntFunction<E>, E).</action>
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary
Gregory, Dependabot">Bump org.apache.commons:commons-parent from 73 to 81
#1267, #1277, #1283, #1288, #1302.</action>
<action type="update" dev="ggregory" due-to="Gary
Gregory, Dependabot">[site] Bump org.codehaus.mojo:taglist-maven-plugin from
3.1.0 to 3.2.1 #1300.</action>
diff --git a/src/main/java/org/apache/commons/lang3/EnumUtils.java
b/src/main/java/org/apache/commons/lang3/EnumUtils.java
index 1c20764c8..1d9da1df4 100644
--- a/src/main/java/org/apache/commons/lang3/EnumUtils.java
+++ b/src/main/java/org/apache/commons/lang3/EnumUtils.java
@@ -24,6 +24,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
+import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -69,7 +70,6 @@ private static <E extends Enum<E>> Class<E>
checkBitVectorable(final Class<E> en
final E[] constants = asEnum(enumClass).getEnumConstants();
Validate.isTrue(constants.length <= Long.SIZE,
CANNOT_STORE_S_S_VALUES_IN_S_BITS,
Integer.valueOf(constants.length), enumClass.getSimpleName(),
Integer.valueOf(Long.SIZE));
-
return enumClass;
}
@@ -321,6 +321,29 @@ public static <E extends Enum<E>> E
getEnumSystemProperty(final Class<E> enumCla
: getEnum(enumClass, System.getProperty(propName), defaultEnum);
}
+ /**
+ * Gets the enum for the class and value, returning {@code defaultEnum} if
not found.
+ *
+ * <p>
+ * This method differs from {@link Enum#valueOf} in that it does not throw
an exception for an invalid enum name and performs case insensitive matching of
+ * the name.
+ * </p>
+ *
+ * @param <E> the type of the enumeration.
+ * @param enumClass the class of the enum to query, not null.
+ * @param value the enum name, null returns default enum.
+ * @param toIntFunction the function that gets an int for an enum for
comparison to {@code value}.
+ * @param defaultEnum the default enum.
+ * @return an enum, default enum if not found.
+ * @since 3.18.0
+ */
+ public static <E extends Enum<E>> E getFirstEnum(final Class<E> enumClass,
final int value, final ToIntFunction<E> toIntFunction, final E defaultEnum) {
+ if (isEnum(enumClass)) {
+ return defaultEnum;
+ }
+ return Stream.of(enumClass.getEnumConstants()).filter(e -> value ==
toIntFunction.applyAsInt(e)).findFirst().orElse(defaultEnum);
+ }
+
/**
* Gets the enum for the class, returning {@code defaultEnum} if not found.
*
@@ -332,15 +355,19 @@ public static <E extends Enum<E>> E
getEnumSystemProperty(final Class<E> enumCla
* @param enumName the enum name, null returns default enum
* @param stringFunction the function that gets the string for an enum for
comparison to {@code enumName}.
* @param defaultEnum the default enum
- * @return the enum, default enum if not found
+ * @return an enum, default enum if not found
* @since 3.13.0
*/
public static <E extends Enum<E>> E getFirstEnumIgnoreCase(final Class<E>
enumClass, final String enumName, final Function<E, String> stringFunction,
- final E defaultEnum) {
- if (enumName == null || !enumClass.isEnum()) {
- return defaultEnum;
+ final E defaultEnum) {
+ if (enumName == null || !enumClass.isEnum()) {
+ return defaultEnum;
+ }
+ return Stream.of(enumClass.getEnumConstants()).filter(e ->
enumName.equalsIgnoreCase(stringFunction.apply(e))).findFirst().orElse(defaultEnum);
}
- return Stream.of(enumClass.getEnumConstants()).filter(e ->
enumName.equalsIgnoreCase(stringFunction.apply(e))).findFirst().orElse(defaultEnum);
+
+ private static <E extends Enum<E>> boolean isEnum(final Class<E>
enumClass) {
+ return enumClass != null && !enumClass.isEnum();
}
/**
diff --git a/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java
b/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java
index acb601413..869061fb5 100644
--- a/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java
@@ -31,16 +31,11 @@
import java.util.List;
import java.util.Map;
import java.util.function.Function;
+import java.util.function.ToIntFunction;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-enum Enum64 {
- A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14,
A15, A16, A17, A18, A19, A20, A21, A22,
- A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37,
A38, A39, A40, A41, A42, A43, A44, A45,
- A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, A60,
A61, A62, A63
-}
-
/**
*/
public class EnumUtilsTest extends AbstractLangTest {
@@ -438,6 +433,21 @@ public void testGetFirstEnumIgnoreCase_defaultEnum() {
assertNull(EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "PURPLE",
f, null));
}
+ @Test
+ public void testGetFirstEnumToIntFunction() {
+ final ToIntFunction<Traffic2> f = Traffic2::getValue;
+ assertEquals(Traffic2.RED, EnumUtils.getFirstEnum(Traffic2.class, 1,
f, Traffic2.AMBER));
+ assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum(Traffic2.class, 2,
f, Traffic2.GREEN));
+ assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnum(Traffic2.class, 3,
f, Traffic2.RED));
+ assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum(Traffic2.class, 4,
f, Traffic2.AMBER));
+ assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnum(Traffic2.class, 5,
f, Traffic2.GREEN));
+ assertEquals(Traffic2.RED, EnumUtils.getFirstEnum(Traffic2.class, 6,
f, Traffic2.RED));
+ assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum(Traffic2.class, 0,
f, Traffic2.AMBER));
+ assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnum(Traffic2.class,
-1, f, Traffic2.GREEN));
+ assertEquals(Traffic2.RED, EnumUtils.getFirstEnum(Traffic2.class, 0,
f, Traffic2.RED));
+ assertNull(EnumUtils.getFirstEnum(Traffic2.class, 7, f, null));
+ }
+
@Test
public void testIsValidEnum() {
assertTrue(EnumUtils.isValidEnum(Traffic.class, "RED"));
@@ -591,6 +601,12 @@ public void testProcessBitVectors_nullClass() {
}
+enum Enum64 {
+ A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14,
A15, A16, A17, A18, A19, A20, A21, A22,
+ A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37,
A38, A39, A40, A41, A42, A43, A44, A45,
+ A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, A60,
A61, A62, A63
+}
+
enum Month {
JAN(1), FEB(2), MAR(3), APR(4), MAY(5), JUN(6), JUL(7), AUG(8), SEP(9),
OCT(10), NOV(11), DEC(12);
@@ -617,15 +633,21 @@ enum Traffic {
enum Traffic2 {
- RED("***Red***"), AMBER("**Amber**"), GREEN("*green*");
+ RED("***Red***", 1), AMBER("**Amber**", 2), GREEN("*green*", 3);
final String label;
+ final int value;
- Traffic2(final String label) {
+ Traffic2(final String label, final int value) {
this.label = label;
+ this.value = value;
}
public String getLabel() {
return label;
}
+
+ public int getValue() {
+ return value;
+ }
}