mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
修复EnumUtil空指针问题
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.core.util;
|
package org.dromara.hutool.core.util;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.collection.CollUtil;
|
||||||
import org.dromara.hutool.core.lang.Assert;
|
import org.dromara.hutool.core.lang.Assert;
|
||||||
import org.dromara.hutool.core.func.LambdaUtil;
|
import org.dromara.hutool.core.func.LambdaUtil;
|
||||||
import org.dromara.hutool.core.func.SerFunction;
|
import org.dromara.hutool.core.func.SerFunction;
|
||||||
@@ -39,8 +40,7 @@ public class EnumUtil {
|
|||||||
* @return 是否为Enum类
|
* @return 是否为Enum类
|
||||||
*/
|
*/
|
||||||
public static boolean isEnum(final Class<?> clazz) {
|
public static boolean isEnum(final Class<?> clazz) {
|
||||||
Assert.notNull(clazz);
|
return Assert.notNull(clazz).isEnum();
|
||||||
return clazz.isEnum();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,8 +50,7 @@ public class EnumUtil {
|
|||||||
* @return 是否为Enum类
|
* @return 是否为Enum类
|
||||||
*/
|
*/
|
||||||
public static boolean isEnum(final Object obj) {
|
public static boolean isEnum(final Object obj) {
|
||||||
Assert.notNull(obj);
|
return Assert.notNull(obj).getClass().isEnum();
|
||||||
return obj.getClass().isEnum();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,8 +73,14 @@ public class EnumUtil {
|
|||||||
* @return 枚举值,null表示无此对应枚举
|
* @return 枚举值,null表示无此对应枚举
|
||||||
* @since 5.1.6
|
* @since 5.1.6
|
||||||
*/
|
*/
|
||||||
public static <E extends Enum<E>> E getEnumAt(final Class<E> enumClass, final int index) {
|
public static <E extends Enum<E>> E getEnumAt(final Class<E> enumClass, int index) {
|
||||||
|
if (null == enumClass) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final E[] enumConstants = enumClass.getEnumConstants();
|
final E[] enumConstants = enumClass.getEnumConstants();
|
||||||
|
if (index < 0) {
|
||||||
|
index = enumConstants.length + index;
|
||||||
|
}
|
||||||
return index >= 0 && index < enumConstants.length ? enumConstants[index] : null;
|
return index >= 0 && index < enumConstants.length ? enumConstants[index] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,9 +94,29 @@ public class EnumUtil {
|
|||||||
* @since 4.1.13
|
* @since 4.1.13
|
||||||
*/
|
*/
|
||||||
public static <E extends Enum<E>> E fromString(final Class<E> enumClass, final String value) {
|
public static <E extends Enum<E>> E fromString(final Class<E> enumClass, final String value) {
|
||||||
|
if (null == enumClass || StrUtil.isBlank(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return Enum.valueOf(enumClass, value);
|
return Enum.valueOf(enumClass, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符串转枚举,调用{@link Enum#valueOf(Class, String)},转换失败返回{@code null} 而非报错
|
||||||
|
*
|
||||||
|
* @param <E> 枚举类型泛型
|
||||||
|
* @param enumClass 枚举类
|
||||||
|
* @param value 值
|
||||||
|
* @return 枚举值
|
||||||
|
* @since 4.5.18
|
||||||
|
*/
|
||||||
|
public static <E extends Enum<E>> E fromStringQuietly(final Class<E> enumClass, final String value) {
|
||||||
|
try {
|
||||||
|
return fromString(enumClass, value);
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符串转枚举,调用{@link Enum#valueOf(Class, String)}<br>
|
* 字符串转枚举,调用{@link Enum#valueOf(Class, String)}<br>
|
||||||
* 如果无枚举值,返回默认值
|
* 如果无枚举值,返回默认值
|
||||||
@@ -107,27 +132,6 @@ public class EnumUtil {
|
|||||||
return ObjUtil.defaultIfNull(fromStringQuietly(enumClass, value), defaultValue);
|
return ObjUtil.defaultIfNull(fromStringQuietly(enumClass, value), defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串转枚举,调用{@link Enum#valueOf(Class, String)},转换失败返回{@code null} 而非报错
|
|
||||||
*
|
|
||||||
* @param <E> 枚举类型泛型
|
|
||||||
* @param enumClass 枚举类
|
|
||||||
* @param value 值
|
|
||||||
* @return 枚举值
|
|
||||||
* @since 4.5.18
|
|
||||||
*/
|
|
||||||
public static <E extends Enum<E>> E fromStringQuietly(final Class<E> enumClass, final String value) {
|
|
||||||
if (null == enumClass || StrUtil.isBlank(value)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return fromString(enumClass, value);
|
|
||||||
} catch (final IllegalArgumentException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模糊匹配转换为枚举,给定一个值,匹配枚举中定义的所有字段名(包括name属性),一旦匹配到返回这个枚举对象,否则返回null
|
* 模糊匹配转换为枚举,给定一个值,匹配枚举中定义的所有字段名(包括name属性),一旦匹配到返回这个枚举对象,否则返回null
|
||||||
*
|
*
|
||||||
@@ -138,6 +142,9 @@ public class EnumUtil {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <E extends Enum<E>> E likeValueOf(final Class<E> enumClass, Object value) {
|
public static <E extends Enum<E>> E likeValueOf(final Class<E> enumClass, Object value) {
|
||||||
|
if (null == enumClass || null == value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (value instanceof CharSequence) {
|
if (value instanceof CharSequence) {
|
||||||
value = value.toString().trim();
|
value = value.toString().trim();
|
||||||
}
|
}
|
||||||
@@ -147,7 +154,7 @@ public class EnumUtil {
|
|||||||
String fieldName;
|
String fieldName;
|
||||||
for (final Field field : fields) {
|
for (final Field field : fields) {
|
||||||
fieldName = field.getName();
|
fieldName = field.getName();
|
||||||
if (field.getType().isEnum() || "ENUM$VALUES".equals(fieldName) || "ordinal".equals(fieldName)) {
|
if (field.getType().isEnum() || StrUtil.equalsAny("ENUM$VALUES", "ordinal", fieldName)) {
|
||||||
// 跳过一些特殊字段
|
// 跳过一些特殊字段
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -167,6 +174,9 @@ public class EnumUtil {
|
|||||||
* @return name列表
|
* @return name列表
|
||||||
*/
|
*/
|
||||||
public static List<String> getNames(final Class<? extends Enum<?>> clazz) {
|
public static List<String> getNames(final Class<? extends Enum<?>> clazz) {
|
||||||
|
if (null == clazz) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final Enum<?>[] enums = clazz.getEnumConstants();
|
final Enum<?>[] enums = clazz.getEnumConstants();
|
||||||
if (null == enums) {
|
if (null == enums) {
|
||||||
return null;
|
return null;
|
||||||
@@ -186,6 +196,9 @@ public class EnumUtil {
|
|||||||
* @return 字段值列表
|
* @return 字段值列表
|
||||||
*/
|
*/
|
||||||
public static List<Object> getFieldValues(final Class<? extends Enum<?>> clazz, final String fieldName) {
|
public static List<Object> getFieldValues(final Class<? extends Enum<?>> clazz, final String fieldName) {
|
||||||
|
if (null == clazz || StrUtil.isBlank(fieldName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final Enum<?>[] enums = clazz.getEnumConstants();
|
final Enum<?>[] enums = clazz.getEnumConstants();
|
||||||
if (null == enums) {
|
if (null == enums) {
|
||||||
return null;
|
return null;
|
||||||
@@ -210,6 +223,9 @@ public class EnumUtil {
|
|||||||
* @since 4.1.20
|
* @since 4.1.20
|
||||||
*/
|
*/
|
||||||
public static List<String> getFieldNames(final Class<? extends Enum<?>> clazz) {
|
public static List<String> getFieldNames(final Class<? extends Enum<?>> clazz) {
|
||||||
|
if (null == clazz) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final List<String> names = new ArrayList<>();
|
final List<String> names = new ArrayList<>();
|
||||||
final Field[] fields = FieldUtil.getFields(clazz);
|
final Field[] fields = FieldUtil.getFields(clazz);
|
||||||
String name;
|
String name;
|
||||||
@@ -235,8 +251,11 @@ public class EnumUtil {
|
|||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public static <E extends Enum<E>> E getBy(final Class<E> enumClass, final Predicate<? super E> predicate) {
|
public static <E extends Enum<E>> E getBy(final Class<E> enumClass, final Predicate<? super E> predicate) {
|
||||||
|
if (null == enumClass || null == predicate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return Arrays.stream(enumClass.getEnumConstants())
|
return Arrays.stream(enumClass.getEnumConstants())
|
||||||
.filter(predicate).findFirst().orElse(null);
|
.filter(predicate).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,11 +268,14 @@ public class EnumUtil {
|
|||||||
* @return 对应枚举 ,获取不到时为 {@code null}
|
* @return 对应枚举 ,获取不到时为 {@code null}
|
||||||
*/
|
*/
|
||||||
public static <E extends Enum<E>, C> E getBy(final SerFunction<E, C> condition, final C value) {
|
public static <E extends Enum<E>, C> E getBy(final SerFunction<E, C> condition, final C value) {
|
||||||
Class<E> implClass = LambdaUtil.getRealClass(condition);
|
if(null == condition){
|
||||||
if (Enum.class.equals(implClass)) {
|
return null;
|
||||||
implClass = LambdaUtil.getRealClass(condition);
|
|
||||||
}
|
}
|
||||||
return Arrays.stream(implClass.getEnumConstants()).filter(e -> condition.apply(e).equals(value)).findAny().orElse(null);
|
final Class<E> implClass = LambdaUtil.getRealClass(condition);
|
||||||
|
return Arrays.stream(implClass.getEnumConstants())
|
||||||
|
.filter(constant -> ObjUtil.equals(condition.apply(constant), value))
|
||||||
|
.findAny()
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -284,15 +306,19 @@ public class EnumUtil {
|
|||||||
*/
|
*/
|
||||||
public static <E extends Enum<E>, F, C> F getFieldBy(final SerFunction<E, F> field,
|
public static <E extends Enum<E>, F, C> F getFieldBy(final SerFunction<E, F> field,
|
||||||
final Function<E, C> condition, final C value) {
|
final Function<E, C> condition, final C value) {
|
||||||
|
if(null == field || null == condition){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Class<E> implClass = LambdaUtil.getRealClass(field);
|
Class<E> implClass = LambdaUtil.getRealClass(field);
|
||||||
if (Enum.class.equals(implClass)) {
|
if (Enum.class.equals(implClass)) {
|
||||||
implClass = LambdaUtil.getRealClass(field);
|
implClass = LambdaUtil.getRealClass(field);
|
||||||
}
|
}
|
||||||
return Arrays.stream(implClass.getEnumConstants())
|
return Arrays.stream(implClass.getEnumConstants())
|
||||||
// 过滤
|
// 过滤
|
||||||
.filter(e -> condition.apply(e).equals(value))
|
.filter(constant -> ObjUtil.equals(condition.apply(constant), value))
|
||||||
// 获取第一个并转换为结果
|
// 获取第一个并转换为结果
|
||||||
.findFirst().map(field).orElse(null);
|
.findFirst().map(field)
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -305,6 +331,9 @@ public class EnumUtil {
|
|||||||
* @since 4.0.2
|
* @since 4.0.2
|
||||||
*/
|
*/
|
||||||
public static <E extends Enum<E>> LinkedHashMap<String, E> getEnumMap(final Class<E> enumClass) {
|
public static <E extends Enum<E>> LinkedHashMap<String, E> getEnumMap(final Class<E> enumClass) {
|
||||||
|
if(null == enumClass){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final LinkedHashMap<String, E> map = new LinkedHashMap<>();
|
final LinkedHashMap<String, E> map = new LinkedHashMap<>();
|
||||||
for (final E e : enumClass.getEnumConstants()) {
|
for (final E e : enumClass.getEnumConstants()) {
|
||||||
map.put(e.name(), e);
|
map.put(e.name(), e);
|
||||||
@@ -321,6 +350,9 @@ public class EnumUtil {
|
|||||||
* @return 枚举名对应指定字段值的Map
|
* @return 枚举名对应指定字段值的Map
|
||||||
*/
|
*/
|
||||||
public static Map<String, Object> getNameFieldMap(final Class<? extends Enum<?>> clazz, final String fieldName) {
|
public static Map<String, Object> getNameFieldMap(final Class<? extends Enum<?>> clazz, final String fieldName) {
|
||||||
|
if(null == clazz || StrUtil.isBlank(fieldName)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final Enum<?>[] enums = clazz.getEnumConstants();
|
final Enum<?>[] enums = clazz.getEnumConstants();
|
||||||
Assert.notNull(enums, "Class [{}] is not an Enum type!", clazz);
|
Assert.notNull(enums, "Class [{}] is not an Enum type!", clazz);
|
||||||
final Map<String, Object> map = MapUtil.newHashMap(enums.length, true);
|
final Map<String, Object> map = MapUtil.newHashMap(enums.length, true);
|
||||||
@@ -339,7 +371,11 @@ public class EnumUtil {
|
|||||||
* @return 是否存在
|
* @return 是否存在
|
||||||
*/
|
*/
|
||||||
public static <E extends Enum<E>> boolean contains(final Class<E> enumClass, final String name) {
|
public static <E extends Enum<E>> boolean contains(final Class<E> enumClass, final String name) {
|
||||||
return getEnumMap(enumClass).containsKey(name);
|
final LinkedHashMap<String, E> enumMap = getEnumMap(enumClass);
|
||||||
|
if(CollUtil.isEmpty(enumMap)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return enumMap.containsKey(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,88 @@
|
|||||||
|
package org.dromara.hutool.core.util;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class IssueI9NSZ4Test {
|
||||||
|
@Test
|
||||||
|
public void getByTest() {
|
||||||
|
// AnimalKindInZoo所有枚举结果的getMappedValue结果值中都无AnimalKind.DOG,返回null
|
||||||
|
final AnimalKindInZoo by = EnumUtil.getBy(AnimalKindInZoo::getMappedValue, AnimalKind.DOG);
|
||||||
|
Assertions.assertNull(by);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getByTest2() {
|
||||||
|
final AnimalKindInZoo by = EnumUtil.getBy(AnimalKindInZoo::getMappedValue, AnimalKind.BIRD);
|
||||||
|
Assertions.assertEquals(AnimalKindInZoo.BIRD, by);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动物类型
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum AnimalKind {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 猫
|
||||||
|
*/
|
||||||
|
CAT("cat", "猫"),
|
||||||
|
/**
|
||||||
|
* 狗
|
||||||
|
*/
|
||||||
|
DOG("dog", "狗"),
|
||||||
|
/**
|
||||||
|
* 鸟
|
||||||
|
*/
|
||||||
|
BIRD("bird", "鸟");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 键
|
||||||
|
*/
|
||||||
|
private final String key;
|
||||||
|
/**
|
||||||
|
* 值
|
||||||
|
*/
|
||||||
|
private final String value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动物园里的动物类型
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum AnimalKindInZoo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 猫
|
||||||
|
*/
|
||||||
|
CAT("cat", "猫", AnimalKind.CAT),
|
||||||
|
/**
|
||||||
|
* 蛇
|
||||||
|
*/
|
||||||
|
SNAKE("snake", "蛇", null),
|
||||||
|
/**
|
||||||
|
* 鸟
|
||||||
|
*/
|
||||||
|
BIRD("bird", "鸟", AnimalKind.BIRD);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 键
|
||||||
|
*/
|
||||||
|
private final String key;
|
||||||
|
/**
|
||||||
|
* 值
|
||||||
|
*/
|
||||||
|
private final String value;
|
||||||
|
/**
|
||||||
|
* 映射值
|
||||||
|
*/
|
||||||
|
private final AnimalKind mappedValue;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user