This commit is contained in:
Looly
2022-06-18 23:03:06 +08:00
parent b0ed5bea9a
commit e9cf532af0
40 changed files with 327 additions and 415 deletions

View File

@@ -7,7 +7,6 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.collection.SetUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.func.Editor;
import cn.hutool.core.lang.mutable.MutableEntry;
import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.map.MapUtil;
@@ -36,6 +35,7 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
/**
@@ -529,7 +529,7 @@ public class BeanUtil {
*/
public static Map<String, Object> beanToMap(final Object bean, final String... properties) {
int mapSize = 16;
Editor<MutableEntry<String, Object>> editor = null;
UnaryOperator<MutableEntry<String, Object>> editor = null;
if (ArrayUtil.isNotEmpty(properties)) {
mapSize = properties.length;
final Set<String> propertiesSet = SetUtil.of(properties);
@@ -583,7 +583,7 @@ public class BeanUtil {
/**
* 对象转Map<br>
* 通过实现{@link Editor} 可以自定义字段值如果这个Editor返回null则忽略这个字段以便实现
* 通过实现{@link UnaryOperator} 可以自定义字段值如果这个Editor返回null则忽略这个字段以便实现
*
* <pre>
* 1. 字段筛选,可以去除不需要的字段
@@ -599,7 +599,7 @@ public class BeanUtil {
* @since 4.0.5
*/
public static Map<String, Object> beanToMap(final Object bean, final Map<String, Object> targetMap,
final boolean ignoreNullValue, final Editor<MutableEntry<String, Object>> keyEditor) {
final boolean ignoreNullValue, final UnaryOperator<MutableEntry<String, Object>> keyEditor) {
if (null == bean) {
return null;
}
@@ -762,7 +762,7 @@ public class BeanUtil {
* @return bean
* @since 5.6.4
*/
public static <T> T edit(final T bean, final Editor<Field> editor) {
public static <T> T edit(final T bean, final UnaryOperator<Field> editor) {
if (bean == null) {
return null;
}
@@ -772,7 +772,7 @@ public class BeanUtil {
if (ModifierUtil.isStatic(field)) {
continue;
}
editor.edit(field);
editor.apply(field);
}
return bean;
}

View File

@@ -2,7 +2,6 @@ package cn.hutool.core.bean.copier;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.Converter;
import cn.hutool.core.lang.func.Editor;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.lang.mutable.MutableEntry;
@@ -14,6 +13,7 @@ import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.UnaryOperator;
/**
* 属性拷贝选项<br>
@@ -53,7 +53,7 @@ public class CopyOptions implements Serializable {
/**
* 字段属性名和属性值编辑器用于自定义属性转换规则例如驼峰转下划线等自定义属性值转换规则例如null转""等)
*/
protected Editor<MutableEntry<String, Object>> fieldEditor;
protected UnaryOperator<MutableEntry<String, Object>> fieldEditor;
/**
* 是否支持transient关键字修饰和@Transient注解如果支持被修饰的字段或方法对应的字段将被忽略。
@@ -250,7 +250,7 @@ public class CopyOptions implements Serializable {
* @return CopyOptions
* @since 5.4.2
*/
public CopyOptions setFieldEditor(final Editor<MutableEntry<String, Object>> editor) {
public CopyOptions setFieldEditor(final UnaryOperator<MutableEntry<String, Object>> editor) {
this.fieldEditor = editor;
return this;
}
@@ -266,7 +266,7 @@ public class CopyOptions implements Serializable {
protected MutableEntry<String, Object> editField(final String fieldName, final Object fieldValue) {
final MutableEntry<String, Object> entry = new MutableEntry<>(fieldName, fieldValue);
return (null != this.fieldEditor) ?
this.fieldEditor.edit(entry) : entry;
this.fieldEditor.apply(entry) : entry;
}
/**

View File

@@ -2,7 +2,6 @@ package cn.hutool.core.collection.iter;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.reflect.FieldUtil;
import cn.hutool.core.reflect.MethodUtil;
@@ -623,27 +622,27 @@ public class IterUtil {
/**
* 过滤{@link Iterator}并将过滤后满足条件的元素添加到List中
*
* @param <E> 元素类型
* @param iter {@link Iterator}
* @param filter 过滤器,保留{@link Filter#accept(Object)}为{@code true}的元素
* @param <E> 元素类型
* @param iter {@link Iterator}
* @param predicate 过滤器,{@link Predicate#test(Object)}为{@code true}保留
* @return ArrayList
* @since 5.7.22
*/
public static <E> List<E> filterToList(final Iterator<E> iter, final Predicate<E> filter) {
return ListUtil.of(filtered(iter, filter));
public static <E> List<E> filterToList(final Iterator<E> iter, final Predicate<E> predicate) {
return ListUtil.of(filtered(iter, predicate));
}
/**
* 获取一个新的 {@link FilterIter},用于过滤指定元素
*
* @param iterator 被包装的 {@link Iterator}
* @param filter 过滤断言,{@link Filter#accept(Object)}为{@code true}保留元素{@code false}抛弃元素
* @param <E> 元素类型
* @param iterator 被包装的 {@link Iterator}
* @param predicate 过滤断言,{@link Predicate#test(Object)}为{@code true}保留元素
* @param <E> 元素类型
* @return {@link FilterIter}
* @since 5.8.0
*/
public static <E> FilterIter<E> filtered(final Iterator<? extends E> iterator, final Predicate<? super E> filter) {
return new FilterIter<>(iterator, filter);
public static <E> FilterIter<E> filtered(final Iterator<? extends E> iterator, final Predicate<? super E> predicate) {
return new FilterIter<>(iterator, predicate);
}
/**

View File

@@ -3,7 +3,6 @@ package cn.hutool.core.compress;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.text.StrUtil;
import java.io.Closeable;
@@ -13,6 +12,7 @@ import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
@@ -134,14 +134,14 @@ public class ZipReader implements Closeable {
* 解压到指定目录中
*
* @param outFile 解压到的目录
* @param entryFilter 过滤器,排除不需要的文件
* @param entryFilter 过滤器,只保留{@link Predicate#test(Object)}结果为{@code true}的文件
* @return 解压的目录
* @throws IORuntimeException IO异常
* @since 5.7.12
*/
public File readTo(final File outFile, final Filter<ZipEntry> entryFilter) throws IORuntimeException {
public File readTo(final File outFile, final Predicate<ZipEntry> entryFilter) throws IORuntimeException {
read((zipEntry) -> {
if (null == entryFilter || entryFilter.accept(zipEntry)) {
if (null == entryFilter || entryFilter.test(zipEntry)) {
//gitee issue #I4ZDQI
String path = zipEntry.getName();
if (FileUtil.isWindows()) {

View File

@@ -1,7 +1,6 @@
package cn.hutool.core.io.watch;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.util.ArrayUtil;
import java.io.Closeable;
@@ -21,6 +20,7 @@ import java.nio.file.WatchService;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
/**
* 文件监听服务,此服务可以同时监听多个路径。
@@ -129,10 +129,10 @@ public class WatchServer extends Thread implements Closeable, Serializable {
* 执行事件获取并处理
*
* @param action 监听回调函数实现此函数接口用于处理WatchEvent事件
* @param watchFilter 监听过滤接口通过实现此接口过滤掉不需要监听的情况null表示不过滤
* @param watchFilter 监听过滤接口,通过实现此接口过滤掉不需要监听的情况,{@link Predicate#test(Object)}为{@code true}保留,null表示不过滤
* @since 5.4.0
*/
public void watch(final WatchAction action, final Filter<WatchEvent<?>> watchFilter) {
public void watch(final WatchAction action, final Predicate<WatchEvent<?>> watchFilter) {
final WatchKey wk;
try {
wk = watchService.take();
@@ -146,7 +146,7 @@ public class WatchServer extends Thread implements Closeable, Serializable {
for (final WatchEvent<?> event : wk.pollEvents()) {
// 如果监听文件,检查当前事件是否与所监听文件关联
if (null != watchFilter && false == watchFilter.accept(event)) {
if (null != watchFilter && false == watchFilter.test(event)) {
continue;
}
@@ -160,9 +160,9 @@ public class WatchServer extends Thread implements Closeable, Serializable {
* 执行事件获取并处理
*
* @param watcher {@link Watcher}
* @param watchFilter 监听过滤接口通过实现此接口过滤掉不需要监听的情况null表示不过滤
* @param watchFilter 监听过滤接口,通过实现此接口过滤掉不需要监听的情况,{@link Predicate#test(Object)}为{@code true}保留,null表示不过滤
*/
public void watch(final Watcher watcher, final Filter<WatchEvent<?>> watchFilter) {
public void watch(final Watcher watcher, final Predicate<WatchEvent<?>> watchFilter) {
watch((event, currentPath)->{
final WatchEvent.Kind<?> kind = event.kind();

View File

@@ -1,24 +0,0 @@
package cn.hutool.core.lang.func;
/**
* 编辑器接口,常用于对于集合中的元素做统一编辑<br>
* 此编辑器两个作用:
*
* <pre>
* 1、如果返回值为{@code null},表示此值被抛弃
* 2、对对象做修改
* </pre>
*
* @param <T> 被编辑对象类型
* @author Looly
*/
@FunctionalInterface
public interface Editor<T> {
/**
* 修改过滤后的结果
*
* @param t 被过滤的对象
* @return 修改后的对象,如果被过滤返回{@code null}
*/
T edit(T t);
}

View File

@@ -1,17 +0,0 @@
package cn.hutool.core.lang.func;
/**
* 过滤器接口
*
* @author Looly
*/
@FunctionalInterface
public interface Filter<T> {
/**
* 是否接受对象
*
* @param t 检查的对象
* @return 是否接受对象
*/
boolean accept(T t);
}

View File

@@ -24,31 +24,31 @@ public class LambdaInfo {
private final Class<?> clazz;
private final SerializedLambda lambda;
public LambdaInfo(Executable executable, SerializedLambda lambda) {
public LambdaInfo(final Executable executable, final SerializedLambda lambda) {
if (executable instanceof Method) {
Method method = (Method) executable;
final Method method = (Method) executable;
this.parameterTypes = method.getGenericParameterTypes();
this.returnType = method.getGenericReturnType();
this.name = method.getName();
} else if (executable instanceof Constructor) {
Constructor<?> constructor = (Constructor<?>) executable;
final Constructor<?> constructor = (Constructor<?>) executable;
this.parameterTypes = constructor.getGenericParameterTypes();
this.returnType = constructor.getDeclaringClass();
this.name = constructor.getName();
} else {
throw new IllegalArgumentException("Unsupported executable type: " + executable.getClass());
}
int index = lambda.getInstantiatedMethodType().indexOf(";)");
final int index = lambda.getInstantiatedMethodType().indexOf(";)");
if (index > -1) {
boolean isArray = lambda.getInstantiatedMethodType().startsWith("([");
final boolean isArray = lambda.getInstantiatedMethodType().startsWith("([");
if (isArray) {
try {
this.instantiatedTypes = new Type[]{Class.forName(lambda.getInstantiatedMethodType().replace("/", ".").substring(0, index).substring(1) + ";")};
} catch (ClassNotFoundException e) {
} catch (final ClassNotFoundException e) {
throw new IllegalStateException(e);
}
} else {
String[] instantiatedTypeNames = lambda.getInstantiatedMethodType().substring(2, index).split(";L");
final String[] instantiatedTypeNames = lambda.getInstantiatedMethodType().substring(2, index).split(";L");
this.instantiatedTypes = new Type[instantiatedTypeNames.length];
for (int i = 0; i < instantiatedTypeNames.length; i++) {
this.instantiatedTypes[i] = ClassLoaderUtil.loadClass(instantiatedTypeNames[i]);

View File

@@ -1,18 +0,0 @@
package cn.hutool.core.lang.func;
/**
* 匹配接口
*
* @param <T> 匹配的对象类型
* @author Looly
*/
@FunctionalInterface
public interface Matcher<T> {
/**
* 给定对象是否匹配
*
* @param t 对象
* @return 是否匹配
*/
boolean match(T t);
}

View File

@@ -1,22 +0,0 @@
package cn.hutool.core.lang.func;
/**
* 替换器<br>
* 通过实现此接口完成指定类型对象的替换操作,替换后的目标类型依旧为指定类型
*
* @author looly
*
* @param <T> 被替换操作的类型
* @since 4.1.5
*/
@FunctionalInterface
public interface Replacer<T> {
/**
* 替换指定类型为目标类型
*
* @param t 被替换的对象
* @return 替代后的对象
*/
T replace(T t);
}

View File

@@ -5,8 +5,6 @@ import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.collection.iter.ArrayIter;
import cn.hutool.core.collection.iter.IterUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.func.Editor;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.reflect.ConstructorUtil;
import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.text.StrUtil;
@@ -32,6 +30,8 @@ import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
/**
@@ -658,7 +658,7 @@ public class MapUtil {
* @return 编辑后的Map
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> edit(final Map<K, V> map, final Editor<Entry<K, V>> editor) {
public static <K, V> Map<K, V> edit(final Map<K, V> map, final UnaryOperator<Entry<K, V>> editor) {
if (null == map || null == editor) {
return map;
}
@@ -673,7 +673,7 @@ public class MapUtil {
Entry<K, V> modified;
for (final Entry<K, V> entry : map.entrySet()) {
modified = editor.edit(entry);
modified = editor.apply(entry);
if (null != modified) {
map2.put(modified.getKey(), modified.getValue());
}
@@ -689,18 +689,18 @@ public class MapUtil {
* 1、过滤出需要的对象如果返回null表示这个元素对象抛弃
* </pre>
*
* @param <K> Key类型
* @param <V> Value类型
* @param map Map
* @param filter 过滤器接口,{@code null}返回原Map
* @param <K> Key类型
* @param <V> Value类型
* @param map Map
* @param predicate 过滤器接口,{@link Predicate#test(Object)}为{@code true}保留,{@code null}返回原Map
* @return 过滤后的Map
* @since 3.1.0
*/
public static <K, V> Map<K, V> filter(final Map<K, V> map, final Filter<Entry<K, V>> filter) {
if (null == map || null == filter) {
public static <K, V> Map<K, V> filter(final Map<K, V> map, final Predicate<Entry<K, V>> predicate) {
if (null == map || null == predicate) {
return map;
}
return edit(map, t -> filter.accept(t) ? t : null);
return edit(map, t -> predicate.test(t) ? t : null);
}

View File

@@ -5,10 +5,9 @@ import cn.hutool.core.collection.iter.EnumerationIter;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.JNDIUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.text.StrUtil;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
@@ -40,6 +39,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;
/**
* 网络相关工具
@@ -424,11 +424,11 @@ public class NetUtil {
/**
* 获取所有满足过滤条件的本地IP地址对象
*
* @param addressFilter 过滤器null表示不过滤获取所有地址
* @param addressPredicate 过滤器,{@link Predicate#test(Object)}为{@code true}保留,null表示不过滤获取所有地址
* @return 过滤后的地址对象列表
* @since 4.5.17
*/
public static LinkedHashSet<InetAddress> localAddressList(final Filter<InetAddress> addressFilter) {
public static LinkedHashSet<InetAddress> localAddressList(final Predicate<InetAddress> addressPredicate) {
final Enumeration<NetworkInterface> networkInterfaces;
try {
networkInterfaces = NetworkInterface.getNetworkInterfaces();
@@ -447,7 +447,7 @@ public class NetUtil {
final Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
while (inetAddresses.hasMoreElements()) {
final InetAddress inetAddress = inetAddresses.nextElement();
if (inetAddress != null && (null == addressFilter || addressFilter.accept(inetAddress))) {
if (inetAddress != null && (null == addressPredicate || addressPredicate.test(inetAddress))) {
ipSet.add(inetAddress);
}
}
@@ -462,7 +462,7 @@ public class NetUtil {
* 此方法不会抛出异常,获取失败将返回{@code null}<br>
* <p>
* 参考:<a href="http://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java">
* http://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java</a>
* http://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java</a>
*
* @return 本机网卡IP地址获取失败返回{@code null}
* @since 3.0.7

View File

@@ -4,7 +4,6 @@ import cn.hutool.core.annotation.Alias;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.text.StrUtil;
@@ -13,6 +12,7 @@ import cn.hutool.core.util.ArrayUtil;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
/**
* 反射中{@link Field}字段工具类,包括字段获取和字段赋值。
@@ -125,13 +125,13 @@ public class FieldUtil {
* 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。
*
* @param beanClass 类
* @param fieldFilter field过滤器过滤掉不需要的field
* @param fieldPredicate field过滤器过滤掉不需要的field{@link Predicate#test(Object)}为{@code true}保留null表示全部保留
* @return 字段列表
* @throws SecurityException 安全检查异常
* @since 5.7.14
*/
public static Field[] getFields(final Class<?> beanClass, final Filter<Field> fieldFilter) throws SecurityException {
return ArrayUtil.filter(getFields(beanClass), fieldFilter);
public static Field[] getFields(final Class<?> beanClass, final Predicate<Field> fieldPredicate) throws SecurityException {
return ArrayUtil.filter(getFields(beanClass), fieldPredicate);
}
/**

View File

@@ -9,7 +9,6 @@ import cn.hutool.core.exceptions.InvocationTargetRuntimeException;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Singleton;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil;
@@ -21,6 +20,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
/**
* 反射中{@link Method}相关工具类,包括方法获取和方法执行<br>
@@ -67,21 +67,21 @@ public class MethodUtil {
/**
* 获得指定类过滤后的Public方法列表<br>
*
* @param clazz 查找方法的类
* @param filter 过滤器
* @param clazz 查找方法的类
* @param predicate 过滤器{@link Predicate#test(Object)}为{@code true}保留null表示保留全部
* @return 过滤后的方法数组
*/
public static Method[] getPublicMethods(final Class<?> clazz, final Filter<Method> filter) {
public static Method[] getPublicMethods(final Class<?> clazz, final Predicate<Method> predicate) {
if (null == clazz) {
return null;
}
final Method[] methods = getPublicMethods(clazz);
if (null == filter) {
if (null == predicate) {
return methods;
}
return ArrayUtil.filter(methods, filter);
return ArrayUtil.filter(methods, predicate);
}
/**
@@ -298,16 +298,16 @@ public class MethodUtil {
/**
* 获得指定类过滤后的Public方法列表
*
* @param clazz 查找方法的类
* @param filter 过滤器
* @param clazz 查找方法的类
* @param predicate 过滤器{@link Predicate#test(Object)}为{@code true}保留null表示全部保留。
* @return 过滤后的方法列表
* @throws SecurityException 安全异常
*/
public static Method[] getMethods(final Class<?> clazz, final Filter<Method> filter) throws SecurityException {
public static Method[] getMethods(final Class<?> clazz, final Predicate<Method> predicate) throws SecurityException {
if (null == clazz) {
return null;
}
return ArrayUtil.filter(getMethods(clazz), filter);
return ArrayUtil.filter(getMethods(clazz), predicate);
}
/**
@@ -566,7 +566,7 @@ public class MethodUtil {
* @param args 参数对象
* @return 结果
* @throws InvocationTargetException 目标方法执行异常
* @throws IllegalAccessException 访问权限异常
* @throws IllegalAccessException 访问权限异常
*/
@SuppressWarnings("unchecked")
public static <T> T invokeRaw(final Object obj, final Method method, final Object... args) throws InvocationTargetException, IllegalAccessException {

View File

@@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.comparator.VersionComparator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.lang.func.Matcher;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.math.NumberUtil;
import cn.hutool.core.regex.ReUtil;
import cn.hutool.core.text.finder.CharFinder;
import cn.hutool.core.text.finder.Finder;
import cn.hutool.core.text.finder.StrFinder;
@@ -14,8 +14,6 @@ import cn.hutool.core.text.split.SplitUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.math.NumberUtil;
import cn.hutool.core.regex.ReUtil;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
@@ -3701,7 +3699,7 @@ public class CharSequenceUtil {
/**
* 替换所有正则匹配的文本,并使用自定义函数决定如何替换<br>
* replaceFun可以通过{@link Matcher}提取出匹配到的内容的不同部分,然后经过重新处理、组装变成新的内容放回原位。
* replaceFun可以提取出匹配到的内容的不同部分然后经过重新处理、组装变成新的内容放回原位。
*
* <pre class="code">
* replace(this.content, "(\\d+)", parameters -&gt; "-" + parameters.group(1) + "-")
@@ -3994,12 +3992,12 @@ public class CharSequenceUtil {
* 过滤字符串
*
* @param str 字符串
* @param filter 过滤器,{@link Filter#accept(Object)}返回为{@code true}保留字符
* @param predicate 过滤器,{@link Predicate#test(Object)}为{@code true}保留字符
* @return 过滤后的字符串
* @since 5.4.0
*/
public static String filter(final CharSequence str, final Filter<Character> filter) {
if (str == null || filter == null) {
public static String filter(final CharSequence str, final Predicate<Character> predicate) {
if (str == null || predicate == null) {
return str(str);
}
@@ -4008,7 +4006,7 @@ public class CharSequenceUtil {
char c;
for (int i = 0; i < len; i++) {
c = str.charAt(i);
if (filter.accept(c)) {
if (predicate.test(c)) {
sb.append(c);
}
}
@@ -4361,12 +4359,12 @@ public class CharSequenceUtil {
* @return 是否全部匹配
* @since 3.2.3
*/
public static boolean isAllCharMatch(final CharSequence value, final Matcher<Character> matcher) {
public static boolean isAllCharMatch(final CharSequence value, final Predicate<Character> matcher) {
if (StrUtil.isBlank(value)) {
return false;
}
for (int i = value.length(); --i >= 0; ) {
if (false == matcher.match(value.charAt(i))) {
if (false == matcher.test(value.charAt(i))) {
return false;
}
}

View File

@@ -5,7 +5,8 @@ import cn.hutool.core.text.replacer.ReplacerChain;
/**
* XML特殊字符转义<br>
* 见https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents<br>
* 见:<a href="https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents">
* https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents</a><br>
*
* <pre>
* &amp; (ampersand) 替换为 &amp;amp;

View File

@@ -1,11 +1,12 @@
package cn.hutool.core.text.finder;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Matcher;
import java.util.function.Predicate;
/**
* 字符匹配查找器<br>
* 查找满足指定{@link Matcher} 匹配的字符所在位置,此类长用于查找某一类字符,如数字等
* 查找满足指定{@link Predicate} 匹配的字符所在位置,此类长用于查找某一类字符,如数字等
*
* @since 5.7.14
* @author looly
@@ -13,13 +14,13 @@ import cn.hutool.core.lang.func.Matcher;
public class CharMatcherFinder extends TextFinder {
private static final long serialVersionUID = 1L;
private final Matcher<Character> matcher;
private final Predicate<Character> matcher;
/**
* 构造
* @param matcher 被查找的字符匹配器
*/
public CharMatcherFinder(final Matcher<Character> matcher) {
public CharMatcherFinder(final Predicate<Character> matcher) {
this.matcher = matcher;
}
@@ -29,13 +30,13 @@ public class CharMatcherFinder extends TextFinder {
final int limit = getValidEndIndex();
if(negative){
for (int i = from; i > limit; i--) {
if(matcher.match(text.charAt(i))){
if(null == matcher || matcher.test(text.charAt(i))){
return i;
}
}
} else {
for (int i = from; i < limit; i++) {
if(matcher.match(text.charAt(i))){
if(null == matcher || matcher.test(text.charAt(i))){
return i;
}
}

View File

@@ -1,8 +1,7 @@
package cn.hutool.core.text.replacer;
import cn.hutool.core.lang.func.Replacer;
import java.io.Serializable;
import java.util.function.UnaryOperator;
/**
* 抽象字符串替换类<br>
@@ -11,7 +10,7 @@ import java.io.Serializable;
* @author looly
* @since 4.1.5
*/
public abstract class StrReplacer implements Replacer<CharSequence>, Serializable {
public abstract class StrReplacer implements UnaryOperator<CharSequence>, Serializable {
private static final long serialVersionUID = 1L;
/**
@@ -25,7 +24,7 @@ public abstract class StrReplacer implements Replacer<CharSequence>, Serializabl
protected abstract int replace(CharSequence str, int pos, StringBuilder out);
@Override
public CharSequence replace(final CharSequence t) {
public CharSequence apply(final CharSequence t) {
final int len = t.length();
final StringBuilder builder = new StringBuilder(len);
int pos = 0;//当前位置

View File

@@ -2,11 +2,10 @@ package cn.hutool.core.tree;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.text.StrUtil;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -14,6 +13,7 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* 通过转换器将你的实体转化为TreeNodeMap节点实体 属性都存在此处,属性有序,可支持排序
@@ -202,28 +202,28 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Node<T> {
/**
* 递归过滤并生成新的树<br>
* 通过{@link Filter}指定的过滤规则,本节点或子节点满足过滤条件,则保留当前节点,否则抛弃节点及其子节点
* 通过{@link Predicate}指定的过滤规则,本节点或子节点满足过滤条件,则保留当前节点,否则抛弃节点及其子节点
*
* @param filter 节点过滤规则函数,只需处理本级节点本身即可
* @param predicate 节点过滤规则函数,只需处理本级节点本身即可{@link Predicate#test(Object)}为{@code true}保留null表示全部保留
* @return 过滤后的节点,{@code null} 表示不满足过滤要求,丢弃之
* @see #filter(Filter)
* @see #filter(Predicate)
* @since 5.7.17
*/
public Tree<T> filterNew(final Filter<Tree<T>> filter) {
return cloneTree().filter(filter);
public Tree<T> filterNew(final Predicate<Tree<T>> predicate) {
return cloneTree().filter(predicate);
}
/**
* 递归过滤当前树,注意此方法会修改当前树<br>
* 通过{@link Filter}指定的过滤规则,本节点或子节点满足过滤条件,则保留当前节点及其所有子节点,否则抛弃节点及其子节点
* 通过{@link Predicate}指定的过滤规则,本节点或子节点满足过滤条件,则保留当前节点及其所有子节点,否则抛弃节点及其子节点
*
* @param filter 节点过滤规则函数,只需处理本级节点本身即可
* @param predicate 节点过滤规则函数,只需处理本级节点本身即可{@link Predicate#test(Object)}为{@code true}保留null表示保留全部
* @return 过滤后的节点,{@code null} 表示不满足过滤要求,丢弃之
* @see #filterNew(Filter)
* @see #filterNew(Predicate)
* @since 5.7.17
*/
public Tree<T> filter(final Filter<Tree<T>> filter) {
if(filter.accept(this)){
public Tree<T> filter(final Predicate<Tree<T>> predicate) {
if (null == predicate || predicate.test(this)) {
// 本节点满足,则包括所有子节点都保留
return this;
}
@@ -234,12 +234,12 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Node<T> {
final List<Tree<T>> filteredChildren = new ArrayList<>(children.size());
Tree<T> filteredChild;
for (final Tree<T> child : children) {
filteredChild = child.filter(filter);
filteredChild = child.filter(predicate);
if (null != filteredChild) {
filteredChildren.add(filteredChild);
}
}
if(CollUtil.isNotEmpty(filteredChildren)){
if (CollUtil.isNotEmpty(filteredChildren)) {
// 子节点有符合过滤条件的节点,则本节点保留
return this.setChildren(filteredChildren);
} else {
@@ -258,7 +258,7 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Node<T> {
* @return this
*/
public Tree<T> setChildren(final List<Tree<T>> children) {
if(null == children){
if (null == children) {
this.remove(treeNodeConfig.getChildrenKey());
}
this.put(treeNodeConfig.getChildrenKey(), children);

View File

@@ -6,9 +6,6 @@ import cn.hutool.core.collection.UniqueKeySet;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Editor;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.lang.func.Matcher;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrJoiner;
import cn.hutool.core.text.StrUtil;
@@ -27,6 +24,8 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
/**
@@ -164,7 +163,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @since 3.0.7
*/
@SuppressWarnings("unchecked")
public static <T> T firstMatch(final Matcher<T> matcher, final T... array) {
public static <T> T firstMatch(final Predicate<T> matcher, final T... array) {
final int index = matchIndex(matcher, array);
if (index < 0) {
return null;
@@ -183,7 +182,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @since 5.6.6
*/
@SuppressWarnings("unchecked")
public static <T> int matchIndex(final Matcher<T> matcher, final T... array) {
public static <T> int matchIndex(final Predicate<T> matcher, final T... array) {
return matchIndex(matcher, 0, array);
}
@@ -198,11 +197,10 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @since 5.7.3
*/
@SuppressWarnings("unchecked")
public static <T> int matchIndex(final Matcher<T> matcher, final int beginIndexInclude, final T... array) {
Assert.notNull(matcher, "Matcher must be not null !");
public static <T> int matchIndex(final Predicate<T> matcher, final int beginIndexInclude, final T... array) {
if (isNotEmpty(array)) {
for (int i = beginIndexInclude; i < array.length; i++) {
if (matcher.match(array[i])) {
if (null == matcher || matcher.test(array[i])) {
return i;
}
}
@@ -654,7 +652,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @return 编辑后的数组
* @since 5.3.3
*/
public static <T> T[] edit(final T[] array, final Editor<T> editor) {
public static <T> T[] edit(final T[] array, final UnaryOperator<T> editor) {
if (null == editor) {
return array;
}
@@ -662,7 +660,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
final ArrayList<T> list = new ArrayList<>(array.length);
T modified;
for (final T t : array) {
modified = editor.edit(t);
modified = editor.apply(t);
if (null != modified) {
list.add(modified);
}
@@ -676,20 +674,20 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* 过滤过程通过传入的Filter实现来过滤返回需要的元素内容这个Filter实现可以实现以下功能
*
* <pre>
* 1、过滤出需要的对象{@link Filter#accept(Object)}方法返回true对象将被加入结果集合中
* 1、过滤出需要的对象{@link Predicate#test(Object)}为{@code true}对象将被加入结果集合中
* </pre>
*
* @param <T> 数组元素类型
* @param array 数组
* @param filter 过滤器接口,用于定义过滤规则,{@code null}返回原集合
* @param <T> 数组元素类型
* @param array 数组
* @param predicate 过滤器接口,用于定义过滤规则,{@link Predicate#test(Object)}为{@code true}保留,{@code null}返回原集合
* @return 过滤后的数组
* @since 3.2.1
*/
public static <T> T[] filter(final T[] array, final Filter<T> filter) {
if (null == array || null == filter) {
public static <T> T[] filter(final T[] array, final Predicate<T> predicate) {
if (null == array || null == predicate) {
return array;
}
return edit(array, t -> filter.accept(t) ? t : null);
return edit(array, t -> predicate.test(t) ? t : null);
}
/**
@@ -1240,8 +1238,8 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @return 连接后的字符串
* @since 5.3.3
*/
public static <T> String join(final T[] array, final CharSequence conjunction, final Editor<T> editor) {
return StrJoiner.of(conjunction).append(array, (t) -> String.valueOf(editor.edit(t))).toString();
public static <T> String join(final T[] array, final CharSequence conjunction, final UnaryOperator<T> editor) {
return StrJoiner.of(conjunction).append(array, (t) -> String.valueOf(editor.apply(t))).toString();
}
/**