fix comment

This commit is contained in:
Looly 2024-07-15 20:03:24 +08:00
parent 052c45537b
commit 0220a1c55e
62 changed files with 557 additions and 249 deletions

View File

@ -32,8 +32,17 @@ import java.util.Map;
public class AnnotationProxy<T extends Annotation> implements Annotation, InvocationHandler, Serializable {
private static final long serialVersionUID = 1L;
/**
* 注解
*/
private final T annotation;
/**
* 注解类型
*/
private final Class<T> type;
/**
* 注解属性
*/
private final Map<String, Object> attributes;
/**

View File

@ -37,7 +37,13 @@ import java.util.Map;
public class DynaBean implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
/**
* bean类
*/
private final Class<?> beanClass;
/**
* bean对象
*/
private Object bean;
/**

View File

@ -28,7 +28,13 @@ import org.dromara.hutool.core.util.ObjUtil;
*/
public abstract class AbsCopier<S, T> implements Copier<T> {
/**
* 来源对象
*/
protected final S source;
/**
* 目标对象
*/
protected final T target;
/**
* 拷贝选项

View File

@ -46,7 +46,9 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
*
*/
private final Map<Mutable<K>, V> rawMap;
// 乐观读写锁
/**
* 乐观读写锁
*/
private final ReadWriteLock lock = new ReentrantReadWriteLock();
/**
* 写的时候每个key一把锁降低锁的粒度

View File

@ -42,6 +42,9 @@ import java.util.stream.Collectors;
public abstract class AbstractCache<K, V> implements Cache<K, V> {
private static final long serialVersionUID = 1L;
/**
* 缓存Map
*/
protected Map<Mutable<K>, CacheObj<K, V>> cacheMap;
/**

View File

@ -28,7 +28,13 @@ import java.util.concurrent.atomic.AtomicLong;
public class CacheObj<K, V> implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
protected final K key;
/**
* 值对象
*/
protected final V obj;
/**

View File

@ -29,7 +29,9 @@ import java.util.concurrent.locks.ReentrantLock;
public abstract class ReentrantCache<K, V> extends AbstractCache<K, V> {
private static final long serialVersionUID = 1L;
// 一些特殊缓存例如使用了LinkedHashMap的缓存由于get方法也会改变Map的结构导致无法使用读写锁
/**
* 一些特殊缓存例如使用了LinkedHashMap的缓存由于get方法也会改变Map的结构导致无法使用读写锁
*/
protected final ReentrantLock lock = new ReentrantLock();
@Override

View File

@ -25,12 +25,14 @@ import java.util.concurrent.locks.StampedLock;
* @author looly
* @since 5.7.15
*/
public abstract class StampedCache<K, V> extends AbstractCache<K, V>{
public abstract class StampedCache<K, V> extends AbstractCache<K, V> {
private static final long serialVersionUID = 1L;
// 乐观锁此处使用乐观锁解决读多写少的场景
// get时乐观读再检查是否修改修改则转入悲观读重新读一遍可以有效解决在写时阻塞大量读操作的情况
// see: https://www.cnblogs.com/jiagoushijuzi/p/13721319.html
/**
* 乐观锁此处使用乐观锁解决读多写少的场景<br>
* get时乐观读再检查是否修改修改则转入悲观读重新读一遍可以有效解决在写时阻塞大量读操作的情况<br>
* see: https://www.cnblogs.com/jiagoushijuzi/p/13721319.html
*/
protected final StampedLock lock = new StampedLock();
@Override
@ -163,7 +165,7 @@ public abstract class StampedCache<K, V> extends AbstractCache<K, V>{
// 无效移除
co = removeWithoutLock(key);
if(isUpdateCount){
if (isUpdateCount) {
missCount.increment();
}
} finally {

View File

@ -22,7 +22,9 @@ import org.dromara.hutool.core.lang.Assert;
*/
public class Caesar {
// 26个字母表
/**
* 26个字母表
*/
public static final String TABLE = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
/**

View File

@ -47,6 +47,17 @@ import java.util.stream.LongStream;
*/
public class Hashids implements Encoder<long[], String>, Decoder<String, long[]> {
/**
* 默认编解码字符串
*/
public static final char[] DEFAULT_ALPHABET = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'
};
private static final int LOTTERY_MOD = 100;
private static final double GUARD_THRESHOLD = 12;
private static final double SEPARATOR_THRESHOLD = 3.5;
@ -54,14 +65,6 @@ public class Hashids implements Encoder<long[], String>, Decoder<String, long[]>
private static final int MIN_ALPHABET_LENGTH = 16;
private static final Pattern HEX_VALUES_PATTERN = Pattern.compile("[\\w\\W]{1,12}");
// 默认编解码字符串
public static final char[] DEFAULT_ALPHABET = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'
};
// 默认分隔符
private static final char[] DEFAULT_SEPARATORS = {
'c', 'f', 'h', 'i', 's', 't', 'u', 'C', 'F', 'H', 'I', 'S', 'T', 'U'

View File

@ -26,6 +26,9 @@ import java.util.*;
*/
public class IterChain<T> implements Iterator<T>, Chain<Iterator<T>, IterChain<T>> {
/**
* 所有的Iterator
*/
protected final List<Iterator<T>> allIterators = new ArrayList<>();
/**
@ -68,6 +71,9 @@ public class IterChain<T> implements Iterator<T>, Chain<Iterator<T>, IterChain<T
// ---------------------------------------------------------------- interface
/**
* 当前位置
*/
protected int currentIter = -1;
@Override

View File

@ -29,7 +29,13 @@ import java.util.List;
*/
public class Partition<T> extends AbstractList<List<T>> {
/**
* 被分区的列表
*/
protected final List<T> list;
/**
* 每个分区的长度
*/
protected final int size;
/**
@ -54,7 +60,7 @@ public class Partition<T> extends AbstractList<List<T>> {
public int size() {
// 此处采用动态计算以应对list变
final int size = this.size;
if(0 == size){
if (0 == size) {
return 0;
}

View File

@ -21,12 +21,16 @@ import java.util.function.Predicate;
* 自定义加入前检查的{@link LinkedBlockingQueue}给定一个检查函数在加入元素前检查此函数<br>
* 原理是通过Runtime#freeMemory()获取剩余内存当剩余内存低于指定的阈值时不再加入
*
* @param <E> 元素类型
* @author looly
* @since 6.0.0
*/
public class CheckedLinkedBlockingQueue<E> extends LinkedBlockingQueue<E> {
private static final long serialVersionUID = 1L;
/**
* 检查函数
*/
protected final Predicate<E> checker;
/**
@ -42,7 +46,7 @@ public class CheckedLinkedBlockingQueue<E> extends LinkedBlockingQueue<E> {
/**
* 构造
*
* @param c 初始集合
* @param c 初始集合
* @param checker 检查函数
*/
public CheckedLinkedBlockingQueue(final Collection<? extends E> c, final Predicate<E> checker) {

View File

@ -30,7 +30,13 @@ import java.util.Objects;
public class NullComparator<T> implements Comparator<T>, Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否{@code null}最大排在最后
*/
protected final boolean nullGreater;
/**
* 实际比较器
*/
protected final Comparator<T> comparator;
/**

View File

@ -32,6 +32,9 @@ import java.lang.reflect.Type;
public class ReferenceConverter extends AbstractConverter {
private static final long serialVersionUID = 1L;
/**
* 单例
*/
public static ReferenceConverter INSTANCE = new ReferenceConverter();
@SuppressWarnings("unchecked")

View File

@ -29,18 +29,10 @@ import java.util.concurrent.atomic.AtomicInteger;
* 4. INC 自增计数器确保同一秒内产生objectId的唯一性
* </pre>
*
* <table summary="" border="1">
* <tr>
* <td>时间戳</td>
* <td>随机数</td>
* <td>自增计数器</td>
* </tr>
* <tr>
* <td>4</td>
* <td>4</td>
* <td>4</td>
* </tr>
* </table>
* <pre>
* | 时间戳 | 随机数 | 自增计数器 |
* | 4 | 4 | 4 |
* </pre>
* <p>
* 参考<a href="https://github.com/mongodb/mongo-java-driver/blob/master/bson/src/main/org/bson/types/ObjectId.java">...</a>
*

View File

@ -46,7 +46,9 @@ public class SeataSnowflake implements Generator<Long>, Serializable {
// 节点ID长度
private static final int NODE_ID_BITS = 10;
// 节点ID的最大值1023
/**
* 节点ID的最大值1023
*/
protected static final int MAX_NODE_ID = ~(-1 << NODE_ID_BITS);
// 时间戳长度
private static final int TIMESTAMP_BITS = 41;

View File

@ -53,10 +53,14 @@ public class Snowflake implements Generator<Long>, Serializable {
*/
public static final long DEFAULT_TWEPOCH = 1288834974657L;
private static final long WORKER_ID_BITS = 5L;
// 最大支持机器节点数0~31一共32个
/**
* 最大支持机器节点数0~31一共32个
*/
protected static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
private static final long DATA_CENTER_ID_BITS = 5L;
// 最大支持数据中心节点数0~31一共32个
/**
* 最大支持数据中心节点数0~31一共32个
*/
protected static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);
// 序列号12位表示只允许序号的范围为0-4095
private static final long SEQUENCE_BITS = 12L;

View File

@ -26,6 +26,9 @@ import java.nio.CharBuffer;
*/
public class ReaderWrapper extends Reader implements Wrapper<Reader> {
/**
* 原始Reader
*/
protected final Reader raw;
/**

View File

@ -29,6 +29,9 @@ public class CRC16 implements Checksum, Serializable {
private final CRC16Checksum crc16;
/**
* 构造
*/
public CRC16() {
this(new CRC16IBM());
}

View File

@ -33,6 +33,9 @@ public abstract class CRC16Checksum implements Checksum, Serializable {
*/
protected int wCRCin;
/**
* 构造
*/
public CRC16Checksum(){
reset();
}

View File

@ -26,6 +26,9 @@ import org.dromara.hutool.core.io.StreamProgress;
*/
public abstract class IoCopier<S, T> {
/**
* 缓存大小
*/
protected final int bufferSize;
/**
* 拷贝总数

View File

@ -30,7 +30,13 @@ import java.nio.charset.StandardCharsets;
public class FileWrapper implements Wrapper<File>, Serializable {
private static final long serialVersionUID = 1L;
/**
* 被包装的文件
*/
protected File file;
/**
* 编码
*/
protected Charset charset;
/**

View File

@ -21,26 +21,43 @@ package org.dromara.hutool.core.io.file;
* Windows系统换行符"\r\n"
* </pre>
*
* @author Looly
* @see #MAC
* @see #LINUX
* @see #WINDOWS
* @author Looly
* @since 3.1.0
*/
public enum LineSeparator {
/** Mac系统换行符"\r" */
/**
* Mac系统换行符"\r"
*/
MAC("\r"),
/** Linux系统换行符"\n" */
/**
* Linux系统换行符"\n"
*/
LINUX("\n"),
/** Windows系统换行符"\r\n" */
/**
* Windows系统换行符"\r\n"
*/
WINDOWS("\r\n");
private final String value;
/**
* 构造
*
* @param lineSeparator 换行符
*/
LineSeparator(final String lineSeparator) {
this.value = lineSeparator;
}
/**
* 获取换行符值
*
* @return
*/
public String getValue() {
return this.value;
}

View File

@ -32,9 +32,15 @@ import java.net.URL;
public class UrlResource implements Resource, Serializable {
private static final long serialVersionUID = 1L;
/**
* URL
*/
protected URL url;
private long lastModified = 0;
/**
* 资源名称
*/
protected String name;
private long lastModified = 0;
//-------------------------------------------------------------------------------------- Constructor start

View File

@ -56,6 +56,9 @@ public enum DataUnit {
*/
TERABYTES("TB", DataSize.ofTerabytes(1));
/**
* 单位名称列表
*/
public static final String[] UNIT_NAMES = new String[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"};
private final String suffix;

View File

@ -12,34 +12,74 @@
package org.dromara.hutool.core.io.watch;
import org.dromara.hutool.core.exception.ExceptionUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.exception.HutoolException;
/**
* 监听异常
* @author Looly
*
*/
public class WatchException extends RuntimeException {
public class WatchException extends HutoolException {
private static final long serialVersionUID = 8068509879445395353L;
/**
* 构造
*
* @param e 异常
*/
public WatchException(final Throwable e) {
super(ExceptionUtil.getMessage(e), e);
super(e);
}
/**
* 构造
*
* @param message 消息
*/
public WatchException(final String message) {
super(message);
}
/**
* 构造
*
* @param messageTemplate 消息模板
* @param params 参数
*/
public WatchException(final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params));
super(messageTemplate, params);
}
public WatchException(final String message, final Throwable throwable) {
super(message, throwable);
/**
* 构造
*
* @param message 消息
* @param cause 被包装的子异常
*/
public WatchException(final String message, final Throwable cause) {
super(message, cause);
}
public WatchException(final Throwable throwable, final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
/**
* 构造
*
* @param message 消息
* @param cause 被包装的子异常
* @param enableSuppression 是否启用抑制
* @param writableStackTrace 堆栈跟踪是否应该是可写的
*/
public WatchException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
/**
* 构造
*
* @param cause 被包装的子异常
* @param messageTemplate 消息模板
* @param params 参数
*/
public WatchException(final Throwable cause, final String messageTemplate, final Object... params) {
super(cause, messageTemplate, params);
}
}

View File

@ -40,7 +40,13 @@ public class MutableEntry<K, V> extends AbsEntry<K, V> implements Mutable<Map.En
return new MutableEntry<>(key, value);
}
/**
*
*/
protected K key;
/**
*
*/
protected V value;
/**

View File

@ -23,7 +23,13 @@ import org.dromara.hutool.core.text.StrUtil;
*/
public class DefaultSegment<T extends Number> implements Segment<T> {
/**
* 起始位置
*/
protected T beginIndex;
/**
* 结束位置
*/
protected T endIndex;
/**

View File

@ -42,7 +42,13 @@ public class Pair<L, R> implements Serializable, Cloneable {
return new Pair<>(left, right);
}
/**
* 左值第一个值
*/
protected L left;
/**
* 右值第二个值
*/
protected R right;
/**

View File

@ -42,6 +42,9 @@ public class Triple<L, M, R> extends Pair<L, R> {
return new Triple<>(left, middle, right);
}
/**
* 中值
*/
protected M middle;
/**
@ -57,6 +60,7 @@ public class Triple<L, M, R> extends Pair<L, R> {
}
// region ----- getXXX
/**
* 获取中值
*

View File

@ -22,6 +22,9 @@ package org.dromara.hutool.core.lang.wrapper;
*/
public class SimpleWrapper<T> implements Wrapper<T> {
/**
* 原始对象
*/
protected final T raw;
/**

View File

@ -10,28 +10,10 @@
* See the Mulan PSL v2 for more details.
*/
/**
* This package contains an implementation of a bounded
* {@link java.util.concurrent.ConcurrentMap} data structure.
* <p>
* {@link org.dromara.hutool.core.map.concurrent.Weigher} is a simple interface
* for determining how many units of capacity an entry consumes. Depending on
* which concrete Weigher class is used, an entry may consume a different amount
* of space within the cache. The
* {@link org.dromara.hutool.core.map.concurrent.Weighers} class provides
* utility methods for obtaining the most common kinds of implementations.
* <p>
* {@link org.dromara.hutool.core.map.concurrent.ConcurrentLinkedHashMap#listener} provides the
* ability to be notified when an entry is evicted from the map. An eviction
* occurs when the entry was automatically removed due to the map exceeding a
* capacity threshold. It is not called when an entry was explicitly removed.
* <p>
* The {@link org.dromara.hutool.core.map.concurrent.ConcurrentLinkedHashMap}
* class supplies an efficient, scalable, thread-safe, bounded map. As with the
* <tt>Java Collections Framework</tt> the "Concurrent" prefix is used to
* indicate that the map is not governed by a single exclusion lock.
* 并发Map工具类
*
* @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
* http://code.google.com/p/concurrentlinkedhashmap/</a>
* @author Looly
*/
package org.dromara.hutool.core.map.concurrent;

View File

@ -158,8 +158,8 @@ public class NumberValidator {
*
* @param s 校验的字符串, 只能含有 正负号数字字符 {@literal X/x}
* @return 是否为 {@link Integer}类型
* @apiNote 6.0.0 支持8进制和16进制
* @see Integer#decode(String)
* @since 6.0.0
*/
public static boolean isInteger(final String s) {
if (!isNumber(s)) {
@ -185,7 +185,7 @@ public class NumberValidator {
*
* @param s 校验的字符串, 只能含有 正负号数字字符{@literal X/x} 后缀{@literal L/l}
* @return 是否为 {@link Long}类型
* @apiNote 6.0.0 支持8进制和16进制数字
* @since 6.0.0
* @since 4.0.0
*/
public static boolean isLong(final String s) {

View File

@ -104,6 +104,9 @@ public class MultipartRequestInputStream extends BufferedInputStream {
// ---------------------------------------------------------------- data header
/**
* 最后的头部信息
*/
protected UploadFileHeader lastHeader;
/**

View File

@ -31,9 +31,6 @@ public class UploadSetting {
/** 扩展名是允许列表还是禁止列表 */
protected boolean isAllowFileExts = true;
public UploadSetting() {
}
// ---------------------------------------------------------------------- Setters and Getters start
/**
* @return 获得最大文件大小-1表示无限制

View File

@ -25,16 +25,28 @@ import java.nio.charset.Charset;
*/
public abstract class AbsServiceLoader<S> implements ServiceLoader<S> {
/**
* 路径前缀
*/
protected final String pathPrefix;
/**
* 服务类
*/
protected final Class<S> serviceClass;
/**
* 自定义类加载器
*/
protected final ClassLoader classLoader;
/**
* 编码
*/
protected final Charset charset;
/**
* 构造
*
* @param pathPrefix 路径前缀
* @param serviceClass 服务名称
* @param serviceClass 服务
* @param classLoader 自定义类加载器, {@code null}表示使用默认当前的类加载器
* @param charset 编码默认UTF-8
*/

View File

@ -471,17 +471,17 @@ public class EasyStream<T> extends AbstractEnhancedWrappedStream<T, EasyStream<T
public interface Builder<T> extends Consumer<T>, org.dromara.hutool.core.lang.builder.Builder<EasyStream<T>> {
/**
* Adds an element to the unwrap being built.
* Adds an element to the unwrap being built.<br>
* The default implementation behaves as if:
* <pre>{@code
* accept(t)
* return this;
* }</pre>
*
* @param t the element to add
* @param t 需要添加的元素
* @return {@code this} builder
* @throws IllegalStateException if the builder has already transitioned to
* the built state
* @implSpec The default implementation behaves as if:
* <pre>{@code
* accept(t)
* return this;
* }</pre>
*/
default Builder<T> add(final T t) {
accept(t);

View File

@ -214,7 +214,7 @@ public class StreamUtil {
public static <T> Stream<T> iterate(final T seed, final Predicate<? super T> hasNext, final UnaryOperator<T> next) {
Objects.requireNonNull(next);
Objects.requireNonNull(hasNext);
return StreamSupport.stream(IterateSpliterator.create(seed, hasNext, next), false);
return StreamSupport.stream(IterateSpliterator.of(seed, hasNext, next), false);
}
/**
@ -305,7 +305,7 @@ public class StreamUtil {
return Stream.empty();
}
Objects.requireNonNull(predicate);
return createStatefulNewStream(source, DropWhileSpliterator.create(source.spliterator(), predicate));
return createStatefulNewStream(source, DropWhileSpliterator.of(source.spliterator(), predicate));
}
// region ----- 私有方法

View File

@ -263,11 +263,7 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
// region ============ peek ============
/**
* 返回与指定函数将元素作为参数执行后组成的流操作带下标
*
* @param action 指定的函数
* @return 返回叠加操作后的FastStream
* @apiNote 该方法存在的意义主要是用来调试
* 返回与指定函数将元素作为参数执行后组成的流操作带下标该方法存在的意义主要是用来调试
* 当你需要查看经过操作管道某处的元素和下标可以执行以下操作:
* <pre>{@code
* Stream.of("one", "two", "three", "four")
@ -277,6 +273,9 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
* .peekIdx((e,i) -> System.out.println("Mapped value: " + e + " Mapped idx:" + i))
* .collect(Collectors.toList());
* }</pre>
*
* @param action 指定的函数
* @return 返回叠加操作后的FastStream
*/
default S peekIdx(final BiConsumer<? super T, Integer> action) {
Objects.requireNonNull(action);

View File

@ -188,21 +188,19 @@ public interface WrappedStream<T, S extends WrappedStream<T, S>> extends Stream<
}
/**
* 返回与指定函数将元素作为参数执行后组成的流
* 这是一个无状态中间操作
*
* @param action 指定的函数
* @return 返回叠加操作后的FastStream
* @apiNote 该方法存在的意义主要是用来调试
* 当你需要查看经过操作管道某处的元素可以执行以下操作:
* 返回与指定函数将元素作为参数执行后组成的流这是一个无状态中间操作<br>
* 该方法存在的意义主要是用来调试当你需要查看经过操作管道某处的元素可以执行以下操作:
* <pre>{@code
* .of("one", "two", "three", "four")
* .filter(e -> e.length() > 3)
* .peek(e -> System.out.println("Filtered value: " + e))
* .peek(e -> Console.log("Filtered value: " + e))
* .map(String::toUpperCase)
* .peek(e -> System.out.println("Mapped value: " + e))
* .peek(e -> Console.log("Mapped value: " + e))
* .collect(Collectors.toList());
* }</pre>
*
* @param action 指定的函数
* @return 返回叠加操作后的FastStream
*/
@Override
default S peek(final Consumer<? super T> action) {

View File

@ -21,12 +21,21 @@ import java.util.function.Predicate;
* dropWhile Spliterator
* <p>借鉴自StreamEx</p>
*
* @param <T> 元素类型
* @author emptypoint
* @since 6.0.0
*/
public class DropWhileSpliterator<T> implements Spliterator<T> {
public static <T> DropWhileSpliterator<T> create(final Spliterator<T> source, final Predicate<? super T> predicate) {
/**
* 创建
*
* @param source {@link Spliterator}
* @param predicate 断言
* @param <T> 元素类型
* @return DropWhileSpliterator
*/
public static <T> DropWhileSpliterator<T> of(final Spliterator<T> source, final Predicate<? super T> predicate) {
return new DropWhileSpliterator<>(source, predicate);
}
@ -34,7 +43,13 @@ public class DropWhileSpliterator<T> implements Spliterator<T> {
private final Predicate<? super T> predicate;
private boolean isFound = false;
private DropWhileSpliterator(final Spliterator<T> source, final Predicate<? super T> predicate) {
/**
* 构造
*
* @param source {@link Spliterator}
* @param predicate 断言
*/
public DropWhileSpliterator(final Spliterator<T> source, final Predicate<? super T> predicate) {
this.source = source;
this.predicate = predicate;
}

View File

@ -22,10 +22,23 @@ import java.util.function.UnaryOperator;
/**
* 无限有序流 的Spliterator
*
* @param <T> 流元素类型
* @author VampireAchao
* @since 6.0.0
*/
public class IterateSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
/**
* @param seed 初始值
* @param hasNext 是否有下一个断言
* @param next 下一个值生产者
* @param <T> 流元素类型
* @return IterateSpliterator
*/
public static <T> IterateSpliterator<T> of(final T seed, final Predicate<? super T> hasNext, final UnaryOperator<T> next) {
return new IterateSpliterator<>(seed, hasNext, next);
}
private final T seed;
private final Predicate<? super T> hasNext;
private final UnaryOperator<T> next;
@ -34,20 +47,19 @@ public class IterateSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
private boolean finished;
/**
* Creates a spliterator reporting the given estimated size and
* additionalCharacteristics.
* 构造
*
* @param seed 初始值
* @param hasNext 是否有下一个断言
* @param next 下一个值生产者
*/
IterateSpliterator(final T seed, final Predicate<? super T> hasNext, final UnaryOperator<T> next) {
public IterateSpliterator(final T seed, final Predicate<? super T> hasNext, final UnaryOperator<T> next) {
super(Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.IMMUTABLE);
this.seed = seed;
this.hasNext = hasNext;
this.next = next;
}
public static <T> IterateSpliterator<T> create(final T seed, final Predicate<? super T> hasNext, final UnaryOperator<T> next) {
return new IterateSpliterator<>(seed, hasNext, next);
}
@Override
public boolean tryAdvance(final Consumer<? super T> action) {
Objects.requireNonNull(action);

View File

@ -437,7 +437,7 @@ public class AntPathMatcher {
*/
protected String[] tokenizePath(final String path) {
return SplitUtil.split(path, this.pathSeparator, this.trimTokens, true)
.toArray(new String[0]);
.toArray(new String[0]);
}
/**
@ -530,7 +530,7 @@ public class AntPathMatcher {
* 提取参数
*
* @param pattern 模式
* @param path 路径
* @param path 路径
* @return 参数
*/
public Map<String, String> extractUriTemplateVariables(final String pattern, final String path) {
@ -548,22 +548,22 @@ public class AntPathMatcher {
* the first pattern contains a file extension match (e.g., {@code *.html}).
* In that case, the second pattern will be merged into the first. Otherwise,
* an {@code IllegalArgumentException} will be thrown.
* <p>Examples</p>
* <table border="1" summary="">
* <tr><th>Pattern 1</th><th>Pattern 2</th><th>Result</th></tr>
* <tr><td>{@code null}</td><td>{@code null}</td><td>&nbsp;</td></tr>
* <tr><td>/hotels</td><td>{@code null}</td><td>/hotels</td></tr>
* <tr><td>{@code null}</td><td>/hotels</td><td>/hotels</td></tr>
* <tr><td>/hotels</td><td>/bookings</td><td>/hotels/bookings</td></tr>
* <tr><td>/hotels</td><td>bookings</td><td>/hotels/bookings</td></tr>
* <tr><td>/hotels/*</td><td>/bookings</td><td>/hotels/bookings</td></tr>
* <tr><td>/hotels/&#42;&#42;</td><td>/bookings</td><td>/hotels/&#42;&#42;/bookings</td></tr>
* <tr><td>/hotels</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr>
* <tr><td>/hotels/*</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr>
* <tr><td>/hotels/&#42;&#42;</td><td>{hotel}</td><td>/hotels/&#42;&#42;/{hotel}</td></tr>
* <tr><td>/*.html</td><td>/hotels.html</td><td>/hotels.html</td></tr>
* <tr><td>/*.html</td><td>/hotels</td><td>/hotels.html</td></tr>
* <tr><td>/*.html</td><td>/*.txt</td><td>{@code IllegalArgumentException}</td></tr>
* <table border="1">
* <caption>Examples</caption>
* <tr><th>Pattern 1</th><th>Pattern 2</th><th>Result</th></tr>
* <tr><td>{@code null}</td><td>{@code null}</td><td>&nbsp;</td></tr>
* <tr><td>/hotels</td><td>{@code null}</td><td>/hotels</td></tr>
* <tr><td>{@code null}</td><td>/hotels</td><td>/hotels</td></tr>
* <tr><td>/hotels</td><td>/bookings</td><td>/hotels/bookings</td></tr>
* <tr><td>/hotels</td><td>bookings</td><td>/hotels/bookings</td></tr>
* <tr><td>/hotels/*</td><td>/bookings</td><td>/hotels/bookings</td></tr>
* <tr><td>/hotels/&#42;&#42;</td><td>/bookings</td><td>/hotels/&#42;&#42;/bookings</td></tr>
* <tr><td>/hotels</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr>
* <tr><td>/hotels/*</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr>
* <tr><td>/hotels/&#42;&#42;</td><td>{hotel}</td><td>/hotels/&#42;&#42;/{hotel}</td></tr>
* <tr><td>/*.html</td><td>/hotels.html</td><td>/hotels.html</td></tr>
* <tr><td>/*.html</td><td>/hotels</td><td>/hotels.html</td></tr>
* <tr><td>/*.html</td><td>/*.txt</td><td>{@code IllegalArgumentException}</td></tr>
* </table>
*
* @param pattern1 the first pattern
@ -677,6 +677,12 @@ public class AntPathMatcher {
private final List<String> variableNames = new ArrayList<>();
/**
* Create a new {@code AntPathStringMatcher} that will match the supplied {@code pattern}
*
* @param pattern the pattern to match against
* @param caseSensitive 是否大小写不敏感
*/
public AntPathStringMatcher(final String pattern, final boolean caseSensitive) {
this.rawPattern = pattern;
this.caseSensitive = caseSensitive;
@ -714,7 +720,7 @@ public class AntPathMatcher {
this.exactMatch = false;
patternBuilder.append(quote(pattern, end, pattern.length()));
this.pattern = (this.caseSensitive ? Pattern.compile(patternBuilder.toString()) :
Pattern.compile(patternBuilder.toString(), Pattern.CASE_INSENSITIVE));
Pattern.compile(patternBuilder.toString(), Pattern.CASE_INSENSITIVE));
}
}
@ -741,15 +747,15 @@ public class AntPathMatcher {
if (uriTemplateVariables != null) {
if (this.variableNames.size() != matcher.groupCount()) {
throw new IllegalArgumentException("The number of capturing groups in the pattern segment " +
this.pattern + " does not match the number of URI template variables it defines, " +
"which can occur if capturing groups are used in a URI template regex. " +
"Use non-capturing groups instead.");
this.pattern + " does not match the number of URI template variables it defines, " +
"which can occur if capturing groups are used in a URI template regex. " +
"Use non-capturing groups instead.");
}
for (int i = 1; i <= matcher.groupCount(); i++) {
final String name = this.variableNames.get(i - 1);
if (name.startsWith("*")) {
throw new IllegalArgumentException("Capturing patterns (" + name + ") are not " +
"supported by the AntPathMatcher. Use the PathPatternParser instead.");
"supported by the AntPathMatcher. Use the PathPatternParser instead.");
}
final String value = matcher.group(i);
uriTemplateVariables.put(name, value);
@ -769,18 +775,23 @@ public class AntPathMatcher {
* {@link #getPatternComparator(String)}.
* <p>In order, the most "generic" pattern is determined by the following:
* <ul>
* <li>if it's null or a capture all pattern (i.e. it is equal to "/**")</li>
* <li>if the other pattern is an actual match</li>
* <li>if it's a catch-all pattern (i.e. it ends with "**"</li>
* <li>if it's got more "*" than the other pattern</li>
* <li>if it's got more "{foo}" than the other pattern</li>
* <li>if it's shorter than the other pattern</li>
* <li>if it's null or a capture all pattern (i.e. it is equal to "/**")</li>
* <li>if the other pattern is an actual match</li>
* <li>if it's a catch-all pattern (i.e. it ends with "**"</li>
* <li>if it's got more "*" than the other pattern</li>
* <li>if it's got more "{foo}" than the other pattern</li>
* <li>if it's shorter than the other pattern</li>
* </ul>
*/
protected static class AntPatternComparator implements Comparator<String> {
private final String path;
/**
* 构造
*
* @param path 路径
*/
public AntPatternComparator(final String path) {
this.path = path;
}
@ -931,7 +942,7 @@ public class AntPathMatcher {
public int getLength() {
if (this.length == null) {
this.length = (this.pattern != null ?
VARIABLE_PATTERN.matcher(this.pattern).replaceAll("#").length() : 0);
VARIABLE_PATTERN.matcher(this.pattern).replaceAll("#").length() : 0);
}
return this.length;
}

View File

@ -23,6 +23,9 @@ public abstract class AbstractFilter implements BloomFilter {
private static final long serialVersionUID = 1L;
private final BitSet bitSet;
/**
* 容量
*/
protected int size;

View File

@ -24,6 +24,9 @@ import org.dromara.hutool.core.text.replacer.LookupReplacer;
public class Html4Escape extends XmlEscape {
private static final long serialVersionUID = 1L;
/**
* ISO8859_1 转义字符
*/
@SuppressWarnings("UnnecessaryUnicodeEscape")
protected static final String[][] ISO8859_1_ESCAPE = { //
{ "\u00A0", "&nbsp;" }, // non-breaking space
@ -124,6 +127,9 @@ public class Html4Escape extends XmlEscape {
{ "\u00FF", "&yuml;" }, // <EFBFBD> - lowercase y, umlaut
};
/**
* HTML 4.01 extended entities.
*/
@SuppressWarnings("UnnecessaryUnicodeEscape")
protected static final String[][] HTML40_EXTENDED_ESCAPE = {
// <!-- Latin Extended-B -->

View File

@ -18,14 +18,22 @@ import org.dromara.hutool.core.text.replacer.LookupReplacer;
* HTML4的UNESCAPE
*
* @author looly
*
*/
public class Html4Unescape extends XmlUnescape {
private static final long serialVersionUID = 1L;
protected static final String[][] ISO8859_1_UNESCAPE = InternalEscapeUtil.invert(Html4Escape.ISO8859_1_ESCAPE);
protected static final String[][] HTML40_EXTENDED_UNESCAPE = InternalEscapeUtil.invert(Html4Escape.HTML40_EXTENDED_ESCAPE);
/**
* ISO8859_1的UNESCAPE
*/
protected static final String[][] ISO8859_1_UNESCAPE = InternalEscapeUtil.invert(Html4Escape.ISO8859_1_ESCAPE);
/**
* HTML40_EXTENDED的UNESCAPE
*/
protected static final String[][] HTML40_EXTENDED_UNESCAPE = InternalEscapeUtil.invert(Html4Escape.HTML40_EXTENDED_ESCAPE);
/**
* 构造
*/
public Html4Unescape() {
super();
addChain(new LookupReplacer(ISO8859_1_UNESCAPE));

View File

@ -34,6 +34,9 @@ import org.dromara.hutool.core.text.replacer.ReplacerChain;
public class XmlEscape extends ReplacerChain {
private static final long serialVersionUID = 1L;
/**
* XML转义字符
*/
protected static final String[][] BASIC_ESCAPE = { //
// {"'", "&apos;"}, // " - single-quote
{"\"", "&quot;"}, // " - double-quote

View File

@ -24,8 +24,13 @@ import org.dromara.hutool.core.text.replacer.ReplacerChain;
public class XmlUnescape extends ReplacerChain {
private static final long serialVersionUID = 1L;
/**
* 基础反转义符
*/
protected static final String[][] BASIC_UNESCAPE = InternalEscapeUtil.invert(XmlEscape.BASIC_ESCAPE);
// issue#1118
/**
* issue#1118新增&apos;反转义
*/
protected static final String[][] OTHER_UNESCAPE = new String[][]{new String[]{"&apos;", "'"}};
/**

View File

@ -25,8 +25,17 @@ import java.io.Serializable;
public abstract class TextFinder implements Finder, Serializable {
private static final long serialVersionUID = 1L;
/**
* 文本
*/
protected CharSequence text;
/**
* 结束位置
*/
protected int endIndex = -1;
/**
* 是否反向查找
*/
protected boolean negative;
/**

View File

@ -151,6 +151,15 @@ public abstract class StrTemplate {
protected int fixedTextTotalLength;
// endregion
/**
* 构造
*
* @param template 字符串模板
* @param escape 转义符
* @param defaultValue 默认值
* @param defaultValueHandler 默认值处理器
* @param features 策略值
*/
protected StrTemplate(final String template, final char escape, final String defaultValue,
final UnaryOperator<String> defaultValueHandler, final int features) {
Assert.notNull(template, "String template cannot be null");
@ -718,6 +727,11 @@ public abstract class StrTemplate {
*/
protected int features;
/**
* 构造
*
* @param template 字符串模板
*/
protected AbstractBuilder(final String template) {
this.template = Objects.requireNonNull(template);
// 策略值 初始为 全局默认策略

View File

@ -21,11 +21,15 @@ package org.dromara.hutool.core.text.placeholder.segment;
*/
public abstract class AbstractPlaceholderSegment implements StrTemplateSegment {
/**
* 占位符变量
* <p>例如{@literal "???"->"???", "{}"->"{}", "{name}"->"name"}</p>
* 占位符变量例如{@literal "???"->"???", "{}"->"{}", "{name}"->"name"}
*/
private final String placeholder;
/**
* 构造
*
* @param placeholder 占位符变量例如{@literal "???"->"???", "{}"->"{}", "{name}"->"name"}
*/
protected AbstractPlaceholderSegment(final String placeholder) {
this.placeholder = placeholder;
}

View File

@ -20,17 +20,23 @@ package org.dromara.hutool.core.text.placeholder.segment;
* @since 6.0.0
*/
public class IndexedPlaceholderSegment extends NamedPlaceholderSegment {
/**
* 下标值
*/
private final int index;
/**
* 下标值
*/
private final int index;
public IndexedPlaceholderSegment(final String idxStr, final String wholePlaceholder) {
super(idxStr, wholePlaceholder);
this.index = Integer.parseInt(idxStr);
}
/**
* 构造
*
* @param idxStr 索引字符串变量
* @param wholePlaceholder 占位符完整文本
*/
public IndexedPlaceholderSegment(final String idxStr, final String wholePlaceholder) {
super(idxStr, wholePlaceholder);
this.index = Integer.parseInt(idxStr);
}
public int getIndex() {
return index;
}
public int getIndex() {
return index;
}
}

View File

@ -19,18 +19,23 @@ package org.dromara.hutool.core.text.placeholder.segment;
* @since 6.0.0
*/
public class LiteralSegment implements StrTemplateSegment {
/**
* 模板中固定的一段文本
*/
private final String text;
/**
* 模板中固定的一段文本
*/
private final String text;
public LiteralSegment(final String text) {
this.text = text;
}
/**
* 构造
*
* @param text 文本
*/
public LiteralSegment(final String text) {
this.text = text;
}
@Override
public String getText() {
return text;
}
@Override
public String getText() {
return text;
}
}

View File

@ -20,20 +20,25 @@ package org.dromara.hutool.core.text.placeholder.segment;
* @since 6.0.0
*/
public class NamedPlaceholderSegment extends AbstractPlaceholderSegment {
/**
* 占位符完整文本
* <p>例如{@literal "{name}"->"{name}"}</p>
*/
private final String wholePlaceholder;
/**
* 占位符完整文本
* <p>例如{@literal "{name}"->"{name}"}</p>
*/
private final String wholePlaceholder;
public NamedPlaceholderSegment(final String name, final String wholePlaceholder) {
super(name);
this.wholePlaceholder = wholePlaceholder;
}
/**
* 构造
* @param name 占位符变量
* @param wholePlaceholder 占位符完整文本
*/
public NamedPlaceholderSegment(final String name, final String wholePlaceholder) {
super(name);
this.wholePlaceholder = wholePlaceholder;
}
@Override
public String getText() {
return wholePlaceholder;
}
@Override
public String getText() {
return wholePlaceholder;
}
}

View File

@ -21,11 +21,17 @@ package org.dromara.hutool.core.text.placeholder.segment;
*/
public class SinglePlaceholderSegment extends AbstractPlaceholderSegment {
private SinglePlaceholderSegment(final String placeholder) {
super(placeholder);
}
private SinglePlaceholderSegment(final String placeholder) {
super(placeholder);
}
public static SinglePlaceholderSegment newInstance(final String placeholder) {
return new SinglePlaceholderSegment(placeholder);
}
/**
* 创建SinglePlaceholderSegment
*
* @param placeholder 占位符
* @return SinglePlaceholderSegment
*/
public static SinglePlaceholderSegment of(final String placeholder) {
return new SinglePlaceholderSegment(placeholder);
}
}

View File

@ -19,11 +19,10 @@ package org.dromara.hutool.core.text.placeholder.segment;
* @since 6.0.0
*/
public interface StrTemplateSegment {
/**
* 获取文本值
*
* @return 文本值对于固定文本Segment返回文本值对于单占位符Segment返回占位符对于有前后缀的占位符Segment返回占位符完整文本例如: "{name}"
*/
String getText();
/**
* 获取文本值
*
* @return 文本值对于固定文本Segment返回文本值对于单占位符Segment返回占位符对于有前后缀的占位符Segment返回占位符完整文本例如: "{name}"
*/
String getText();
}

View File

@ -582,6 +582,10 @@ public class NamedPlaceholderStrTemplate extends StrTemplate {
*/
protected String suffix;
/**
* 构造
* @param template 模板
*/
protected Builder(final String template) {
super(template);
}

View File

@ -66,7 +66,7 @@ public class SinglePlaceholderStrTemplate extends StrTemplate {
// 上一个解析的segment是否是固定文本如果是则需要和当前新的文本部分合并
boolean lastIsLiteralSegment = false;
// 复用的占位符变量
final SinglePlaceholderSegment singlePlaceholderSegment = SinglePlaceholderSegment.newInstance(placeholder);
final SinglePlaceholderSegment singlePlaceholderSegment = SinglePlaceholderSegment.of(placeholder);
List<StrTemplateSegment> segments = null;
while (true) {
delimIndex = template.indexOf(placeholder, handledPosition);
@ -200,6 +200,11 @@ public class SinglePlaceholderStrTemplate extends StrTemplate {
*/
protected String placeholder;
/**
* 构造
*
* @param template 字符串模板
*/
protected Builder(final String template) {
super(template);
}

View File

@ -12,39 +12,75 @@
package org.dromara.hutool.core.thread;
import org.dromara.hutool.core.exception.ExceptionUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.exception.HutoolException;
/**
* 工具类异常
* 线程异常
*
* @author looly
* @since 5.7.17
*/
public class ThreadException extends RuntimeException {
public class ThreadException extends HutoolException {
private static final long serialVersionUID = 5253124428623713216L;
/**
* 构造
*
* @param e 异常
*/
public ThreadException(final Throwable e) {
super(ExceptionUtil.getMessage(e), e);
super(e);
}
/**
* 构造
*
* @param message 消息
*/
public ThreadException(final String message) {
super(message);
}
/**
* 构造
*
* @param messageTemplate 消息模板
* @param params 参数
*/
public ThreadException(final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params));
super(messageTemplate, params);
}
public ThreadException(final String message, final Throwable throwable) {
super(message, throwable);
/**
* 构造
*
* @param message 消息
* @param cause 被包装的子异常
*/
public ThreadException(final String message, final Throwable cause) {
super(message, cause);
}
public ThreadException(final String message, final Throwable throwable, final boolean enableSuppression, final boolean writableStackTrace) {
super(message, throwable, enableSuppression, writableStackTrace);
/**
* 构造
*
* @param message 消息
* @param cause 被包装的子异常
* @param enableSuppression 是否启用抑制
* @param writableStackTrace 堆栈跟踪是否应该是可写的
*/
public ThreadException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public ThreadException(final Throwable throwable, final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
/**
* 构造
*
* @param cause 被包装的子异常
* @param messageTemplate 消息模板
* @param params 参数
*/
public ThreadException(final Throwable cause, final String messageTemplate, final Object... params) {
super(cause, messageTemplate, params);
}
}

View File

@ -24,6 +24,9 @@ import java.util.concurrent.locks.Lock;
*/
public class NoLock implements Lock{
/**
* 单例
*/
public static NoLock INSTANCE = new NoLock();
@Override

77
pom.xml
View File

@ -57,12 +57,12 @@
</properties>
<dependencies>
<!-- Kotlin适配用于在测试和编译中使用kotlin代码 -->
<!-- Kotlin适配用于在测试中使用kotlin代码 -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin-version}</version>
<scope>provided</scope>
<scope>test</scope>
</dependency>
<!-- 全局单元测试 -->
<dependency>
@ -100,6 +100,10 @@
<name>VampireAchao</name>
<email>VampireAchao@dromara.org</email>
</developer>
<developer>
<name>CherryRum</name>
<email>yulin.1996@foxmail.com</email>
</developer>
<developer>
<name>Emptypoint</name>
<email>1215582715@qq.com</email>
@ -116,10 +120,6 @@
<name>Dazer007</name>
<email>dazer007@163.com</email>
</developer>
<developer>
<name>CherryRum</name>
<email>yulin.1996@foxmail.com</email>
</developer>
<developer>
<name>Aihuahua</name>
<email>aihuahua522@qq.com</email>
@ -169,8 +169,10 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<fork>true</fork>
<source>${compile.version}</source>
<target>${compile.version}</target>
<!-- 编译时启用警告位置 -->
<compilerArgument>-Xlint:unchecked</compilerArgument>
</configuration>
</plugin>
@ -214,46 +216,6 @@
</goals>
</execution>
</executions>
<configuration>
<tags>
<tag>
<name>apiNote</name>
<placement>a</placement>
<head>API Note:</head>
</tag>
<tag>
<name>implSpec</name>
<placement>a</placement>
<head>Implementation Requirements:</head>
</tag>
<tag>
<name>implNote</name>
<placement>a</placement>
<head>Implementation Note:</head>
</tag>
<tag>
<name>param</name>
</tag>
<tag>
<name>return</name>
</tag>
<tag>
<name>throws</name>
</tag>
<tag>
<name>since</name>
</tag>
<tag>
<name>version</name>
</tag>
<tag>
<name>serialData</name>
</tag>
<tag>
<name>see</name>
</tag>
</tags>
</configuration>
</plugin>
<!-- 统一更新pom版本 -->
<plugin>
@ -277,6 +239,29 @@
<check/>
</configuration>
</plugin>
<!-- 用于生成模块化系统中的module-info.classhttps://github.com/moditect/moditect -->
<plugin>
<groupId>org.moditect</groupId>
<artifactId>moditect-maven-plugin</artifactId>
<version>1.2.2.Final</version>
<executions>
<execution>
<id>add-module-infos</id>
<phase>package</phase>
<goals>
<goal>add-module-info</goal>
</goals>
<configuration>
<jvmVersion>9</jvmVersion>
<module>
<moduleInfo>
<name>${Automatic-Module-Name}</name>
</moduleInfo>
</module>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>