修复EnglishNumberFormatter.format小数问题

This commit is contained in:
Looly 2024-05-11 11:58:25 +08:00
parent 7daeb183b5
commit 478b523c67
10 changed files with 254 additions and 320 deletions

View File

@ -24,6 +24,16 @@ import java.util.function.Predicate;
*/
public class PredicateUtil {
/**
* <p>创建一个匹配任何方法的方法匹配器
*
* @param <T> 参数类型
* @return 方法匹配器
*/
public static <T> Predicate<T> alwaysTrue() {
return method -> true;
}
/**
* 强制转换 {@code Predicate<? super T>} {@code Predicate<T>}.
*

View File

@ -132,16 +132,12 @@ public class EnglishNumberFormatter {
}
}
String xs = ""; // 用来存放转换后小数部分
String xs = lm.length() == 0 ? "ZERO " : " "; // 用来存放转换后小数部分
if (z > -1) {
xs = "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数
xs += "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数
}
return lm.toString().trim() + " " + xs + "ONLY";
}
private static String parseFirst(final String s) {
return NUMBER[Integer.parseInt(s.substring(s.length() - 1))];
return lm.toString().trim() + xs + "ONLY";
}
private static String parseTeen(final String s) {
@ -163,17 +159,18 @@ public class EnglishNumberFormatter {
if (s.length() > 2) {
s = s.substring(0, 2);
} else if (s.length() < 2) {
s = "0" + s;
// 单位数出现于小数部分按照分对待
s = s + "0";
}
if (s.startsWith("0")) {// 07 - seven 是否小於10
value = parseFirst(s);
value = parseLast(s);
} else if (s.startsWith("1")) {// 17 seventeen 是否在10和20之间
value = parseTeen(s);
} else if (s.endsWith("0")) {// 是否在10与100之间的能被10整除的数
value = parseTen(s);
} else {
value = parseTen(s) + " " + parseFirst(s);
value = parseTen(s) + " " + parseLast(s);
}
return value;
}
@ -185,10 +182,14 @@ public class EnglishNumberFormatter {
if (s.startsWith("0")) {// 是否小於100
value = transTwo(s.substring(1));
} else if ("00".equals(s.substring(1))) {// 是否被100整除
value = parseFirst(s.substring(0, 1)) + " HUNDRED";
value = parseLast(s.substring(0, 1)) + " HUNDRED";
} else {
value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1));
value = parseLast(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1));
}
return value;
}
private static String parseLast(final String s) {
return NUMBER[Integer.parseInt(s.substring(s.length() - 1))];
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.reflect.method;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.function.Predicate;
/**
* <p>方法匹配器本身可作为{@link Predicate}校验方法是否匹配指定条件
* 当作为{@link MethodMetadataLookup}使用时
* 若方法符合条件则返回{@link Boolean#TRUE}否则返回{@code null}
*
* @author huangchengxing
* @see MethodMatcherUtil
* @see MethodMetadataLookup
* @since 6.0.0
*/
@FunctionalInterface
public interface MethodMatcher extends MethodMetadataLookup<Boolean>, Predicate<Method> {
/**
* 返回一个组合的条件当且仅当所有条件都符合时才返回{@code true}
*
* @param other 其他条件
* @return 条件
* @throws NullPointerException 当other为null时抛出
*/
@Override
default MethodMatcher and(final Predicate<? super Method> other) {
Objects.requireNonNull(other);
return t -> test(t) && other.test(t);
}
/**
* 返回一个与此条件相反的条件
*
* @return 条件
*/
@Override
default MethodMatcher negate() {
return t -> !test(t);
}
/**
* 返回一个组合的条件当且仅当任一条件符合时才返回{@code true}
*
* @param other 其他条件
* @return 条件
* @throws NullPointerException 当other为null时抛出
*/
@Override
default MethodMatcher or(final Predicate<? super Method> other) {
Objects.requireNonNull(other);
return t -> test(t) || other.test(t);
}
/**
* 检查方法若结果不为{@code null}则认为方法与其匹配
*
* @param method 要检查的方法
* @return 结果
*/
@Override
default Boolean inspect(final Method method) {
return test(method) ? Boolean.TRUE : null;
}
}

View File

@ -29,34 +29,13 @@ import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* 方法匹配器工具类用于基于各种预设条件创建方法匹配器用于配合{@link MethodScanner}从各种范围中寻找匹配的方法
* 方法匹配器工具类用于基于各种预设条件创建方法匹配器用于配合{@link MethodScanner2}从各种范围中寻找匹配的方法
*
* @author huangchengxing
* @see MethodMatcher
* @since 6.0.0
*/
public class MethodMatcherUtil {
/**
* <p>创建一个匹配任何方法的方法匹配器
*
* @return 方法匹配器
*/
public static MethodMatcher alwaysMatch() {
return method -> true;
}
/**
* <p>创建一个方法匹配器
*
* @param predicate 条件
* @return 方法匹配器
*/
public static MethodMatcher of(final Predicate<Method> predicate) {
return predicate::test;
}
/**
* <p>用于组合多个方法匹配器的方法匹配器仅当所有方法匹配器均匹配失败时才认为方法匹配
*
@ -64,7 +43,8 @@ public class MethodMatcherUtil {
* @return 方法匹配器
* @see Stream#noneMatch
*/
public static MethodMatcher noneMatch(final MethodMatcher... matchers) {
@SafeVarargs
public static Predicate<Method> noneMatch(final Predicate<Method>... matchers) {
return method -> Stream.of(matchers).noneMatch(matcher -> matcher.test(method));
}
@ -75,7 +55,8 @@ public class MethodMatcherUtil {
* @return 方法匹配器
* @see Stream#anyMatch
*/
public static MethodMatcher anyMatch(final MethodMatcher... matchers) {
@SafeVarargs
public static Predicate<Method> anyMatch(final Predicate<Method>... matchers) {
return method -> Stream.of(matchers).anyMatch(matcher -> matcher.test(method));
}
@ -86,7 +67,8 @@ public class MethodMatcherUtil {
* @return 方法匹配器
* @see Stream#allMatch
*/
public static MethodMatcher allMatch(final MethodMatcher... matchers) {
@SafeVarargs
public static Predicate<Method> allMatch(final Predicate<Method>... matchers) {
return method -> Stream.of(matchers).allMatch(matcher -> matcher.test(method));
}
@ -97,7 +79,7 @@ public class MethodMatcherUtil {
*
* @return 方法匹配器
*/
public static MethodMatcher isPublic() {
public static Predicate<Method> isPublic() {
return forModifiers(Modifier.PUBLIC);
}
@ -106,7 +88,7 @@ public class MethodMatcherUtil {
*
* @return 方法匹配器
*/
public static MethodMatcher isStatic() {
public static Predicate<Method> isStatic() {
return forModifiers(Modifier.STATIC);
}
@ -115,7 +97,7 @@ public class MethodMatcherUtil {
*
* @return 方法匹配器
*/
public static MethodMatcher isPublicStatic() {
public static Predicate<Method> isPublicStatic() {
return forModifiers(Modifier.PUBLIC, Modifier.STATIC);
}
@ -125,7 +107,7 @@ public class MethodMatcherUtil {
* @param modifiers 修饰符
* @return 方法匹配器
*/
public static MethodMatcher forModifiers(final int... modifiers) {
public static Predicate<Method> forModifiers(final int... modifiers) {
return method -> {
final int methodModifiers = method.getModifiers();
return Arrays.stream(modifiers).allMatch(modifier -> (methodModifiers & modifier) != 0);
@ -144,7 +126,7 @@ public class MethodMatcherUtil {
* @return 方法匹配器
* @see AnnotatedElementUtil#isAnnotationPresent
*/
public static MethodMatcher hasDeclaredAnnotation(final Class<? extends Annotation> annotationType) {
public static Predicate<Method> hasDeclaredAnnotation(final Class<? extends Annotation> annotationType) {
return method -> method.isAnnotationPresent(annotationType);
}
@ -160,7 +142,7 @@ public class MethodMatcherUtil {
* @return 方法匹配器
* @see AnnotatedElementUtil#isAnnotationPresent
*/
public static MethodMatcher hasAnnotation(final Class<? extends Annotation> annotationType) {
public static Predicate<Method> hasAnnotation(final Class<? extends Annotation> annotationType) {
return method -> AnnotatedElementUtil.isAnnotationPresent(method, annotationType);
}
@ -176,7 +158,7 @@ public class MethodMatcherUtil {
* @return 方法匹配器
* @see AnnotatedElementUtil#isAnnotationPresent
*/
public static MethodMatcher hasAnnotationOnDeclaringClass(final Class<? extends Annotation> annotationType) {
public static Predicate<Method> hasAnnotationOnDeclaringClass(final Class<? extends Annotation> annotationType) {
return method -> AnnotatedElementUtil.isAnnotationPresent(method.getDeclaringClass(), annotationType);
}
@ -193,7 +175,7 @@ public class MethodMatcherUtil {
* @param annotationType 注解类型
* @return 方法匹配器
*/
public static MethodMatcher hasAnnotationOnMethodOrDeclaringClass(final Class<? extends Annotation> annotationType) {
public static Predicate<Method> hasAnnotationOnMethodOrDeclaringClass(final Class<? extends Annotation> annotationType) {
return method -> AnnotatedElementUtil.isAnnotationPresent(method, annotationType)
|| AnnotatedElementUtil.isAnnotationPresent(method.getDeclaringClass(), annotationType);
}
@ -214,11 +196,11 @@ public class MethodMatcherUtil {
* @param fieldType 属性类型
* @return 方法匹配器
*/
public static MethodMatcher forGetterMethod(final String fieldName, final Class<?> fieldType) {
public static Predicate<Method> forGetterMethod(final String fieldName, final Class<?> fieldType) {
Objects.requireNonNull(fieldName);
Objects.requireNonNull(fieldType);
// 匹配方法名为 get + 首字母大写的属性名的无参数方法
MethodMatcher nameMatcher = forName(CharSequenceUtil.upperFirstAndAddPre(fieldName, "get"));
Predicate<Method> nameMatcher = forName(CharSequenceUtil.upperFirstAndAddPre(fieldName, "get"));
// 查找方法名为属性名的无参数方法
nameMatcher = nameMatcher.or(forName(fieldName));
if (Objects.equals(boolean.class, fieldType) || Objects.equals(Boolean.class, fieldType)) {
@ -239,7 +221,7 @@ public class MethodMatcherUtil {
* @param field 属性
* @return 方法匹配器
*/
public static MethodMatcher forGetterMethod(final Field field) {
public static Predicate<Method> forGetterMethod(final Field field) {
Objects.requireNonNull(field);
return forGetterMethod(field.getName(), field.getType());
}
@ -255,10 +237,10 @@ public class MethodMatcherUtil {
* @param fieldType 属性类型
* @return 方法匹配器
*/
public static MethodMatcher forSetterMethod(final String fieldName, final Class<?> fieldType) {
public static Predicate<Method> forSetterMethod(final String fieldName, final Class<?> fieldType) {
Objects.requireNonNull(fieldName);
Objects.requireNonNull(fieldType);
final MethodMatcher nameMatcher = forName(CharSequenceUtil.upperFirstAndAddPre(fieldName, "set"))
final Predicate<Method> nameMatcher = forName(CharSequenceUtil.upperFirstAndAddPre(fieldName, "set"))
.or(forName(fieldName));
return allMatch(nameMatcher, forParameterTypes(fieldType));
}
@ -273,7 +255,7 @@ public class MethodMatcherUtil {
* @param field 属性
* @return 方法匹配器
*/
public static MethodMatcher forSetterMethod(final Field field) {
public static Predicate<Method> forSetterMethod(final Field field) {
Objects.requireNonNull(field);
return forSetterMethod(field.getName(), field.getType());
}
@ -289,7 +271,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forNameAndParameterTypes(final String methodName, final Class<?>... parameterTypes) {
public static Predicate<Method> forNameAndParameterTypes(final String methodName, final Class<?>... parameterTypes) {
Objects.requireNonNull(methodName);
Objects.requireNonNull(parameterTypes);
return allMatch(forName(methodName), forParameterTypes(parameterTypes));
@ -302,7 +284,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forNameAndStrictParameterTypes(final String methodName, final Class<?>... parameterTypes) {
public static Predicate<Method> forNameAndStrictParameterTypes(final String methodName, final Class<?>... parameterTypes) {
Objects.requireNonNull(methodName);
Objects.requireNonNull(parameterTypes);
return allMatch(forName(methodName), forStrictParameterTypes(parameterTypes));
@ -315,7 +297,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forNameIgnoreCaseAndParameterTypes(
public static Predicate<Method> forNameIgnoreCaseAndParameterTypes(
final String methodName, final Class<?>... parameterTypes) {
Objects.requireNonNull(methodName);
Objects.requireNonNull(parameterTypes);
@ -329,7 +311,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forNameIgnoreCaseAndStrictParameterTypes(
public static Predicate<Method> forNameIgnoreCaseAndStrictParameterTypes(
final String methodName, final Class<?>... parameterTypes) {
Objects.requireNonNull(methodName);
Objects.requireNonNull(parameterTypes);
@ -351,7 +333,7 @@ public class MethodMatcherUtil {
* @param method 方法
* @return 方法匹配器
*/
public static MethodMatcher forMethodSignature(final Method method) {
public static Predicate<Method> forMethodSignature(final Method method) {
Objects.requireNonNull(method);
return forMethodSignature(method.getName(), method.getReturnType(), method.getParameterTypes());
}
@ -369,12 +351,12 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型若为{@code null}则表示匹配无参数的方法
* @return 方法匹配器
*/
public static MethodMatcher forMethodSignature(
public static Predicate<Method> forMethodSignature(
final String methodName, final Class<?> returnType, final Class<?>... parameterTypes) {
Objects.requireNonNull(methodName);
final MethodMatcher resultMatcher = Objects.isNull(returnType) ?
final Predicate<Method> resultMatcher = Objects.isNull(returnType) ?
forNoneReturnType() : forReturnType(returnType);
final MethodMatcher parameterMatcher = Objects.isNull(parameterTypes) ?
final Predicate<Method> parameterMatcher = Objects.isNull(parameterTypes) ?
forNoneParameter() : forParameterTypes(parameterTypes);
return allMatch(forName(methodName), resultMatcher, parameterMatcher);
}
@ -392,12 +374,12 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型若为{@code null}则表示匹配无参数的方法
* @return 方法匹配器
*/
public static MethodMatcher forStrictMethodSignature(
public static Predicate<Method> forStrictMethodSignature(
final String methodName, final Class<?> returnType, final Class<?>... parameterTypes) {
Objects.requireNonNull(methodName);
final MethodMatcher resultMatcher = Objects.isNull(returnType) ?
final Predicate<Method> resultMatcher = Objects.isNull(returnType) ?
forNoneReturnType() : forReturnType(returnType);
final MethodMatcher parameterMatcher = Objects.isNull(parameterTypes) ?
final Predicate<Method> parameterMatcher = Objects.isNull(parameterTypes) ?
forNoneParameter() : forStrictParameterTypes(parameterTypes);
return allMatch(forName(methodName), resultMatcher, parameterMatcher);
}
@ -413,7 +395,7 @@ public class MethodMatcherUtil {
* @param method 方法
* @return 方法匹配器
*/
public static MethodMatcher forStrictMethodSignature(final Method method) {
public static Predicate<Method> forStrictMethodSignature(final Method method) {
Objects.requireNonNull(method);
return forMethodSignature(method.getName(), method.getReturnType(), method.getParameterTypes());
}
@ -428,7 +410,7 @@ public class MethodMatcherUtil {
* @param methodName 方法名
* @return 方法匹配器
*/
public static MethodMatcher forName(final String methodName) {
public static Predicate<Method> forName(final String methodName) {
return method -> Objects.equals(method.getName(), methodName);
}
@ -438,7 +420,7 @@ public class MethodMatcherUtil {
* @param methodName 方法名
* @return 方法匹配器
*/
public static MethodMatcher forNameIgnoreCase(final String methodName) {
public static Predicate<Method> forNameIgnoreCase(final String methodName) {
return method -> CharSequenceUtil.endWithIgnoreCase(method.getName(), methodName);
}
@ -447,7 +429,7 @@ public class MethodMatcherUtil {
*
* @return 方法匹配器
*/
public static MethodMatcher forNoneReturnType() {
public static Predicate<Method> forNoneReturnType() {
return method -> Objects.equals(method.getReturnType(), Void.TYPE);
}
@ -457,7 +439,7 @@ public class MethodMatcherUtil {
* @param returnType 返回值类型
* @return 方法匹配器
*/
public static MethodMatcher forReturnType(final Class<?> returnType) {
public static Predicate<Method> forReturnType(final Class<?> returnType) {
return method -> ClassUtil.isAssignable(returnType, method.getReturnType());
}
@ -467,7 +449,7 @@ public class MethodMatcherUtil {
* @param returnType 返回值类型
* @return 方法匹配器
*/
public static MethodMatcher forStrictReturnType(final Class<?> returnType) {
public static Predicate<Method> forStrictReturnType(final Class<?> returnType) {
return method -> Objects.equals(method.getReturnType(), returnType);
}
@ -476,7 +458,7 @@ public class MethodMatcherUtil {
*
* @return 方法匹配器
*/
public static MethodMatcher forNoneParameter() {
public static Predicate<Method> forNoneParameter() {
return method -> method.getParameterCount() == 0;
}
@ -486,7 +468,7 @@ public class MethodMatcherUtil {
* @param count 参数个数
* @return 方法匹配器
*/
public static MethodMatcher forParameterCount(final int count) {
public static Predicate<Method> forParameterCount(final int count) {
return method -> method.getParameterCount() == count;
}
@ -497,7 +479,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forParameterTypes(final Class<?>... parameterTypes) {
public static Predicate<Method> forParameterTypes(final Class<?>... parameterTypes) {
Objects.requireNonNull(parameterTypes);
return method -> ClassUtil.isAllAssignableFrom(parameterTypes, method.getParameterTypes());
}
@ -530,7 +512,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forMostSpecificParameterTypes(final Class<?>... parameterTypes) {
public static Predicate<Method> forMostSpecificParameterTypes(final Class<?>... parameterTypes) {
return mostSpecificStrictParameterTypesMatcher(parameterTypes, ClassUtil::isAssignable);
}
@ -561,7 +543,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forMostSpecificStrictParameterTypes(final Class<?>... parameterTypes) {
public static Predicate<Method> forMostSpecificStrictParameterTypes(final Class<?>... parameterTypes) {
return mostSpecificStrictParameterTypesMatcher(parameterTypes, Objects::equals);
}
@ -571,7 +553,7 @@ public class MethodMatcherUtil {
* @param parameterTypes 参数类型
* @return 方法匹配器
*/
public static MethodMatcher forStrictParameterTypes(final Class<?>... parameterTypes) {
public static Predicate<Method> forStrictParameterTypes(final Class<?>... parameterTypes) {
Objects.requireNonNull(parameterTypes);
return method -> ArrayUtil.equals(method.getParameterTypes(), parameterTypes);
}
@ -579,7 +561,7 @@ public class MethodMatcherUtil {
// endregion
@NotNull
private static MethodMatcher mostSpecificStrictParameterTypesMatcher(
private static Predicate<Method> mostSpecificStrictParameterTypesMatcher(
final Class<?>[] parameterTypes, final BiPredicate<Class<?>, Class<?>> typeMatcher) {
Objects.requireNonNull(parameterTypes);
// 若参数为空则表示匹配无参数方法

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.reflect.method;
import java.lang.reflect.Method;
/**
* 方法的元数据查找器参照 spring {@code MethodIntrospector.MetadataLookup}用于从方法上获得特定的元数据
*
* @param <T> 返回类型
* @author huangchengxing
* @see MethodMatcher
* @see MethodMatcherUtil
* @since 6.0.0
*/
@FunctionalInterface
public interface MethodMetadataLookup<T> {
/**
* 检查并返回方法上的特定元数据若结果不为{@code null}则认为方法与其匹配
*
* @param method 要检查的方法
* @return 结果
*/
T inspect(Method method);
}

View File

@ -21,6 +21,7 @@ import org.dromara.hutool.core.reflect.ClassUtil;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
/**
@ -45,9 +46,9 @@ import java.util.function.Predicate;
* 若我们希望获得类所有方法范围中首个匹配的方法则应当调用{@link #getFromAllMethods}
*
* <p><strong>匹配规则</strong>
* <p>方法查找的规则由{@link MethodMetadataLookup}实现<br>
* 规定{@link MethodMetadataLookup#inspect(Method)}方法返回元数据不为{@code null}则认为方法与其匹配返回结果时将同时返回匹配的方法与元数据<br>
* 因此我们可以通过实现{@link MethodMetadataLookup}接口来同时实现方法的查找与元数据的获取<br>
* <p>方法查找的规则由{@link Function}实现<br>
* 规定{@link Function#apply(Object)}方法返回元数据不为{@code null}则认为方法与其匹配返回结果时将同时返回匹配的方法与元数据<br>
* 因此我们可以通过实现{@link Function}接口来同时实现方法的查找与元数据的获取<br>
* 比如我们希望查找所有方法上带有{@code Annotation}注解的方法则可以实现如下
* <pre>{@code
* Map<Method, Annotation> methods = MethodScanner.findFromAllMethods(Foo.class, method -> method.getAnnotation(Annotation.class));
@ -69,12 +70,10 @@ import java.util.function.Predicate;
* 缓存在GC时会被回收但是也可以通过{@link #clearCaches}手动清除缓存
*
* @author huangchengxing
* @see MethodMetadataLookup
* @see MethodMatcher
* @see MethodMatcherUtil
* @since 6.0.0
*/
public class MethodScanner {
public class MethodScanner2 {
/*
TODO 替换{@link MethodUtil}中的部分方法实现
*/
@ -106,7 +105,7 @@ public class MethodScanner {
if (Objects.isNull(type)) {
return EMPTY_METHODS;
}
return MapUtil.computeIfAbsentForJdk8(METHODS_CACHE, type, Class::getMethods);
return METHODS_CACHE.computeIfAbsent(type, Class::getMethods);
}
/**
@ -119,7 +118,7 @@ public class MethodScanner {
if (Objects.isNull(type)) {
return EMPTY_METHODS;
}
return MapUtil.computeIfAbsentForJdk8(DECLARED_METHODS_CACHE, type, Class::getDeclaredMethods);
return DECLARED_METHODS_CACHE.computeIfAbsent(type, Class::getDeclaredMethods);
}
/**
@ -168,13 +167,13 @@ public class MethodScanner {
* @return 方法与对应的元数据集合
* @param <T> 结果类型
*/
public static <T> Map<Method, T> findWithMetadataFromSpecificMethods(final Method[] methods, final MethodMetadataLookup<T> lookup) {
public static <T> Map<Method, T> findWithMetadataFromSpecificMethods(final Method[] methods, final Function<Method, T> lookup) {
if (ArrayUtil.isEmpty(methods)) {
return Collections.emptyMap();
}
final Map<Method, T> results = new LinkedHashMap<>();
for (final Method method : methods) {
final T result = lookup.inspect(method);
final T result = lookup.apply(method);
if (Objects.nonNull(result)) {
results.put(method, result);
}
@ -189,7 +188,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法集合
*/
public static Set<Method> findFromSpecificMethods(final Method[] methods, final MethodMetadataLookup<?> lookup) {
public static Set<Method> findFromSpecificMethods(final Method[] methods, final Function<Method, ?> lookup) {
return findWithMetadataFromSpecificMethods(methods, lookup).keySet();
}
@ -201,9 +200,9 @@ public class MethodScanner {
* @return 方法与对应的元数据
* @param <T> 值类型
*/
public static <T> Map.Entry<Method, T> getWithMetadataFromSpecificMethods(final Method[] methods, final MethodMetadataLookup<T> lookup) {
public static <T> Map.Entry<Method, T> getWithMetadataFromSpecificMethods(final Method[] methods, final Function<Method, T> lookup) {
for (final Method method : methods) {
final T result = lookup.inspect(method);
final T result = lookup.apply(method);
if (Objects.nonNull(result)) {
return MapUtil.entry(method, result);
}
@ -218,7 +217,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法
*/
public static Method getFromSpecificMethods(final Method[] methods, final MethodMetadataLookup<?> lookup) {
public static Method getFromSpecificMethods(final Method[] methods, final Function<Method, ?> lookup) {
final Map.Entry<Method, ?> result = getWithMetadataFromSpecificMethods(methods, lookup);
return Objects.isNull(result) ? null : result.getKey();
}
@ -235,7 +234,7 @@ public class MethodScanner {
* @return 方法与对应的元数据集合
* @param <T> 值类型
*/
public static <T> Map<Method, T> findWithMetadataFromMethods(final Class<?> type, final MethodMetadataLookup<T> lookup) {
public static <T> Map<Method, T> findWithMetadataFromMethods(final Class<?> type, final Function<Method, T> lookup) {
return findWithMetadataFromSpecificMethods(getMethods(type), lookup);
}
@ -246,7 +245,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法集合
*/
public static Set<Method> findFromMethods(final Class<?> type, final MethodMetadataLookup<?> lookup) {
public static Set<Method> findFromMethods(final Class<?> type, final Function<Method, ?> lookup) {
return findFromSpecificMethods(getMethods(type), lookup);
}
@ -258,7 +257,7 @@ public class MethodScanner {
* @return 方法及元数据若无任何匹配的结果则返回{@code null}
* @param <T> 值类型
*/
public static <T> Map.Entry<Method, T> getWithMetadataFromMethods(final Class<?> type, final MethodMetadataLookup<T> lookup) {
public static <T> Map.Entry<Method, T> getWithMetadataFromMethods(final Class<?> type, final Function<Method, T> lookup) {
return getWithMetadataFromSpecificMethods(getMethods(type), lookup);
}
@ -269,7 +268,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法若无任何匹配的结果则返回{@code null}
*/
public static Method getFromMethods(final Class<?> type, final MethodMetadataLookup<?> lookup) {
public static Method getFromMethods(final Class<?> type, final Function<Method, ?> lookup) {
return getFromSpecificMethods(getMethods(type), lookup);
}
@ -285,7 +284,7 @@ public class MethodScanner {
* @return 方法与对应的元数据集合
* @param <T> 值类型
*/
public static <T> Map<Method, T> findWithMetadataFromDeclaredMethods(final Class<?> type, final MethodMetadataLookup<T> lookup) {
public static <T> Map<Method, T> findWithMetadataFromDeclaredMethods(final Class<?> type, final Function<Method, T> lookup) {
return findWithMetadataFromSpecificMethods(getDeclaredMethods(type), lookup);
}
@ -296,7 +295,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法集合
*/
public static Set<Method> findFromDeclaredMethods(final Class<?> type, final MethodMetadataLookup<?> lookup) {
public static Set<Method> findFromDeclaredMethods(final Class<?> type, final Function<Method, ?> lookup) {
return findFromSpecificMethods(getDeclaredMethods(type), lookup);
}
@ -308,7 +307,7 @@ public class MethodScanner {
* @return 方法及元数据若无任何匹配的结果则返回{@code null}
* @param <T> 值类型
*/
public static <T> Map.Entry<Method, T> getWithMetadataFromDeclaredMethods(final Class<?> type, final MethodMetadataLookup<T> lookup) {
public static <T> Map.Entry<Method, T> getWithMetadataFromDeclaredMethods(final Class<?> type, final Function<Method, T> lookup) {
return getWithMetadataFromSpecificMethods(getDeclaredMethods(type), lookup);
}
@ -319,7 +318,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法若无任何匹配的结果则返回{@code null}
*/
public static Method getFromDeclaredMethods(final Class<?> type, final MethodMetadataLookup<?> lookup) {
public static Method getFromDeclaredMethods(final Class<?> type, final Function<Method, ?> lookup) {
return getFromSpecificMethods(getDeclaredMethods(type), lookup);
}
@ -336,7 +335,7 @@ public class MethodScanner {
* @return 方法与对应的元数据集合
* @param <T> 值类型
*/
public static <T> Map<Method, T> findWithMetadataFromAllMethods(final Class<?> type, final MethodMetadataLookup<T> lookup) {
public static <T> Map<Method, T> findWithMetadataFromAllMethods(final Class<?> type, final Function<Method, T> lookup) {
return findWithMetadataFromSpecificMethods(getAllMethods(type), lookup);
}
@ -347,7 +346,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法集合
*/
public static Set<Method> findFromAllMethods(final Class<?> type, final MethodMetadataLookup<?> lookup) {
public static Set<Method> findFromAllMethods(final Class<?> type, final Function<Method, ?> lookup) {
return findFromSpecificMethods(getAllMethods(type), lookup);
}
@ -359,7 +358,7 @@ public class MethodScanner {
* @return 方法及元数据若无任何匹配的结果则返回{@code null}
* @param <T> 值类型
*/
public static <T> Map.Entry<Method, T> getWithMetadataFromAllMethods(final Class<?> type, final MethodMetadataLookup<T> lookup) {
public static <T> Map.Entry<Method, T> getWithMetadataFromAllMethods(final Class<?> type, final Function<Method, T> lookup) {
if (Objects.isNull(type)) {
return null;
}
@ -382,7 +381,7 @@ public class MethodScanner {
* @param lookup 查找器
* @return 方法若无任何匹配的结果则返回{@code null}
*/
public static Method getFromAllMethods(final Class<?> type, final MethodMetadataLookup<?> lookup) {
public static Method getFromAllMethods(final Class<?> type, final Function<Method, ?> lookup) {
final Map.Entry<Method, ?> target = getWithMetadataFromAllMethods(type, lookup);
return Objects.isNull(target) ? null : target.getKey();
}

View File

@ -0,0 +1,54 @@
package org.dromara.hutool.core.math;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class EnglishNumberFormatterTest {
@Test
public void testFormatNull() {
// 测试传入null值的情况
final String result = EnglishNumberFormatter.format(null);
Assertions.assertEquals("", result);
}
@Test
public void testFormatInteger() {
// 测试传入整数的情况
String result = EnglishNumberFormatter.format(1234);
Assertions.assertEquals("ONE THOUSAND TWO HUNDRED AND THIRTY FOUR ONLY", result);
result = EnglishNumberFormatter.format(1204);
Assertions.assertEquals("ONE THOUSAND TWO HUNDRED AND FOUR ONLY", result);
result = EnglishNumberFormatter.format(1004);
Assertions.assertEquals("ONE THOUSAND FOUR ONLY", result);
}
@Test
public void testFormatDecimal() {
// 测试传入小数的情况
final String result = EnglishNumberFormatter.format(1234.56);
Assertions.assertEquals("ONE THOUSAND TWO HUNDRED AND THIRTY FOUR AND CENTS FIFTY SIX ONLY", result);
}
@Test
public void testFormatLargeNumber() {
// 测试传入大数字的情况
final String result = EnglishNumberFormatter.format(1234567890123L);
Assertions.assertEquals("ONE TRILLION TWO HUNDRED AND THIRTY FOUR BILLION FIVE HUNDRED AND SIXTY SEVEN MILLION EIGHT HUNDRED AND NINETY THOUSAND ONE HUNDRED AND TWENTY THREE ONLY", result);
}
@Test
public void testFormatNonNumeric() {
Assertions.assertThrows(NumberFormatException.class, ()->{
// 测试传入非数字字符串的情况
EnglishNumberFormatter.format("non-numeric");
});
}
@Test
public void issue3579Test() {
Assertions.assertEquals("ZERO AND CENTS TEN ONLY", EnglishNumberFormatter.format(0.1));
Assertions.assertEquals("ZERO AND CENTS ONE ONLY", EnglishNumberFormatter.format(0.01));
}
}

View File

@ -17,15 +17,14 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
import java.util.function.Predicate;
/**
* test for {@link MethodMatcher}
*
* @author huangchengxing
*/
class MethodMatcherTest {
private final MethodMatcher matchToString = t -> "toString".equals(t.getName());
private final Predicate<Method> matchToString = t -> "toString".equals(t.getName());
@SneakyThrows
@Test
@ -41,7 +40,7 @@ class MethodMatcherTest {
void and() {
final Method toString = Object.class.getDeclaredMethod("toString");
Assertions.assertTrue(matchToString.test(toString));
final MethodMatcher newMatcher = matchToString.and(t -> t.getReturnType() == String.class);
final Predicate<Method> newMatcher = matchToString.and(t -> t.getReturnType() == String.class);
Assertions.assertTrue(newMatcher.test(toString));
}
@ -50,14 +49,14 @@ class MethodMatcherTest {
void negate() {
final Method toString = Object.class.getDeclaredMethod("toString");
Assertions.assertTrue(matchToString.test(toString));
final MethodMatcher newMatcher = matchToString.negate();
final Predicate<Method> newMatcher = matchToString.negate();
Assertions.assertFalse(newMatcher.test(toString));
}
@SneakyThrows
@Test
void or() {
final MethodMatcher newMatcher = matchToString.or(t -> "hashCode".equals(t.getName()));
final Predicate<Method> newMatcher = matchToString.or(t -> "hashCode".equals(t.getName()));
final Method toString = Object.class.getDeclaredMethod("toString");
final Method hashCode = Object.class.getDeclaredMethod("hashCode");
Assertions.assertTrue(newMatcher.test(toString));
@ -68,8 +67,8 @@ class MethodMatcherTest {
@Test
void inspect() {
final Method toString = Object.class.getDeclaredMethod("toString");
Assertions.assertTrue(matchToString.inspect(toString));
Assertions.assertTrue(matchToString.test(toString));
final Method hashCode = Object.class.getDeclaredMethod("hashCode");
Assertions.assertNull(matchToString.inspect(hashCode));
Assertions.assertFalse(matchToString.test(hashCode));
}
}

View File

@ -29,6 +29,7 @@ import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
/**
* test for {@link MethodMatcherUtil}
@ -59,14 +60,14 @@ class MethodMatcherUtilsTest {
@Test
void testForName() {
MethodMatcher methodMatcher = MethodMatcherUtil.forName("noneReturnNoArgs");
final Predicate<Method> methodMatcher = MethodMatcherUtil.forName("noneReturnNoArgs");
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
}
@Test
void forNameIgnoreCase() {
MethodMatcher methodMatcher = MethodMatcherUtil.forNameIgnoreCase("noneReturnNoArgs");
Predicate<Method> methodMatcher = MethodMatcherUtil.forNameIgnoreCase("noneReturnNoArgs");
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
// if name is upper case, it will be ignored
@ -77,7 +78,7 @@ class MethodMatcherUtilsTest {
@Test
void forNoneReturnType() {
MethodMatcher methodMatcher = MethodMatcherUtil.forNoneReturnType();
final Predicate<Method> methodMatcher = MethodMatcherUtil.forNoneReturnType();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -88,7 +89,7 @@ class MethodMatcherUtilsTest {
@Test
void forReturnType() {
MethodMatcher methodMatcher = MethodMatcherUtil.forReturnType(Collection.class);
final Predicate<Method> methodMatcher = MethodMatcherUtil.forReturnType(Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
@ -99,7 +100,7 @@ class MethodMatcherUtilsTest {
@Test
void forStrictReturnType() {
MethodMatcher methodMatcher = MethodMatcherUtil.forStrictReturnType(Collection.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.forStrictReturnType(Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
@ -118,7 +119,7 @@ class MethodMatcherUtilsTest {
@Test
void forParameterCount() {
MethodMatcher methodMatcher = MethodMatcherUtil.forParameterCount(2);
final Predicate<Method> methodMatcher = MethodMatcherUtil.forParameterCount(2);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -127,7 +128,7 @@ class MethodMatcherUtilsTest {
@Test
void forMostSpecificParameterTypes() {
// match none args method
MethodMatcher methodMatcher = MethodMatcherUtil.forMostSpecificParameterTypes();
Predicate<Method> methodMatcher = MethodMatcherUtil.forMostSpecificParameterTypes();
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
@ -159,7 +160,7 @@ class MethodMatcherUtilsTest {
@Test
void forMostSpecificStrictParameterTypes() {
// match none args method
MethodMatcher methodMatcher = MethodMatcherUtil.forMostSpecificStrictParameterTypes();
Predicate<Method> methodMatcher = MethodMatcherUtil.forMostSpecificStrictParameterTypes();
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
@ -194,7 +195,7 @@ class MethodMatcherUtilsTest {
@Test
void forParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtil.forParameterTypes();
Predicate<Method> methodMatcher = MethodMatcherUtil.forParameterTypes();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
@ -213,7 +214,7 @@ class MethodMatcherUtilsTest {
@Test
void forStrictParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtil.forStrictParameterTypes();
Predicate<Method> methodMatcher = MethodMatcherUtil.forStrictParameterTypes();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
@ -242,7 +243,7 @@ class MethodMatcherUtilsTest {
@Test
void noneMatch() {
MethodMatcher methodMatcher = MethodMatcherUtil.noneMatch();
Predicate<Method> methodMatcher = MethodMatcherUtil.noneMatch();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -261,7 +262,7 @@ class MethodMatcherUtilsTest {
@Test
void anyMatch() {
MethodMatcher methodMatcher = MethodMatcherUtil.anyMatch();
Predicate<Method> methodMatcher = MethodMatcherUtil.anyMatch();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
@ -281,7 +282,7 @@ class MethodMatcherUtilsTest {
@Test
void allMatch() {
MethodMatcher methodMatcher = MethodMatcherUtil.allMatch();
Predicate<Method> methodMatcher = MethodMatcherUtil.allMatch();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -304,7 +305,7 @@ class MethodMatcherUtilsTest {
@Test
void isPublic() {
MethodMatcher methodMatcher = MethodMatcherUtil.isPublic();
final Predicate<Method> methodMatcher = MethodMatcherUtil.isPublic();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -315,7 +316,7 @@ class MethodMatcherUtilsTest {
@Test
void isStatic() {
MethodMatcher methodMatcher = MethodMatcherUtil.isStatic();
final Predicate<Method> methodMatcher = MethodMatcherUtil.isStatic();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -326,7 +327,7 @@ class MethodMatcherUtilsTest {
@Test
void isPublicStatic() {
MethodMatcher methodMatcher = MethodMatcherUtil.isPublicStatic();
final Predicate<Method> methodMatcher = MethodMatcherUtil.isPublicStatic();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -337,7 +338,7 @@ class MethodMatcherUtilsTest {
@Test
void forModifiers() {
MethodMatcher methodMatcher = MethodMatcherUtil.forModifiers(Modifier.PUBLIC, Modifier.STATIC);
final Predicate<Method> methodMatcher = MethodMatcherUtil.forModifiers(Modifier.PUBLIC, Modifier.STATIC);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -348,7 +349,7 @@ class MethodMatcherUtilsTest {
@Test
void forNameAndParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtil.forNameAndParameterTypes("noneReturnTwoArgs", CharSequence.class, List.class);
final Predicate<Method> methodMatcher = MethodMatcherUtil.forNameAndParameterTypes("noneReturnTwoArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -359,7 +360,7 @@ class MethodMatcherUtilsTest {
@Test
void forNameAndStrictParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtil.forNameAndStrictParameterTypes("noneReturnTwoArgs", CharSequence.class, List.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.forNameAndStrictParameterTypes("noneReturnTwoArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
@ -378,7 +379,7 @@ class MethodMatcherUtilsTest {
@Test
void forNameIgnoreCaseAndParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtil.forNameIgnoreCaseAndParameterTypes("NONEReturnTWOArgs", CharSequence.class, List.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.forNameIgnoreCaseAndParameterTypes("NONEReturnTWOArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -397,7 +398,7 @@ class MethodMatcherUtilsTest {
@Test
void forNameIgnoreCaseAndStrictParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtil.forNameIgnoreCaseAndStrictParameterTypes("NONEReturnTWOArgs", CharSequence.class, List.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.forNameIgnoreCaseAndStrictParameterTypes("NONEReturnTWOArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
@ -416,7 +417,7 @@ class MethodMatcherUtilsTest {
@Test
void forStrictMethodSignature() {
MethodMatcher methodMatcher = MethodMatcherUtil.forStrictMethodSignature("noneReturnTwoArgs", null, CharSequence.class, Collection.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.forStrictMethodSignature("noneReturnTwoArgs", null, CharSequence.class, Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs2));
@ -435,7 +436,7 @@ class MethodMatcherUtilsTest {
@Test
void forStrictMethodSignatureWithMethod() {
MethodMatcher methodMatcher = MethodMatcherUtil.forStrictMethodSignature(noneReturnTwoArgs);
Predicate<Method> methodMatcher = MethodMatcherUtil.forStrictMethodSignature(noneReturnTwoArgs);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -454,7 +455,7 @@ class MethodMatcherUtilsTest {
@Test
void forMethodSignatureWithMethod() {
MethodMatcher methodMatcher = MethodMatcherUtil.forMethodSignature(noneReturnTwoArgs2);
final Predicate<Method> methodMatcher = MethodMatcherUtil.forMethodSignature(noneReturnTwoArgs2);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
@ -466,7 +467,7 @@ class MethodMatcherUtilsTest {
@Test
void forMethodSignature() {
MethodMatcher methodMatcher = MethodMatcherUtil.forMethodSignature(
final Predicate<Method> methodMatcher = MethodMatcherUtil.forMethodSignature(
"noneReturnTwoArgs", null, CharSequence.class, Collection.class
);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
@ -481,77 +482,77 @@ class MethodMatcherUtilsTest {
@Test
@SneakyThrows
void forGetterMethodWithField() {
Field nameField = Foo.class.getDeclaredField("name");
MethodMatcher methodMatcher = MethodMatcherUtil.forGetterMethod(nameField);
Method getName = Foo.class.getMethod("getName");
final Field nameField = Foo.class.getDeclaredField("name");
Predicate<Method> methodMatcher = MethodMatcherUtil.forGetterMethod(nameField);
final Method getName = Foo.class.getMethod("getName");
Assertions.assertTrue(methodMatcher.test(getName));
Field flagField = Foo.class.getDeclaredField("flag");
final Field flagField = Foo.class.getDeclaredField("flag");
methodMatcher = MethodMatcherUtil.forGetterMethod(flagField);
Method isFlag = Foo.class.getMethod("isFlag");
final Method isFlag = Foo.class.getMethod("isFlag");
Assertions.assertTrue(methodMatcher.test(isFlag));
Field objectField = Foo.class.getDeclaredField("object");
final Field objectField = Foo.class.getDeclaredField("object");
methodMatcher = MethodMatcherUtil.forGetterMethod(objectField);
Method object = Foo.class.getMethod("object");
final Method object = Foo.class.getMethod("object");
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void forGetterMethod() {
MethodMatcher methodMatcher = MethodMatcherUtil.forGetterMethod("name", String.class);
Method getName = Foo.class.getMethod("getName");
Predicate<Method> methodMatcher = MethodMatcherUtil.forGetterMethod("name", String.class);
final Method getName = Foo.class.getMethod("getName");
Assertions.assertTrue(methodMatcher.test(getName));
methodMatcher = MethodMatcherUtil.forGetterMethod("flag", boolean.class);
Method isFlag = Foo.class.getMethod("isFlag");
final Method isFlag = Foo.class.getMethod("isFlag");
Assertions.assertTrue(methodMatcher.test(isFlag));
methodMatcher = MethodMatcherUtil.forGetterMethod("object", Object.class);
Method object = Foo.class.getMethod("object");
final Method object = Foo.class.getMethod("object");
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void forSetterMethodWithField() {
Field nameField = Foo.class.getDeclaredField("name");
MethodMatcher methodMatcher = MethodMatcherUtil.forSetterMethod(nameField);
Method setName = Foo.class.getMethod("setName", String.class);
final Field nameField = Foo.class.getDeclaredField("name");
Predicate<Method> methodMatcher = MethodMatcherUtil.forSetterMethod(nameField);
final Method setName = Foo.class.getMethod("setName", String.class);
Assertions.assertTrue(methodMatcher.test(setName));
Field flagField = Foo.class.getDeclaredField("flag");
final Field flagField = Foo.class.getDeclaredField("flag");
methodMatcher = MethodMatcherUtil.forSetterMethod(flagField);
Method setFlag = Foo.class.getMethod("setFlag", boolean.class);
final Method setFlag = Foo.class.getMethod("setFlag", boolean.class);
Assertions.assertTrue(methodMatcher.test(setFlag));
Field objectField = Foo.class.getDeclaredField("object");
final Field objectField = Foo.class.getDeclaredField("object");
methodMatcher = MethodMatcherUtil.forSetterMethod(objectField);
Method object = Foo.class.getMethod("object", Object.class);
final Method object = Foo.class.getMethod("object", Object.class);
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void forSetterMethod() {
MethodMatcher methodMatcher = MethodMatcherUtil.forSetterMethod("name", String.class);
Method setName = Foo.class.getMethod("setName", String.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.forSetterMethod("name", String.class);
final Method setName = Foo.class.getMethod("setName", String.class);
Assertions.assertTrue(methodMatcher.test(setName));
methodMatcher = MethodMatcherUtil.forSetterMethod("flag", boolean.class);
Method setFlag = Foo.class.getMethod("setFlag", boolean.class);
final Method setFlag = Foo.class.getMethod("setFlag", boolean.class);
Assertions.assertTrue(methodMatcher.test(setFlag));
methodMatcher = MethodMatcherUtil.forSetterMethod("object", Object.class);
Method object = Foo.class.getMethod("object", Object.class);
final Method object = Foo.class.getMethod("object", Object.class);
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void hasDeclaredAnnotation() {
MethodMatcher methodMatcher = MethodMatcherUtil.hasDeclaredAnnotation(GrandParentAnnotation.class);
final Predicate<Method> methodMatcher = MethodMatcherUtil.hasDeclaredAnnotation(GrandParentAnnotation.class);
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
@ -561,7 +562,7 @@ class MethodMatcherUtilsTest {
@Test
@SneakyThrows
void hasAnnotation() {
MethodMatcher methodMatcher = MethodMatcherUtil.hasAnnotation(GrandParentAnnotation.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.hasAnnotation(GrandParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
@ -577,7 +578,7 @@ class MethodMatcherUtilsTest {
@Test
@SneakyThrows
void hasAnnotationOnDeclaringClass() {
MethodMatcher methodMatcher = MethodMatcherUtil.hasAnnotationOnDeclaringClass(GrandParentAnnotation.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.hasAnnotationOnDeclaringClass(GrandParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
@ -599,7 +600,7 @@ class MethodMatcherUtilsTest {
@Test
@SneakyThrows
void hasAnnotationOnMethodOrDeclaringClass() {
MethodMatcher methodMatcher = MethodMatcherUtil.hasAnnotationOnMethodOrDeclaringClass(GrandParentAnnotation.class);
Predicate<Method> methodMatcher = MethodMatcherUtil.hasAnnotationOnMethodOrDeclaringClass(GrandParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
@ -652,23 +653,23 @@ class MethodMatcherUtilsTest {
@Getter
private boolean flag;
private Object object;
public void setName(String name, Void none) { }
public void setName(final String name, final Void none) { }
public Object object() {
return object;
}
public Foo object(Object object) {
public Foo object(final Object object) {
this.object = object;
return this;
}
}
private void noneReturnNoArgs() { }
private static void noneReturnOneArgs(String arg1) { }
public static void noneReturnTwoArgs(String arg1, List<String> stringList) { }
public static void noneReturnTwoArgs(CharSequence arg1, Collection<String> stringList) { }
private static void noneReturnOneArgs(final String arg1) { }
public static void noneReturnTwoArgs(final String arg1, final List<String> stringList) { }
public static void noneReturnTwoArgs(final CharSequence arg1, final Collection<String> stringList) { }
public List<String> returnNoArgs() { return null; }
public Set<String> returnOneArgs(String arg1) { return null; }
public List<String> returnTwoArgs(String arg1, List<String> stringList) { return null; }
public Set<String> returnOneArgs(final String arg1) { return null; }
public List<String> returnTwoArgs(final String arg1, final List<String> stringList) { return null; }
}

View File

@ -27,7 +27,7 @@ import java.util.Set;
import java.util.stream.Stream;
/**
* test for {@link MethodScanner}
* test for {@link MethodScanner2}
*
* @author huangchengxing
*/
@ -35,52 +35,52 @@ class MethodScannerTest {
@Test
void testGetMethods() {
Assertions.assertEquals(0, MethodScanner.getMethods(null).length);
final Method[] actual = MethodScanner.getMethods(Child.class);
Assertions.assertSame(actual, MethodScanner.getMethods(Child.class));
Assertions.assertEquals(0, MethodScanner2.getMethods(null).length);
final Method[] actual = MethodScanner2.getMethods(Child.class);
Assertions.assertSame(actual, MethodScanner2.getMethods(Child.class));
final Method[] expected = Child.class.getMethods();
Assertions.assertArrayEquals(expected, actual);
}
@Test
void testGetDeclaredMethods() {
Assertions.assertEquals(0, MethodScanner.getDeclaredMethods(null).length);
final Method[] actual = MethodScanner.getDeclaredMethods(Child.class);
Assertions.assertSame(actual, MethodScanner.getDeclaredMethods(Child.class));
Assertions.assertEquals(0, MethodScanner2.getDeclaredMethods(null).length);
final Method[] actual = MethodScanner2.getDeclaredMethods(Child.class);
Assertions.assertSame(actual, MethodScanner2.getDeclaredMethods(Child.class));
final Method[] expected = Child.class.getDeclaredMethods();
Assertions.assertArrayEquals(expected, actual);
}
@Test
void testGetAllMethods() {
Assertions.assertEquals(0, MethodScanner.getAllMethods(null).length);
final Method[] actual = MethodScanner.getAllMethods(Child.class);
Assertions.assertEquals(0, MethodScanner2.getAllMethods(null).length);
final Method[] actual = MethodScanner2.getAllMethods(Child.class);
// get declared method from childparentgrandparent
final Method[] expected = Stream.of(Child.class, Parent.class, Interface.class, Object.class)
.flatMap(c -> Stream.of(MethodScanner.getDeclaredMethods(c)))
.flatMap(c -> Stream.of(MethodScanner2.getDeclaredMethods(c)))
.toArray(Method[]::new);
Assertions.assertArrayEquals(expected, actual);
}
@Test
void testClearCaches() {
final Method[] declaredMethods = MethodScanner.getDeclaredMethods(Child.class);
Assertions.assertSame(declaredMethods, MethodScanner.getDeclaredMethods(Child.class));
final Method[] methods = MethodScanner.getMethods(Child.class);
Assertions.assertSame(methods, MethodScanner.getMethods(Child.class));
final Method[] declaredMethods = MethodScanner2.getDeclaredMethods(Child.class);
Assertions.assertSame(declaredMethods, MethodScanner2.getDeclaredMethods(Child.class));
final Method[] methods = MethodScanner2.getMethods(Child.class);
Assertions.assertSame(methods, MethodScanner2.getMethods(Child.class));
// clear method cache
MethodScanner.clearCaches();
Assertions.assertNotSame(declaredMethods, MethodScanner.getDeclaredMethods(Child.class));
Assertions.assertNotSame(methods, MethodScanner.getMethods(Child.class));
MethodScanner2.clearCaches();
Assertions.assertNotSame(declaredMethods, MethodScanner2.getDeclaredMethods(Child.class));
Assertions.assertNotSame(methods, MethodScanner2.getMethods(Child.class));
}
@SneakyThrows
@Test
void testFindWithMetadataFromSpecificMethods() {
Assertions.assertTrue(MethodScanner.findWithMetadataFromSpecificMethods(null, m -> m.getAnnotation(Annotation.class)).isEmpty());
final Method[] methods = MethodScanner.getMethods(Child.class);
final Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromSpecificMethods(methods, m -> m.getAnnotation(Annotation.class));
Assertions.assertTrue(MethodScanner2.findWithMetadataFromSpecificMethods(null, m -> m.getAnnotation(Annotation.class)).isEmpty());
final Method[] methods = MethodScanner2.getMethods(Child.class);
final Map<Method, Annotation> actual = MethodScanner2.findWithMetadataFromSpecificMethods(methods, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -95,8 +95,8 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testFindFromSpecificMethods() {
final Method[] methods = MethodScanner.getMethods(Child.class);
final Set<Method> actual = MethodScanner.findFromSpecificMethods(methods, m -> m.getAnnotation(Annotation.class));
final Method[] methods = MethodScanner2.getMethods(Child.class);
final Set<Method> actual = MethodScanner2.findFromSpecificMethods(methods, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -108,8 +108,9 @@ class MethodScannerTest {
@Test
void testGetWithMetadataFromSpecificMethods() {
// find first oneArgMethod method
final Method[] methods = MethodScanner.getMethods(Child.class);
final Map.Entry<Method, Boolean> actual = MethodScanner.getWithMetadataFromSpecificMethods(methods, MethodMatcherUtil.forName("oneArgMethod"));
final Method[] methods = MethodScanner2.getMethods(Child.class);
final Map.Entry<Method, Boolean> actual = MethodScanner2.getWithMetadataFromSpecificMethods(methods,
(method -> method.getName().equals("oneArgMethod") ? true : null));
Assertions.assertNotNull(actual);
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
@ -120,8 +121,9 @@ class MethodScannerTest {
@Test
void testGetFromSpecificMethods() {
// find first oneArgMethod method
final Method[] methods = MethodScanner.getMethods(Child.class);
final Method actual = MethodScanner.getFromSpecificMethods(methods, MethodMatcherUtil.forName("oneArgMethod"));
final Method[] methods = MethodScanner2.getMethods(Child.class);
final Method actual = MethodScanner2.getFromSpecificMethods(methods, method ->
method.getName().equals("oneArgMethod") ? true : null);
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}
@ -129,7 +131,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testFindWithMetadataFromMethods() {
final Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Map<Method, Annotation> actual = MethodScanner2.findWithMetadataFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -144,7 +146,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testFindFromMethods() {
final Set<Method> actual = MethodScanner.findFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Set<Method> actual = MethodScanner2.findFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -155,7 +157,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testGetWithMetadataFromMethods() {
final Map.Entry<Method, Annotation> actual = MethodScanner.getWithMetadataFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Map.Entry<Method, Annotation> actual = MethodScanner2.getWithMetadataFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertNotNull(actual);
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
@ -166,7 +168,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testGetFromMethods() {
final Method actual = MethodScanner.getFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Method actual = MethodScanner2.getFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}
@ -174,7 +176,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testFindWithMetadataFromDeclaredMethods() {
final Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
final Map<Method, Annotation> actual = MethodScanner2.findWithMetadataFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -189,7 +191,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testFindFromDeclaredMethods() {
final Set<Method> actual = MethodScanner.findFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
final Set<Method> actual = MethodScanner2.findFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -200,7 +202,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testGetWithMetadataFromDeclaredMethods() {
final Map.Entry<Method, Annotation> actual = MethodScanner.getWithMetadataFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
final Map.Entry<Method, Annotation> actual = MethodScanner2.getWithMetadataFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertNotNull(actual);
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
@ -211,7 +213,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testGetFromDeclaredMethods() {
final Method actual = MethodScanner.getFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
final Method actual = MethodScanner2.getFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}
@ -219,7 +221,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testFindWithMetadataFromAllMethods() {
final Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Map<Method, Annotation> actual = MethodScanner2.findWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -234,7 +236,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testFindFromAllMethods() {
final Set<Method> actual = MethodScanner.findFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Set<Method> actual = MethodScanner2.findFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
@ -245,8 +247,8 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testGetWithMetadataFromAllMethods() {
Assertions.assertNull(MethodScanner.getWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Alias.class)));
final Map.Entry<Method, Annotation> actual = MethodScanner.getWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertNull(MethodScanner2.getWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Alias.class)));
final Map.Entry<Method, Annotation> actual = MethodScanner2.getWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertNotNull(actual);
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
@ -257,7 +259,7 @@ class MethodScannerTest {
@SneakyThrows
@Test
void testGetFromAllMethods() {
final Method actual = MethodScanner.getFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Method actual = MethodScanner2.getFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
final Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}