修复EnumUtil空指针问题

This commit is contained in:
Looly 2024-05-10 11:25:16 +08:00
parent e86c264dfc
commit fab02fc0b6
3 changed files with 153 additions and 32 deletions

View File

@ -2,7 +2,7 @@
# 🚀Changelog # 🚀Changelog
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.8.28(2024-05-09) # 5.8.28(2024-05-10)
### 🐣新特性 ### 🐣新特性
* 【core 】 修正XmlUtil的omitXmlDeclaration描述注释issue#I9CPC7@Gitee * 【core 】 修正XmlUtil的omitXmlDeclaration描述注释issue#I9CPC7@Gitee
@ -34,6 +34,7 @@
* 【core 】 修复ZipReader.checkZipBomb遇到空目录报错问题issue#I9K494@Gitee * 【core 】 修复ZipReader.checkZipBomb遇到空目录报错问题issue#I9K494@Gitee
* 【db 】 修复Oracle下特殊表名导致meta信息获取不到问题issue#I9BANE@Gitee * 【db 】 修复Oracle下特殊表名导致meta信息获取不到问题issue#I9BANE@Gitee
* 【db 】 修复FuncComparator.thenComparing不生效问题issue#3569@Github * 【db 】 修复FuncComparator.thenComparing不生效问题issue#3569@Github
* 【core 】 修复EnumUtil空指针问题issue#I9NSZ4@Gitee
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.8.27(2024-03-29) # 5.8.27(2024-03-29)

View File

