mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add methods
This commit is contained in:
parent
31e5eead89
commit
e38f9bf9b8
@ -0,0 +1,46 @@
|
|||||||
|
package cn.hutool.core.lang.func;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 两个函数的叠加函数. 叠加 {@code f: A->B} 和 {@code g: B->C},效果等同于:{@code h(a) == g(f(a))}
|
||||||
|
*
|
||||||
|
* @param <A> 第一个函数的传入参数类型
|
||||||
|
* @param <B> 第一个函数的返回类型(第二个函数有的参数类型)
|
||||||
|
* @param <C> 最终结果类型
|
||||||
|
* @author Guava
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class ComposeFunction<A, B, C> implements Function<A, C>, Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 两个函数的叠加函数. 叠加 {@code f: A->B} 和 {@code g: B->C},效果等同于:{@code h(a) == g(f(a))}
|
||||||
|
*
|
||||||
|
* @param g 第二个函数
|
||||||
|
* @param f 第一个函数
|
||||||
|
* @param <A> 第一个函数的传入参数类型
|
||||||
|
* @param <B> 第一个函数的返回类型(第二个函数有的参数类型)
|
||||||
|
* @param <C> 最终结果类型
|
||||||
|
* @return 叠加函数
|
||||||
|
*/
|
||||||
|
public static <A, B, C> ComposeFunction<A, B, C> of(final Function<B, C> g, final Function<A, ? extends B> f) {
|
||||||
|
return new ComposeFunction<>(g, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Function<B, C> g;
|
||||||
|
private final Function<A, ? extends B> f;
|
||||||
|
|
||||||
|
public ComposeFunction(final Function<B, C> g, final Function<A, ? extends B> f) {
|
||||||
|
this.g = Assert.notNull(g);
|
||||||
|
this.f = Assert.notNull(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public C apply(final A a) {
|
||||||
|
return g.apply(f.apply(a));
|
||||||
|
}
|
||||||
|
}
|
@ -132,6 +132,8 @@ public class LambdaUtil {
|
|||||||
return BeanUtil.getFieldName(getMethodName(func));
|
return BeanUtil.getFieldName(getMethodName(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//region Private methods
|
//region Private methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,138 @@
|
|||||||
|
package cn.hutool.core.lang.func;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.text.StrUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一些{@link Predicate}相关封装
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class PredicateUtil {
|
||||||
|
|
||||||
|
public static <T> Predicate<T> negate(final Predicate<T> predicate) {
|
||||||
|
return predicate.negate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个条件转换为”与“复合条件,即所有条件都为true时,才返回true
|
||||||
|
*
|
||||||
|
* @param <T> 判断条件的对象类型
|
||||||
|
* @param components 多个条件
|
||||||
|
* @return 复合条件
|
||||||
|
*/
|
||||||
|
public static <T> Predicate<T> and(final Iterable<? extends Predicate<? super T>> components) {
|
||||||
|
return new AndPredicate<>(ListUtil.of(components));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个条件转换为”与“复合条件,即所有条件都为true时,才返回true
|
||||||
|
*
|
||||||
|
* @param <T> 判断条件的对象类型
|
||||||
|
* @param components 多个条件
|
||||||
|
* @return 复合条件
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> Predicate<T> and(final Predicate<? super T>... components) {
|
||||||
|
return new AndPredicate<>(components);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个条件转换为”或“复合条件,即任意一个条件都为true时,返回true
|
||||||
|
*
|
||||||
|
* @param <T> 判断条件的对象类型
|
||||||
|
* @param components 多个条件
|
||||||
|
* @return 复合条件
|
||||||
|
*/
|
||||||
|
public static <T> Predicate<T> or(final Iterable<? extends Predicate<? super T>> components) {
|
||||||
|
return new OrPredicate<>(ListUtil.of(components));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个条件转换为”或“复合条件,即任意一个条件都为true时,返回true
|
||||||
|
*
|
||||||
|
* @param <T> 判断条件的对象类型
|
||||||
|
* @param components 多个条件
|
||||||
|
* @return 复合条件
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> Predicate<T> or(final Predicate<? super T>... components) {
|
||||||
|
return new OrPredicate<>(components);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个{@link Predicate}的与,只有所有条件满足才为true,当任意一个条件的test为false,返回false
|
||||||
|
*
|
||||||
|
* @param <T> 泛型类型
|
||||||
|
* @author Guava
|
||||||
|
*/
|
||||||
|
private static class AndPredicate<T> implements Predicate<T>, Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final List<? extends Predicate<? super T>> components;
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
private AndPredicate(final Predicate<? super T>... components) {
|
||||||
|
this.components = ListUtil.of(components);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AndPredicate(final List<? extends Predicate<? super T>> components) {
|
||||||
|
this.components = components;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(final T t) {
|
||||||
|
// Avoid using the Iterator to avoid generating garbage
|
||||||
|
//noinspection ForLoopReplaceableByForEach
|
||||||
|
for (int i = 0; i < components.size(); i++) {
|
||||||
|
if (false == components.get(i).test(t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Predicates.and(" + StrUtil.join(",", this.components) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个{@link Predicate}的或操作,即当一个条件满足,则全部满足,当任意一个条件的test为true,返回true
|
||||||
|
*
|
||||||
|
* @param <T> 泛型类型
|
||||||
|
* @author Guava
|
||||||
|
*/
|
||||||
|
private static class OrPredicate<T> implements Predicate<T>, Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final List<? extends Predicate<? super T>> components;
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
private OrPredicate(final Predicate<? super T>... components) {
|
||||||
|
this.components = ListUtil.of(components);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrPredicate(final List<? extends Predicate<? super T>> components) {
|
||||||
|
this.components = components;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(final T t) {
|
||||||
|
// Avoid using the Iterator to avoid generating garbage
|
||||||
|
//noinspection ForLoopReplaceableByForEach
|
||||||
|
for (int i = 0; i < components.size(); i++) {
|
||||||
|
if (false == components.get(i).test(t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,14 +16,14 @@ public class LambdaUtilTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getMethodNameTest() {
|
public void getMethodNameTest() {
|
||||||
Func1<MyTeacher, String> lambda = MyTeacher::getAge;
|
final Func1<MyTeacher, String> lambda = MyTeacher::getAge;
|
||||||
final String methodName = LambdaUtil.getMethodName(lambda);
|
final String methodName = LambdaUtil.getMethodName(lambda);
|
||||||
Assert.assertEquals("getAge", methodName);
|
Assert.assertEquals("getAge", methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getFieldNameTest() {
|
public void getFieldNameTest() {
|
||||||
Func1<MyTeacher, String> lambda = MyTeacher::getAge;
|
final Func1<MyTeacher, String> lambda = MyTeacher::getAge;
|
||||||
final String fieldName = LambdaUtil.getFieldName(lambda);
|
final String fieldName = LambdaUtil.getFieldName(lambda);
|
||||||
Assert.assertEquals("age", fieldName);
|
Assert.assertEquals("age", fieldName);
|
||||||
}
|
}
|
||||||
@ -32,43 +32,45 @@ public class LambdaUtilTest {
|
|||||||
public void resolveTest() {
|
public void resolveTest() {
|
||||||
Stream.<Runnable>of(() -> {
|
Stream.<Runnable>of(() -> {
|
||||||
// 引用构造函数
|
// 引用构造函数
|
||||||
Func0<MyTeacher> lambda = MyTeacher::new;
|
final Func0<MyTeacher> lambda = MyTeacher::new;
|
||||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||||
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
||||||
Assert.assertEquals(MyTeacher.class, lambdaInfo.getReturnType());
|
Assert.assertEquals(MyTeacher.class, lambdaInfo.getReturnType());
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 数组构造函数引用(此处数组构造参数)
|
// 数组构造函数引用(此处数组构造参数)
|
||||||
Func1<Integer, MyTeacher[]> lambda = MyTeacher[]::new;
|
final Func1<Integer, MyTeacher[]> lambda = MyTeacher[]::new;
|
||||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||||
Assert.assertEquals(int.class, lambdaInfo.getParameterTypes()[0]);
|
Assert.assertEquals(int.class, lambdaInfo.getParameterTypes()[0]);
|
||||||
Assert.assertEquals(MyTeacher.class, ((Class<Array>) lambdaInfo.getReturnType()).getComponentType());
|
Assert.assertEquals(MyTeacher.class, ((Class<Array>) lambdaInfo.getReturnType()).getComponentType());
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用静态方法
|
// 引用静态方法
|
||||||
Func0<String> lambda = MyTeacher::takeAge;
|
final Func0<String> lambda = MyTeacher::takeAge;
|
||||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||||
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
||||||
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用特定对象的实例方法
|
// 引用特定对象的实例方法
|
||||||
Func0<String> lambda = new MyTeacher()::getAge;
|
final Func0<String> lambda = new MyTeacher()::getAge;
|
||||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||||
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
||||||
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用特定类型的任意对象的实例方法
|
// 引用特定类型的任意对象的实例方法
|
||||||
Func1<MyTeacher, String> lambda = MyTeacher::getAge;
|
final Func1<MyTeacher, String> lambda = MyTeacher::getAge;
|
||||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||||
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
||||||
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 最最重要的!!!
|
// 最最重要的!!!
|
||||||
Character character = '0';
|
final Character character = '0';
|
||||||
Integer integer = 0;
|
final Integer integer = 0;
|
||||||
SerThiCons<Object, Boolean, String> lambda = (obj, bool, str) -> {
|
final SerThiCons<Object, Boolean, String> lambda = (obj, bool, str) -> {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
Objects.nonNull(character);
|
Objects.nonNull(character);
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
Objects.nonNull(integer);
|
Objects.nonNull(integer);
|
||||||
};
|
};
|
||||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||||
// 获取闭包使用的参数类型
|
// 获取闭包使用的参数类型
|
||||||
Assert.assertEquals(Character.class, lambdaInfo.getParameterTypes()[0]);
|
Assert.assertEquals(Character.class, lambdaInfo.getParameterTypes()[0]);
|
||||||
Assert.assertEquals(Integer.class, lambdaInfo.getParameterTypes()[1]);
|
Assert.assertEquals(Integer.class, lambdaInfo.getParameterTypes()[1]);
|
||||||
@ -102,35 +104,36 @@ public class LambdaUtilTest {
|
|||||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用特定对象的实例方法
|
// 引用特定对象的实例方法
|
||||||
Func0<String> lambda = myTeacher::getAge;
|
final Func0<String> lambda = myTeacher::getAge;
|
||||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 枚举测试,只能获取到枚举类型
|
// 枚举测试,只能获取到枚举类型
|
||||||
Func0<Integer> lambda = LambdaKindEnum.REF_NONE::ordinal;
|
final Func0<Integer> lambda = LambdaKindEnum.REF_NONE::ordinal;
|
||||||
Assert.assertEquals(Enum.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(Enum.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 调用父类方法,只能获取到父类类型
|
// 调用父类方法,只能获取到父类类型
|
||||||
VoidFunc0 lambda = myTeacher::getId;
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
final VoidFunc0 lambda = myTeacher::getId;
|
||||||
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用静态带参方法,能够获取到正确的参数类型
|
// 引用静态带参方法,能够获取到正确的参数类型
|
||||||
Func1<MyTeacher, String> lambda = MyTeacher::takeAgeBy;
|
final Func1<MyTeacher, String> lambda = MyTeacher::takeAgeBy;
|
||||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用父类静态带参方法,只能获取到父类类型
|
// 引用父类静态带参方法,只能获取到父类类型
|
||||||
Func0<?> lambda = MyTeacher::takeId;
|
final Func0<?> lambda = MyTeacher::takeId;
|
||||||
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用静态无参方法,能够获取到正确的类型
|
// 引用静态无参方法,能够获取到正确的类型
|
||||||
Func0<String> lambda = MyTeacher::takeAge;
|
final Func0<String> lambda = MyTeacher::takeAge;
|
||||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 引用父类静态无参方法,能够获取到正确的参数类型
|
// 引用父类静态无参方法,能够获取到正确的参数类型
|
||||||
Func1<MyTeacher, ?> lambda = MyTeacher::takeIdBy;
|
final Func1<MyTeacher, ?> lambda = MyTeacher::takeIdBy;
|
||||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// 数组测试
|
// 数组测试
|
||||||
VoidFunc1<String[]> lambda = (String[] stringList) -> {};
|
final VoidFunc1<String[]> lambda = (String[] stringList) -> {};
|
||||||
Assert.assertEquals(String[].class, LambdaUtil.getRealClass(lambda));
|
Assert.assertEquals(String[].class, LambdaUtil.getRealClass(lambda));
|
||||||
}).forEach(Runnable::run);
|
}).forEach(Runnable::run);
|
||||||
}
|
}
|
||||||
@ -176,6 +179,7 @@ public class LambdaUtilTest {
|
|||||||
/**
|
/**
|
||||||
* 测试Lambda类型枚举
|
* 测试Lambda类型枚举
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
enum LambdaKindEnum {
|
enum LambdaKindEnum {
|
||||||
REF_NONE,
|
REF_NONE,
|
||||||
REF_getField,
|
REF_getField,
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package cn.hutool.core.lang.func;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.SetUtil;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class PredicateUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void notContainsTest(){
|
||||||
|
final Set<String> sets = SetUtil.of("1", "2", "3");
|
||||||
|
final List<String> collect = Stream.of("3", "4", "5")
|
||||||
|
.filter(PredicateUtil.negate(sets::contains))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Assert.assertEquals(2, collect.size());
|
||||||
|
Assert.assertEquals("4", collect.get(0));
|
||||||
|
Assert.assertEquals("5", collect.get(1));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user