@ -1,16 +1,13 @@
package cn.hutool.core.util; package cn.hutool.core.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -29,8 +26,7 @@ public class EnumUtil {
* @return 是否为Enum类 * @return 是否为Enum类
*/ */
public static boolean isEnum(Class<?> clazz) { public static boolean isEnum(Class<?> clazz) {
Assert.notNull(clazz); return Assert.notNull(clazz).isEnum();
return clazz.isEnum();
} }
/** /**
@ -40,8 +36,7 @@ public class EnumUtil {
* @return 是否为Enum类 * @return 是否为Enum类
*/ */
public static boolean isEnum(Object obj) { public static boolean isEnum(Object obj) {
Assert.notNull(obj); return Assert.notNull(obj).getClass().isEnum();
return obj.getClass().isEnum();
} }
/** /**
@ -65,7 +60,14 @@ public class EnumUtil {
* @since 5.1.6 * @since 5.1.6
*/ */
public static <E extends Enum<E>> E getEnumAt(Class<E> enumClass, int index) { public static <E extends Enum<E>> E getEnumAt(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;
} }
@ -79,6 +81,9 @@ public class EnumUtil {
* @since 4.1.13 * @since 4.1.13
*/ */
public static <E extends Enum<E>> E fromString(Class<E> enumClass, String value) { public static <E extends Enum<E>> E fromString(Class<E> enumClass, String value) {
if (null == enumClass || StrUtil.isBlank(value)) {
return null;
}
return Enum.valueOf(enumClass, value); return Enum.valueOf(enumClass, value);
} }
@ -107,10 +112,6 @@ public class EnumUtil {
* @since 4.5.18 * @since 4.5.18
*/ */
public static <E extends Enum<E>> E fromStringQuietly(Class<E> enumClass, String value) { public static <E extends Enum<E>> E fromStringQuietly(Class<E> enumClass, String value) {
if (null == enumClass || StrUtil.isBlank(value)) {
return null;
}
try { try {
return fromString(enumClass, value); return fromString(enumClass, value);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -128,6 +129,9 @@ public class EnumUtil {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <E extends Enum<E>> E likeValueOf(Class<E> enumClass, Object value) { public static <E extends Enum<E>> E likeValueOf(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();
} }
@ -157,6 +161,9 @@ public class EnumUtil {
* @return name列表 * @return name列表
*/ */
public static List<String> getNames(Class<? extends Enum<?>> clazz) { public static List<String> getNames(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;
@ -176,6 +183,9 @@ public class EnumUtil {
* @return 字段值列表 * @return 字段值列表
*/ */
public static List<Object> getFieldValues(Class<? extends Enum<?>> clazz, String fieldName) { public static List<Object> getFieldValues(Class<? extends Enum<?>> clazz, 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;
@ -200,6 +210,9 @@ public class EnumUtil {
* @since 4.1.20 * @since 4.1.20
*/ */
public static List<String> getFieldNames(Class<? extends Enum<?>> clazz) { public static List<String> getFieldNames(Class<? extends Enum<?>> clazz) {
if(null == clazz){
return null;
}
final List<String> names = new ArrayList<>(); final List<String> names = new ArrayList<>();
final Field[] fields = ReflectUtil.getFields(clazz); final Field[] fields = ReflectUtil.getFields(clazz);
String name; String name;
@ -225,25 +238,31 @@ public class EnumUtil {
* @since 5.8.0 * @since 5.8.0
*/ */
public static <E extends Enum<E>> E getBy(Class<E> enumClass, Predicate<? super E> predicate) { public static <E extends Enum<E>> E getBy(Class<E> enumClass, 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);
} }
/** /**
* 通过 某字段对应值 获取 枚举获取不到时为 {@code null} * 通过 某字段对应值 获取 枚举获取不到时为 {@code null}
* *
* @param condition 条件字段 * @param condition 条件字段{@code null}返回{@code null}
* @param value 条件字段值 * @param value 条件字段值
* @param <E> 枚举类型 * @param <E> 枚举类型
* @param <C> 字段类型 * @param <C> 字段类型
* @return 对应枚举 获取不到时为 {@code null} * @return 对应枚举 获取不到时为 {@code null}
*/ */
public static <E extends Enum<E>, C> E getBy(Func1<E, C> condition, C value) { public static <E extends Enum<E>, C> E getBy(Func1<E, C> condition, 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.callWithRuntimeException(e).equals(value)).findAny().orElse(null); final Class<E> implClass = LambdaUtil.getRealClass(condition);
return Arrays.stream(implClass.getEnumConstants())
.filter(constant -> ObjUtil.equals(condition.callWithRuntimeException(constant), value))
.findAny()
.orElse(null);
} }
/** /**
@ -264,8 +283,8 @@ public class EnumUtil {
/** /**
* 通过 某字段对应值 获取 枚举中另一字段值获取不到时为 {@code null} * 通过 某字段对应值 获取 枚举中另一字段值获取不到时为 {@code null}
* *
* @param field 你想要获取的字段 * @param field 你想要获取的字段{@code null}返回{@code null}
* @param condition 条件字段 * @param condition 条件字段{@code null}返回{@code null}
* @param value 条件字段值 * @param value 条件字段值
* @param <E> 枚举类型 * @param <E> 枚举类型
* @param <F> 想要获取的字段类型 * @param <F> 想要获取的字段类型
@ -273,17 +292,18 @@ public class EnumUtil {
* @return 对应枚举中另一字段值 获取不到时为 {@code null} * @return 对应枚举中另一字段值 获取不到时为 {@code null}
* @since 5.8.0 * @since 5.8.0
*/ */
public static <E extends Enum<E>, F, C> F getFieldBy(Func1<E, F> field, public static <E extends Enum<E>, F, C> F getFieldBy(Func1<E, F> field, Function<E, C> condition, C value) {
Function<E, C> condition, C value) { if(null == field || null == condition){
Class<E> implClass = LambdaUtil.getRealClass(field); return null;
if (Enum.class.equals(implClass)) {
implClass = LambdaUtil.getRealClass(field);
} }
final Class<E> 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::callWithRuntimeException).orElse(null); .findFirst()
.map(field::callWithRuntimeException)
.orElse(null);
} }
/** /**
@ -296,6 +316,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);
@ -312,6 +335,9 @@ public class EnumUtil {
* @return 枚举名对应指定字段值的Map * @return 枚举名对应指定字段值的Map
*/ */
public static Map<String, Object> getNameFieldMap(Class<? extends Enum<?>> clazz, String fieldName) { public static Map<String, Object> getNameFieldMap(Class<? extends Enum<?>> clazz, 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;
@ -332,7 +358,11 @@ public class EnumUtil {
* @return 是否存在 * @return 是否存在
*/ */
public static <E extends Enum<E>> boolean contains(final Class<E> enumClass, String val) { public static <E extends Enum<E>> boolean contains(final Class<E> enumClass, String val) {
return EnumUtil.getEnumMap(enumClass).containsKey(val); final LinkedHashMap<String, E> enumMap = getEnumMap(enumClass);
if(CollUtil.isEmpty(enumMap)){
return false;
}
return enumMap.containsKey(val);
} }
/** /**

View File

@ -0,0 +1,90 @@
package cn.hutool.core.util;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import org.junit.Assert;
import org.junit.Test;
public class IssueI9NSZ4Test {
@Test
public void getByTest() {
// AnimalKindInZoo所有枚举结果的getMappedValue结果值中都无AnimalKind.DOG返回null
final AnimalKindInZoo by = EnumUtil.getBy(AnimalKindInZoo::getMappedValue, AnimalKind.DOG);
Assert.assertNull(by);
}
@Test
public void getByTest2() {
// AnimalKindInZoo所有枚举结果的getMappedValue结果值中都无AnimalKind.DOG返回null
final AnimalKindInZoo by = EnumUtil.getBy(AnimalKindInZoo::getMappedValue, AnimalKind.BIRD);
Assert.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;
}
}