mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix code
This commit is contained in:
parent
73fd3b849f
commit
bc486cdac4
@ -22,6 +22,8 @@
|
||||
* 【all 】 cn.hutool.extra.servlet.multipart包迁移到cn.hutool.core.net下
|
||||
* 【core 】 XmlUtil.mapToXml方法支持集合解析(issue#820@Github)
|
||||
* 【json 】 解析Object中对是否为bean单独判断,而不是直接解析
|
||||
* 【core 】 SimHash锁改为StampedLock
|
||||
* 【core 】 Singleton改为SimpleCache实现
|
||||
|
||||
### Bug修复
|
||||
* 【extra 】 修复SpringUtil使用devtools重启报错问题
|
||||
|
@ -13,7 +13,7 @@ import java.lang.reflect.Method;
|
||||
public class TimeIntervalAspect extends SimpleAspect {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private TimeInterval interval = new TimeInterval();
|
||||
private final TimeInterval interval = new TimeInterval();
|
||||
|
||||
@Override
|
||||
public boolean before(Object target, Method method, Object[] args) {
|
||||
|
@ -18,8 +18,8 @@ import java.lang.reflect.Method;
|
||||
public class JdkInterceptor implements InvocationHandler, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Object target;
|
||||
private Aspect aspect;
|
||||
private final Object target;
|
||||
private final Aspect aspect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -55,7 +55,7 @@ public class BitMapBloomFilter implements BloomFilter{
|
||||
*/
|
||||
@Override
|
||||
public boolean add(String str) {
|
||||
boolean flag = true;
|
||||
boolean flag = false;
|
||||
for (BloomFilter filter : filters) {
|
||||
flag |= filter.add(str);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import java.io.Serializable;
|
||||
public class IntMap implements BitMap, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int[] ints;
|
||||
private final int[] ints;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -11,7 +11,7 @@ import java.io.Serializable;
|
||||
public class LongMap implements BitMap, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private long[] longs;
|
||||
private final long[] longs;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -24,7 +24,7 @@ public enum GlobalPruneTimer {
|
||||
/**
|
||||
* 缓存任务计数
|
||||
*/
|
||||
private AtomicInteger cacheTaskNumber = new AtomicInteger(1);
|
||||
private final AtomicInteger cacheTaskNumber = new AtomicInteger(1);
|
||||
|
||||
/**
|
||||
* 定时器
|
||||
|
@ -1,10 +1,10 @@
|
||||
package cn.hutool.cache.impl;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import cn.hutool.cache.Cache;
|
||||
import cn.hutool.core.lang.func.Func0;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 无缓存实现,用于快速关闭缓存
|
||||
*
|
||||
@ -61,7 +61,17 @@ public class NoCache<K, V> implements Cache<K, V> {
|
||||
|
||||
@Override
|
||||
public Iterator<V> iterator() {
|
||||
return null;
|
||||
return new Iterator<V>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V next() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,16 +1,16 @@
|
||||
package cn.hutool.captcha;
|
||||
|
||||
import cn.hutool.core.img.GraphicsUtil;
|
||||
import cn.hutool.core.img.ImgUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import cn.hutool.core.img.GraphicsUtil;
|
||||
import cn.hutool.core.img.ImgUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
|
||||
/**
|
||||
* 扭曲干扰验证码
|
||||
*
|
||||
@ -110,18 +110,15 @@ public class ShearCaptcha extends AbstractCaptcha {
|
||||
|
||||
int period = RandomUtil.randomInt(this.width);
|
||||
|
||||
boolean borderGap = true;
|
||||
int frames = 1;
|
||||
int phase = RandomUtil.randomInt(2);
|
||||
|
||||
for (int i = 0; i < h1; i++) {
|
||||
double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
|
||||
g.copyArea(0, i, w1, 1, (int) d, 0);
|
||||
if (borderGap) {
|
||||
g.setColor(color);
|
||||
g.drawLine((int) d, i, 0, i);
|
||||
g.drawLine((int) d + w1, i, w1, i);
|
||||
}
|
||||
g.setColor(color);
|
||||
g.drawLine((int) d, i, 0, i);
|
||||
g.drawLine((int) d + w1, i, w1, i);
|
||||
}
|
||||
|
||||
}
|
||||
@ -162,6 +159,7 @@ public class ShearCaptcha extends AbstractCaptcha {
|
||||
* @param thickness 粗细
|
||||
* @param c 颜色
|
||||
*/
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private void drawInterfere(Graphics g, int x1, int y1, int x2, int y2, int thickness, Color c) {
|
||||
|
||||
// The thick line is in fact a filled polygon
|
||||
|
@ -16,7 +16,7 @@ public class MathGenerator implements CodeGenerator {
|
||||
private static final String operators = "+-*";
|
||||
|
||||
/** 参与计算数字最大长度 */
|
||||
private int numberLength;
|
||||
private final int numberLength;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,13 +1,5 @@
|
||||
package cn.hutool.core.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
@ -16,6 +8,14 @@ import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Bean路径表达式,用于获取多层嵌套Bean中的字段值或Bean对象<br>
|
||||
* 根据给定的表达式,查找Bean中对应的属性值对象。 表达式分为两种:
|
||||
@ -242,10 +242,6 @@ public class BeanPath implements Serializable{
|
||||
}
|
||||
isNumStart = false;
|
||||
// 中括号结束加入下标
|
||||
if (builder.length() > 0) {
|
||||
localPatternParts.add(unWrapIfPossible(builder));
|
||||
}
|
||||
builder.reset();
|
||||
} else {
|
||||
if (isNumStart) {
|
||||
// 非结束中括号情况下发现起始中括号报错(中括号未关闭)
|
||||
@ -255,11 +251,11 @@ public class BeanPath implements Serializable{
|
||||
isNumStart = true;
|
||||
}
|
||||
// 每一个边界符之前的表达式是一个完整的KEY,开始处理KEY
|
||||
if (builder.length() > 0) {
|
||||
localPatternParts.add(unWrapIfPossible(builder));
|
||||
}
|
||||
builder.reset();
|
||||
}
|
||||
if (builder.length() > 0) {
|
||||
localPatternParts.add(unWrapIfPossible(builder));
|
||||
}
|
||||
builder.reset();
|
||||
} else {
|
||||
// 非边界符号,追加字符
|
||||
builder.append(c);
|
||||
|
@ -694,7 +694,7 @@ public class BeanUtil {
|
||||
*/
|
||||
public static <T> T trimStrFields(T bean, String... ignoreFields) {
|
||||
if (bean == null) {
|
||||
return bean;
|
||||
return null;
|
||||
}
|
||||
|
||||
final Field[] fields = ReflectUtil.getFields(bean.getClass());
|
||||
|
@ -1,14 +1,14 @@
|
||||
package cn.hutool.core.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.hutool.core.clone.CloneSupport;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 动态Bean,通过反射对Bean的相关方法做操作<br>
|
||||
* 支持Map和普通Bean
|
||||
@ -19,8 +19,8 @@ import cn.hutool.core.util.ReflectUtil;
|
||||
public class DynaBean extends CloneSupport<DynaBean> implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Class<?> beanClass;
|
||||
private Object bean;
|
||||
private final Class<?> beanClass;
|
||||
private final Object bean;
|
||||
|
||||
/**
|
||||
* 创建一个{@link DynaBean}
|
||||
|
@ -16,7 +16,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class MapValueProvider implements ValueProvider<String> {
|
||||
|
||||
private Map<?, ?> map;
|
||||
private final Map<?, ?> map;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,13 +1,13 @@
|
||||
package cn.hutool.core.builder;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
|
||||
/**
|
||||
* 用于构建 {@link java.lang.Comparable#compareTo(Object)} 方法的辅助工具
|
||||
*
|
||||
@ -418,7 +418,7 @@ public class CompareToBuilder implements Builder<Integer> {
|
||||
if (comparison != 0) {
|
||||
return this;
|
||||
}
|
||||
comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
|
||||
comparison = (Long.compare(lhs, rhs));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -434,7 +434,7 @@ public class CompareToBuilder implements Builder<Integer> {
|
||||
if (comparison != 0) {
|
||||
return this;
|
||||
}
|
||||
comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
|
||||
comparison = (Integer.compare(lhs, rhs));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -450,7 +450,7 @@ public class CompareToBuilder implements Builder<Integer> {
|
||||
if (comparison != 0) {
|
||||
return this;
|
||||
}
|
||||
comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
|
||||
comparison = (Short.compare(lhs, rhs));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -466,7 +466,7 @@ public class CompareToBuilder implements Builder<Integer> {
|
||||
if (comparison != 0) {
|
||||
return this;
|
||||
}
|
||||
comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
|
||||
comparison = (Character.compare(lhs, rhs));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -482,7 +482,7 @@ public class CompareToBuilder implements Builder<Integer> {
|
||||
if (comparison != 0) {
|
||||
return this;
|
||||
}
|
||||
comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
|
||||
comparison = (Byte.compare(lhs, rhs));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package cn.hutool.core.builder;
|
||||
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -7,9 +10,6 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
|
||||
/**
|
||||
* <p>{@link Object#equals(Object)} 方法的构建器</p>
|
||||
*
|
||||
@ -51,7 +51,7 @@ public class EqualsBuilder implements Builder<Boolean> {
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
private static final ThreadLocal<Set<Pair<IDKey, IDKey>>> REGISTRY = new ThreadLocal<Set<Pair<IDKey, IDKey>>>();
|
||||
private static final ThreadLocal<Set<Pair<IDKey, IDKey>>> REGISTRY = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -79,7 +79,7 @@ public class EqualsBuilder implements Builder<Boolean> {
|
||||
static Pair<IDKey, IDKey> getRegisterPair(final Object lhs, final Object rhs) {
|
||||
final IDKey left = new IDKey(lhs);
|
||||
final IDKey right = new IDKey(rhs);
|
||||
return new Pair<IDKey, IDKey>(left, right);
|
||||
return new Pair<>(left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +98,7 @@ public class EqualsBuilder implements Builder<Boolean> {
|
||||
static boolean isRegistered(final Object lhs, final Object rhs) {
|
||||
final Set<Pair<IDKey, IDKey>> registry = getRegistry();
|
||||
final Pair<IDKey, IDKey> pair = getRegisterPair(lhs, rhs);
|
||||
final Pair<IDKey, IDKey> swappedPair = new Pair<IDKey, IDKey>(pair.getKey(), pair.getValue());
|
||||
final Pair<IDKey, IDKey> swappedPair = new Pair<>(pair.getKey(), pair.getValue());
|
||||
|
||||
return registry != null
|
||||
&& (registry.contains(pair) || registry.contains(swappedPair));
|
||||
@ -116,7 +116,7 @@ public class EqualsBuilder implements Builder<Boolean> {
|
||||
static void register(final Object lhs, final Object rhs) {
|
||||
synchronized (EqualsBuilder.class) {
|
||||
if (getRegistry() == null) {
|
||||
REGISTRY.set(new HashSet<Pair<IDKey, IDKey>>());
|
||||
REGISTRY.set(new HashSet<>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -845,7 +845,7 @@ public class EqualsBuilder implements Builder<Boolean> {
|
||||
*/
|
||||
@Override
|
||||
public Boolean build() {
|
||||
return Boolean.valueOf(isEquals());
|
||||
return isEquals();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -854,7 +854,8 @@ public class EqualsBuilder implements Builder<Boolean> {
|
||||
* @param isEquals The value to set.
|
||||
* @since 2.1
|
||||
*/
|
||||
protected void setEquals(final boolean isEquals) {
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
protected void setEquals(boolean isEquals) {
|
||||
this.isEquals = isEquals;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package cn.hutool.core.collection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.PriorityQueue;
|
||||
@ -80,7 +79,7 @@ public class BoundedPriorityQueue<E> extends PriorityQueue<E>{
|
||||
*/
|
||||
public ArrayList<E> toList() {
|
||||
final ArrayList<E> list = new ArrayList<>(this);
|
||||
Collections.sort(list, comparator);
|
||||
list.sort(comparator);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ import java.util.List;
|
||||
public class CopiedIter<E> implements Iterator<E>, Iterable<E>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Iterator<E> listIterator;
|
||||
private final Iterator<E> listIterator;
|
||||
|
||||
public static <V> CopiedIter<V> copyOf(Iterator<V> iterator){
|
||||
return new CopiedIter<>(iterator);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.hutool.core.comparator;
|
||||
|
||||
import cn.hutool.core.lang.Chain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
@ -8,8 +10,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import cn.hutool.core.lang.Chain;
|
||||
|
||||
/**
|
||||
* 比较器链。此链包装了多个比较器,最终比较结果按照比较器顺序综合多个比较器结果。<br>
|
||||
* 按照比较器链的顺序分别比较,如果比较出相等则转向下一个比较器,否则直接返回<br>
|
||||
@ -24,7 +24,7 @@ public class ComparatorChain<E> implements Chain<Comparator<E>, ComparatorChain<
|
||||
/** 比较器链. */
|
||||
private final List<Comparator<E>> chain;
|
||||
/** 对应比较器位置是否反序. */
|
||||
private BitSet orderingBits;
|
||||
private final BitSet orderingBits;
|
||||
/** 比较器是否被锁定。锁定的比较器链不能再添加新的比较器。比较器会在开始比较时开始加锁。 */
|
||||
private boolean lock = false;
|
||||
|
||||
@ -249,8 +249,9 @@ public class ComparatorChain<E> implements Chain<Comparator<E>, ComparatorChain<
|
||||
}
|
||||
if (object.getClass().equals(this.getClass())) {
|
||||
final ComparatorChain<?> otherChain = (ComparatorChain<?>) object;
|
||||
return (Objects.equals(this.orderingBits, otherChain.orderingBits)) //
|
||||
&& (null == otherChain ? null == otherChain.chain : this.chain.equals(otherChain.chain));
|
||||
//
|
||||
return Objects.equals(this.orderingBits, otherChain.orderingBits)
|
||||
&& this.chain.equals(otherChain.chain);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package cn.hutool.core.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* 按照数组的顺序正序排列,数组的元素位置决定了对象的排序先后<br>
|
||||
* 如果参与排序的元素并不在数组中,则排序在前
|
||||
@ -15,7 +15,7 @@ import cn.hutool.core.util.ArrayUtil;
|
||||
*/
|
||||
public class IndexedComparator<T> implements Comparator<T> {
|
||||
|
||||
private T[] array;
|
||||
private final T[] array;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -93,7 +93,7 @@ public class ConverterRegistry implements Serializable{
|
||||
/** 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 */
|
||||
private static class SingletonHolder {
|
||||
/** 静态初始化器,由JVM来保证线程安全 */
|
||||
private static ConverterRegistry instance = new ConverterRegistry();
|
||||
private static final ConverterRegistry INSTANCE = new ConverterRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,7 +102,7 @@ public class ConverterRegistry implements Serializable{
|
||||
* @return {@link ConverterRegistry}
|
||||
*/
|
||||
public static ConverterRegistry getInstance() {
|
||||
return SingletonHolder.instance;
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
public ConverterRegistry() {
|
||||
|
@ -13,11 +13,8 @@ public class BooleanConverter extends AbstractConverter<Boolean>{
|
||||
|
||||
@Override
|
||||
protected Boolean convertInternal(Object value) {
|
||||
if(boolean.class == value.getClass()){
|
||||
return Boolean.valueOf((boolean)value);
|
||||
}
|
||||
String valueStr = convertToStr(value);
|
||||
return Boolean.valueOf(BooleanUtil.toBoolean(valueStr));
|
||||
//Object不可能出现Primitive类型,故忽略
|
||||
return BooleanUtil.toBoolean(convertToStr(value));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,16 +15,12 @@ public class CharacterConverter extends AbstractConverter<Character> {
|
||||
|
||||
@Override
|
||||
protected Character convertInternal(Object value) {
|
||||
if (char.class == value.getClass()) {
|
||||
return Character.valueOf((char) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
if (value instanceof Boolean) {
|
||||
return BooleanUtil.toCharacter((Boolean) value);
|
||||
} else if (boolean.class == value.getClass()) {
|
||||
return BooleanUtil.toCharacter((boolean) value);
|
||||
} else {
|
||||
final String valueStr = convertToStr(value);
|
||||
if (StrUtil.isNotBlank(valueStr)) {
|
||||
return Character.valueOf(valueStr.charAt(0));
|
||||
return valueStr.charAt(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -18,7 +18,7 @@ import java.util.Date;
|
||||
public class DateConverter extends AbstractConverter<java.util.Date> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Class<? extends java.util.Date> targetType;
|
||||
private final Class<? extends java.util.Date> targetType;
|
||||
/** 日期格式化 */
|
||||
private String format;
|
||||
|
||||
|
@ -25,7 +25,7 @@ public class EnumConverter extends AbstractConverter<Object> {
|
||||
|
||||
private static final Map<Class<?>, Map<Class<?>, Method>> VALUE_OF_METHOD_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private Class enumClass;
|
||||
private final Class enumClass;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -14,7 +14,7 @@ import cn.hutool.core.convert.AbstractConverter;
|
||||
public class GenericEnumConverter<E extends Enum<E>> extends AbstractConverter<E> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Class<E> enumClass;
|
||||
private final Class<E> enumClass;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,15 +1,15 @@
|
||||
package cn.hutool.core.convert.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import cn.hutool.core.convert.AbstractConverter;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* 数字转换器<br>
|
||||
* 支持类型为:<br>
|
||||
@ -30,7 +30,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
public class NumberConverter extends AbstractConverter<Number> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Class<? extends Number> targetType;
|
||||
private final Class<? extends Number> targetType;
|
||||
|
||||
public NumberConverter() {
|
||||
this.targetType = Number.class;
|
||||
@ -50,7 +50,7 @@ public class NumberConverter extends AbstractConverter<Number> {
|
||||
final Class<?> targetType = this.targetType;
|
||||
if (Byte.class == targetType) {
|
||||
if (value instanceof Number) {
|
||||
return Byte.valueOf(((Number) value).byteValue());
|
||||
return ((Number) value).byteValue();
|
||||
} else if(value instanceof Boolean) {
|
||||
return BooleanUtil.toByteObj((Boolean)value);
|
||||
}
|
||||
@ -59,7 +59,7 @@ public class NumberConverter extends AbstractConverter<Number> {
|
||||
|
||||
} else if (Short.class == targetType) {
|
||||
if (value instanceof Number) {
|
||||
return Short.valueOf(((Number) value).shortValue());
|
||||
return ((Number) value).shortValue();
|
||||
} else if(value instanceof Boolean) {
|
||||
return BooleanUtil.toShortObj((Boolean)value);
|
||||
}
|
||||
@ -68,12 +68,12 @@ public class NumberConverter extends AbstractConverter<Number> {
|
||||
|
||||
} else if (Integer.class == targetType) {
|
||||
if (value instanceof Number) {
|
||||
return Integer.valueOf(((Number) value).intValue());
|
||||
return ((Number) value).intValue();
|
||||
} else if(value instanceof Boolean) {
|
||||
return BooleanUtil.toInteger((Boolean)value);
|
||||
}
|
||||
final String valueStr = convertToStr(value);
|
||||
return StrUtil.isBlank(valueStr) ? null : Integer.valueOf(NumberUtil.parseInt(valueStr));
|
||||
return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseInt(valueStr);
|
||||
|
||||
} else if (AtomicInteger.class == targetType) {
|
||||
final AtomicInteger intValue = new AtomicInteger();
|
||||
@ -90,12 +90,12 @@ public class NumberConverter extends AbstractConverter<Number> {
|
||||
return intValue;
|
||||
} else if (Long.class == targetType) {
|
||||
if (value instanceof Number) {
|
||||
return Long.valueOf(((Number) value).longValue());
|
||||
return ((Number) value).longValue();
|
||||
} else if(value instanceof Boolean) {
|
||||
return BooleanUtil.toLongObj((Boolean)value);
|
||||
}
|
||||
final String valueStr = convertToStr(value);
|
||||
return StrUtil.isBlank(valueStr) ? null : Long.valueOf(NumberUtil.parseLong(valueStr));
|
||||
return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseLong(valueStr);
|
||||
|
||||
} else if (AtomicLong.class == targetType) {
|
||||
final AtomicLong longValue = new AtomicLong();
|
||||
@ -113,7 +113,7 @@ public class NumberConverter extends AbstractConverter<Number> {
|
||||
|
||||
} else if (Float.class == targetType) {
|
||||
if (value instanceof Number) {
|
||||
return Float.valueOf(((Number) value).floatValue());
|
||||
return ((Number) value).floatValue();
|
||||
} else if(value instanceof Boolean) {
|
||||
return BooleanUtil.toFloatObj((Boolean)value);
|
||||
}
|
||||
@ -122,7 +122,7 @@ public class NumberConverter extends AbstractConverter<Number> {
|
||||
|
||||
} else if (Double.class == targetType) {
|
||||
if (value instanceof Number) {
|
||||
return Double.valueOf(((Number) value).doubleValue());
|
||||
return ((Number) value).doubleValue();
|
||||
} else if(value instanceof Boolean) {
|
||||
return BooleanUtil.toDoubleObj((Boolean)value);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ import java.util.Date;
|
||||
public class PrimitiveConverter extends AbstractConverter<Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Class<?> targetType;
|
||||
private final Class<?> targetType;
|
||||
|
||||
/**
|
||||
* 构造<br>
|
||||
|
@ -1,15 +1,15 @@
|
||||
package cn.hutool.core.convert.impl;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import cn.hutool.core.convert.AbstractConverter;
|
||||
import cn.hutool.core.convert.ConverterRegistry;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.TypeUtil;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* {@link Reference}转换器
|
||||
*
|
||||
@ -20,7 +20,7 @@ import cn.hutool.core.util.TypeUtil;
|
||||
public class ReferenceConverter extends AbstractConverter<Reference> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Class<? extends Reference> targetType;
|
||||
private final Class<? extends Reference> targetType;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -39,7 +39,7 @@ import java.util.Objects;
|
||||
public class TemporalAccessorConverter extends AbstractConverter<TemporalAccessor> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Class<?> targetType;
|
||||
private final Class<?> targetType;
|
||||
/**
|
||||
* 日期格式化
|
||||
*/
|
||||
|
@ -16,9 +16,9 @@ public class DateBetween implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 开始日期 */
|
||||
private Date begin;
|
||||
private final Date begin;
|
||||
/** 结束日期 */
|
||||
private Date end;
|
||||
private final Date end;
|
||||
|
||||
/**
|
||||
* 创建<br>
|
||||
|
@ -103,7 +103,7 @@ public enum DateField {
|
||||
MILLISECOND(Calendar.MILLISECOND);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
private int value;
|
||||
private final int value;
|
||||
|
||||
DateField(int value) {
|
||||
this.value = value;
|
||||
|
@ -19,7 +19,7 @@ public enum DateUnit {
|
||||
/**一周的毫秒数 */
|
||||
WEEK(DAY.getMillis() * 7);
|
||||
|
||||
private long millis;
|
||||
private final long millis;
|
||||
DateUnit(long millis){
|
||||
this.millis = millis;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public enum Month {
|
||||
UNDECIMBER(Calendar.UNDECIMBER);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
private int value;
|
||||
private final int value;
|
||||
|
||||
Month(int value) {
|
||||
this.value = value;
|
||||
|
@ -23,7 +23,7 @@ public enum Quarter {
|
||||
Q4(4);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
private int value;
|
||||
private final int value;
|
||||
|
||||
Quarter(int value) {
|
||||
this.value = value;
|
||||
|
@ -26,7 +26,7 @@ public class SystemClock {
|
||||
* 构造
|
||||
* @param period 时钟更新间隔,单位毫秒
|
||||
*/
|
||||
private SystemClock(long period) {
|
||||
public SystemClock(long period) {
|
||||
this.period = period;
|
||||
this.now = System.currentTimeMillis();
|
||||
scheduleClockUpdating();
|
||||
|
@ -12,7 +12,7 @@ public class TimeInterval implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private long time;
|
||||
private boolean isNano;
|
||||
private final boolean isNano;
|
||||
|
||||
/**
|
||||
* 构造,默认使用毫秒计数
|
||||
|
@ -36,7 +36,7 @@ public enum Week {
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
/** 星期对应{@link Calendar} 中的Week值 */
|
||||
private int value;
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.hutool.core.date.format;
|
||||
|
||||
import cn.hutool.core.date.DateException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.text.DateFormatSymbols;
|
||||
@ -12,8 +14,6 @@ import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import cn.hutool.core.date.DateException;
|
||||
|
||||
/**
|
||||
* {@link java.text.SimpleDateFormat} 的线程安全版本,用于将 {@link Date} 格式化输出<br>
|
||||
* Thanks to Apache Commons Lang 3.5
|
||||
@ -48,7 +48,7 @@ class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
|
||||
*/
|
||||
private void init() {
|
||||
final List<Rule> rulesList = parsePattern();
|
||||
rules = rulesList.toArray(new Rule[rulesList.size()]);
|
||||
rules = rulesList.toArray(new Rule[0]);
|
||||
|
||||
int len = 0;
|
||||
for (int i = rules.length; --i >= 0;) {
|
||||
|
@ -47,7 +47,7 @@ import java.nio.file.Path;
|
||||
public class Img implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private BufferedImage srcImage;
|
||||
private final BufferedImage srcImage;
|
||||
private Image targetImage;
|
||||
/**
|
||||
* 目标图片文件格式,用于写出
|
||||
|
@ -35,7 +35,7 @@ public enum ScaleType {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private int value;
|
||||
private final int value;
|
||||
|
||||
public int getValue() {
|
||||
return this.value;
|
||||
|
@ -82,7 +82,7 @@ public class FileUtil {
|
||||
/**
|
||||
* Windows下文件名中的无效字符
|
||||
*/
|
||||
private static Pattern FILE_NAME_INVALID_PATTERN_WIN = Pattern.compile("[\\\\/:*?\"<>|]");
|
||||
private static final Pattern FILE_NAME_INVALID_PATTERN_WIN = Pattern.compile("[\\\\/:*?\"<>|]");
|
||||
|
||||
/**
|
||||
* Class文件扩展名
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.hutool.core.io.file;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
@ -7,8 +9,6 @@ import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
/**
|
||||
* 文件追加器<br>
|
||||
* 持有一个文件,在内存中积累一定量的数据后统一追加到文件<br>
|
||||
@ -21,12 +21,12 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
public class FileAppender implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private FileWriter writer;
|
||||
private final FileWriter writer;
|
||||
/** 内存中持有的字符串数 */
|
||||
private int capacity;
|
||||
private final int capacity;
|
||||
/** 追加内容是否为新行 */
|
||||
private boolean isNewLineMode;
|
||||
private List<String> list = new ArrayList<>(100);
|
||||
private final boolean isNewLineMode;
|
||||
private final List<String> list = new ArrayList<>(100);
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,16 +1,16 @@
|
||||
package cn.hutool.core.io.file;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.LineHandler;
|
||||
import cn.hutool.core.io.watch.SimpleWatcher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.WatchEvent;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.LineHandler;
|
||||
import cn.hutool.core.io.watch.SimpleWatcher;
|
||||
|
||||
/**
|
||||
* 行处理的Watcher实现
|
||||
*
|
||||
@ -19,9 +19,9 @@ import cn.hutool.core.io.watch.SimpleWatcher;
|
||||
*/
|
||||
public class LineReadWatcher extends SimpleWatcher implements Runnable {
|
||||
|
||||
private RandomAccessFile randomAccessFile;
|
||||
private Charset charset;
|
||||
private LineHandler lineHandler;
|
||||
private final RandomAccessFile randomAccessFile;
|
||||
private final Charset charset;
|
||||
private final LineHandler lineHandler;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -23,7 +23,7 @@ public enum LineSeparator {
|
||||
/** Windows系统换行符:"\r\n" */
|
||||
WINDOWS("\r\n");
|
||||
|
||||
private String value;
|
||||
private final String value;
|
||||
|
||||
LineSeparator(String lineSeparator) {
|
||||
this.value = lineSeparator;
|
||||
|
@ -1,5 +1,14 @@
|
||||
package cn.hutool.core.io.file;
|
||||
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.LineHandler;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
@ -12,15 +21,6 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.LineHandler;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
/**
|
||||
* 文件内容跟随器,实现类似Linux下"tail -f"命令功能
|
||||
*
|
||||
@ -33,16 +33,16 @@ public class Tailer implements Serializable {
|
||||
public static final LineHandler CONSOLE_HANDLER = new ConsoleLineHandler();
|
||||
|
||||
/** 编码 */
|
||||
private Charset charset;
|
||||
private final Charset charset;
|
||||
/** 行处理器 */
|
||||
private LineHandler lineHandler;
|
||||
private final LineHandler lineHandler;
|
||||
/** 初始读取的行数 */
|
||||
private int initReadLine;
|
||||
private final int initReadLine;
|
||||
/** 定时任务检查间隔时长 */
|
||||
private long period;
|
||||
private final long period;
|
||||
|
||||
private RandomAccessFile randomAccessFile;
|
||||
private ScheduledExecutorService executorService;
|
||||
private final RandomAccessFile randomAccessFile;
|
||||
private final ScheduledExecutorService executorService;
|
||||
|
||||
/**
|
||||
* 构造,默认UTF-8编码
|
||||
|
@ -1,15 +1,15 @@
|
||||
package cn.hutool.core.io.resource;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
/**
|
||||
* 基于{@link InputStream}的资源获取器<br>
|
||||
* 注意:此对象中getUrl方法始终返回null
|
||||
@ -20,8 +20,8 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
public class InputStreamResource implements Resource, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private InputStream in;
|
||||
private String name;
|
||||
private final InputStream in;
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,5 +1,8 @@
|
||||
package cn.hutool.core.io.resource;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
@ -10,9 +13,6 @@ import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
|
||||
/**
|
||||
* 多资源组合资源<br>
|
||||
* 此资源为一个利用游标自循环资源,只有调用{@link #next()} 方法才会获取下一个资源,使用完毕后调用{@link #reset()}方法重置游标
|
||||
@ -23,7 +23,7 @@ import cn.hutool.core.io.IORuntimeException;
|
||||
public class MultiResource implements Resource, Iterable<Resource>, Iterator<Resource>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<Resource> resources;
|
||||
private final List<Resource> resources;
|
||||
private int cursor;
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,9 @@
|
||||
package cn.hutool.core.io.resource;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
@ -8,10 +12,6 @@ import java.io.StringReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
/**
|
||||
* 字符串资源,字符串做为资源
|
||||
*
|
||||
@ -21,9 +21,9 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
public class StringResource implements Resource, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String data;
|
||||
private String name;
|
||||
private Charset charset;
|
||||
private final String data;
|
||||
private final String name;
|
||||
private final Charset charset;
|
||||
|
||||
/**
|
||||
* 构造,使用UTF8编码
|
||||
|
@ -1,12 +1,5 @@
|
||||
package cn.hutool.core.io.resource;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
@ -14,6 +7,13 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* URL资源访问类
|
||||
* @author Looly
|
||||
@ -68,7 +68,7 @@ public class UrlResource implements Resource, Serializable{
|
||||
@Override
|
||||
public InputStream getStream() throws NoResourceException{
|
||||
if(null == this.url){
|
||||
throw new NoResourceException("Resource [{}] not exist!", this.url);
|
||||
throw new NoResourceException("Resource URL is null!");
|
||||
}
|
||||
return URLUtil.getStream(url);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public enum WatchKind {
|
||||
DELETE.getValue() //删除
|
||||
};
|
||||
|
||||
private WatchEvent.Kind<?> value;
|
||||
private final WatchEvent.Kind<?> value;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -51,7 +51,7 @@ public class WatchServer extends Thread implements Closeable, Serializable {
|
||||
/**
|
||||
* WatchKey 和 Path的对应表
|
||||
*/
|
||||
private Map<WatchKey, Path> watchKeyPathMap = new HashMap<>();
|
||||
private final Map<WatchKey, Path> watchKeyPathMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 初始化<br>
|
||||
|
@ -2,7 +2,6 @@ package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.EnumerationIter;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
|
@ -1,10 +1,10 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.clone.CloneSupport;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import cn.hutool.core.clone.CloneSupport;
|
||||
|
||||
/**
|
||||
* 键值对对象,只能在构造时传入键值
|
||||
*
|
||||
@ -17,8 +17,8 @@ import cn.hutool.core.clone.CloneSupport;
|
||||
public class Pair<K, V> extends CloneSupport<Pair<K, V>> implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private K key;
|
||||
private V value;
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -183,8 +183,8 @@ public class PatternPool {
|
||||
* @author Looly
|
||||
*/
|
||||
private static class RegexWithFlag {
|
||||
private String regex;
|
||||
private int flag;
|
||||
private final String regex;
|
||||
private final int flag;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.thread.lock.NoLock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
@ -7,8 +9,6 @@ import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import cn.hutool.core.thread.lock.NoLock;
|
||||
|
||||
/**
|
||||
* 范围生成器。根据给定的初始值、结束值和步进生成一个步进列表生成器<br>
|
||||
* 由于用户自行实现{@link Steper}来定义步进,因此Range本身无法判定边界(是否达到end),需在step实现边界判定逻辑。
|
||||
@ -27,19 +27,19 @@ public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
||||
/** 锁保证线程安全 */
|
||||
private Lock lock = new ReentrantLock();
|
||||
/** 起始对象 */
|
||||
private T start;
|
||||
private final T start;
|
||||
/** 结束对象 */
|
||||
private T end;
|
||||
private final T end;
|
||||
/** 当前对象 */
|
||||
private T current;
|
||||
/** 下一个对象 */
|
||||
private T next;
|
||||
/** 步进 */
|
||||
private Steper<T> steper;
|
||||
private final Steper<T> steper;
|
||||
/** 索引 */
|
||||
private int index = 0;
|
||||
/** 是否包含第一个元素 */
|
||||
private boolean includeStart;
|
||||
private final boolean includeStart;
|
||||
/** 是否包含最后一个元素 */
|
||||
private boolean includeEnd;
|
||||
|
||||
|
@ -8,24 +8,46 @@ import java.util.WeakHashMap;
|
||||
import java.util.concurrent.locks.StampedLock;
|
||||
|
||||
/**
|
||||
* 简单缓存,无超时实现,使用{@link WeakHashMap}实现缓存自动清理
|
||||
* @author Looly
|
||||
* 简单缓存,无超时实现,默认使用{@link WeakHashMap}实现缓存自动清理
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @author Looly
|
||||
*/
|
||||
public class SimpleCache<K, V> implements Serializable{
|
||||
public class SimpleCache<K, V> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 池 */
|
||||
private final Map<K, V> cache = new WeakHashMap<>();
|
||||
|
||||
/**
|
||||
* 池
|
||||
*/
|
||||
private final Map<K, V> cache;
|
||||
// 乐观读写锁
|
||||
private final StampedLock lock = new StampedLock ();
|
||||
private final StampedLock lock = new StampedLock();
|
||||
|
||||
/**
|
||||
* 构造,默认使用{@link WeakHashMap}实现缓存自动清理
|
||||
*/
|
||||
public SimpleCache() {
|
||||
this(new WeakHashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* <p>
|
||||
* 通过自定义Map初始化,可以自定义缓存实现。<br>
|
||||
* 比如使用{@link WeakHashMap}则会自动清理key,使用HashMap则不会清理<br>
|
||||
* 同时,传入的Map对象也可以自带初始化的键值对,防止在get时创建
|
||||
* </p>
|
||||
*
|
||||
* @param initMap 初始Map,用于定义Map类型
|
||||
*/
|
||||
public SimpleCache(Map<K, V> initMap) {
|
||||
this.cache = initMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存池中查找值
|
||||
*
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
@ -37,27 +59,27 @@ public class SimpleCache<K, V> implements Serializable{
|
||||
lock.unlockRead(stamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从缓存中获得对象,当对象不在缓存中或已经过期返回Func0回调产生的对象
|
||||
*
|
||||
* @param key 键
|
||||
*
|
||||
* @param key 键
|
||||
* @param supplier 如果不存在回调方法,用于生产值对象
|
||||
* @return 值对象
|
||||
*/
|
||||
public V get(K key, Func0<V> supplier) {
|
||||
if(null == supplier){
|
||||
if (null == supplier) {
|
||||
return get(key);
|
||||
}
|
||||
|
||||
long stamp = lock.readLock();
|
||||
V v;
|
||||
try{
|
||||
try {
|
||||
v = cache.get(key);
|
||||
if (null == v) {
|
||||
// 尝试转换独占写锁
|
||||
long writeStamp = lock.tryConvertToWriteLock(stamp);
|
||||
if(0 == writeStamp){
|
||||
if (0 == writeStamp) {
|
||||
// 转换失败,手动更新为写锁
|
||||
lock.unlockRead(stamp);
|
||||
writeStamp = lock.writeLock();
|
||||
@ -65,7 +87,7 @@ public class SimpleCache<K, V> implements Serializable{
|
||||
stamp = writeStamp;
|
||||
v = cache.get(key);
|
||||
// 双重检查,防止在竞争锁的过程中已经有其它线程写入
|
||||
if(null == v) {
|
||||
if (null == v) {
|
||||
try {
|
||||
v = supplier.call();
|
||||
} catch (Exception e) {
|
||||
@ -79,14 +101,15 @@ public class SimpleCache<K, V> implements Serializable{
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 放入缓存
|
||||
* @param key 键
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 值
|
||||
*/
|
||||
public V put(K key, V value){
|
||||
public V put(K key, V value) {
|
||||
// 独占写锁
|
||||
final long stamp = lock.writeLock();
|
||||
try {
|
||||
@ -99,7 +122,7 @@ public class SimpleCache<K, V> implements Serializable{
|
||||
|
||||
/**
|
||||
* 移除缓存
|
||||
*
|
||||
*
|
||||
* @param key 键
|
||||
* @return 移除的值
|
||||
*/
|
||||
|
@ -1,22 +1,21 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 单例类<br>
|
||||
* 提供单例对象的统一管理,当调用get方法时,如果对象池中存在此对象,返回此对象,否则创建新对象返回<br>
|
||||
*
|
||||
* @author loolly
|
||||
*
|
||||
* @author loolly
|
||||
*/
|
||||
public final class Singleton {
|
||||
private static Map<String, Object> pool = new ConcurrentHashMap<>();
|
||||
|
||||
private static final SimpleCache<String, Object> POOL = new SimpleCache<>(new HashMap<>());
|
||||
|
||||
private Singleton() {
|
||||
}
|
||||
@ -25,9 +24,9 @@ public final class Singleton {
|
||||
* 获得指定类的单例对象<br>
|
||||
* 对象存在于池中返回,否则创建,每次调用此方法获得的对象为同一个对象<br>
|
||||
* 注意:单例针对的是类和对象,因此get方法第一次调用时创建的对象始终唯一,也就是说就算参数变更,返回的依旧是第一次创建的对象
|
||||
*
|
||||
* @param <T> 单例对象类型
|
||||
* @param clazz 类
|
||||
*
|
||||
* @param <T> 单例对象类型
|
||||
* @param clazz 类
|
||||
* @param params 构造方法参数
|
||||
* @return 单例对象
|
||||
*/
|
||||
@ -35,28 +34,16 @@ public final class Singleton {
|
||||
public static <T> T get(Class<T> clazz, Object... params) {
|
||||
Assert.notNull(clazz, "Class must be not null !");
|
||||
final String key = buildKey(clazz.getName(), params);
|
||||
T obj = (T) pool.get(key);
|
||||
|
||||
if (null == obj) {
|
||||
synchronized (Singleton.class) {
|
||||
obj = (T) pool.get(key);
|
||||
if (null == obj) {
|
||||
obj = (T) ReflectUtil.newInstance(clazz, params);
|
||||
pool.put(key, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
return (T) POOL.get(key, () -> ReflectUtil.newInstance(clazz, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定类的单例对象<br>
|
||||
* 对象存在于池中返回,否则创建,每次调用此方法获得的对象为同一个对象<br>
|
||||
*
|
||||
* @param <T> 单例对象类型
|
||||
*
|
||||
* @param <T> 单例对象类型
|
||||
* @param className 类名
|
||||
* @param params 构造参数
|
||||
* @param params 构造参数
|
||||
* @return 单例对象
|
||||
*/
|
||||
public static <T> T get(String className, Object... params) {
|
||||
@ -67,23 +54,23 @@ public final class Singleton {
|
||||
|
||||
/**
|
||||
* 将已有对象放入单例中,其Class做为键
|
||||
*
|
||||
*
|
||||
* @param obj 对象
|
||||
* @since 4.0.7
|
||||
*/
|
||||
public static void put(Object obj) {
|
||||
Assert.notNull(obj, "Bean object must be not null !");
|
||||
pool.put(obj.getClass().getName(), obj);
|
||||
POOL.put(obj.getClass().getName(), obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定Singleton对象
|
||||
*
|
||||
*
|
||||
* @param clazz 类
|
||||
*/
|
||||
public static void remove(Class<?> clazz) {
|
||||
if (null != clazz) {
|
||||
pool.remove(clazz.getName());
|
||||
POOL.remove(clazz.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,15 +78,16 @@ public final class Singleton {
|
||||
* 清除所有Singleton对象
|
||||
*/
|
||||
public static void destroy() {
|
||||
pool.clear();
|
||||
POOL.clear();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 构建key
|
||||
*
|
||||
*
|
||||
* @param className 类名
|
||||
* @param params 参数列表
|
||||
* @param params 参数列表
|
||||
* @return key
|
||||
*/
|
||||
private static String buildKey(String className, Object... params) {
|
||||
|
@ -51,11 +51,11 @@ public class Snowflake implements Serializable {
|
||||
@SuppressWarnings({"PointlessBitwiseExpression", "FieldCanBeLocal"})
|
||||
private final long sequenceMask = -1L ^ (-1L << sequenceBits);// 4095
|
||||
|
||||
private long workerId;
|
||||
private long dataCenterId;
|
||||
private final long workerId;
|
||||
private final long dataCenterId;
|
||||
private final boolean useSystemClock;
|
||||
private long sequence = 0L;
|
||||
private long lastTimestamp = -1L;
|
||||
private boolean useSystemClock;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,13 +1,13 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* 提供通用唯一识别码(universally unique identifier)(UUID)实现,UUID表示一个128位的值。<br>
|
||||
* 此类拷贝自java.util.UUID,用于生成不带-的UUID字符串
|
||||
@ -165,15 +165,15 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
components[i] = "0x" + components[i];
|
||||
}
|
||||
|
||||
long mostSigBits = Long.decode(components[0]).longValue();
|
||||
long mostSigBits = Long.decode(components[0]);
|
||||
mostSigBits <<= 16;
|
||||
mostSigBits |= Long.decode(components[1]).longValue();
|
||||
mostSigBits |= Long.decode(components[1]);
|
||||
mostSigBits <<= 16;
|
||||
mostSigBits |= Long.decode(components[2]).longValue();
|
||||
mostSigBits |= Long.decode(components[2]);
|
||||
|
||||
long leastSigBits = Long.decode(components[3]).longValue();
|
||||
long leastSigBits = Long.decode(components[3]);
|
||||
leastSigBits <<= 48;
|
||||
leastSigBits |= Long.decode(components[4]).longValue();
|
||||
leastSigBits |= Long.decode(components[4]);
|
||||
|
||||
return new UUID(mostSigBits, leastSigBits);
|
||||
}
|
||||
@ -412,11 +412,11 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
public int compareTo(UUID val) {
|
||||
// The ordering is intentionally set up so that the UUIDs
|
||||
// can simply be numerically compared as two numbers
|
||||
return (this.mostSigBits < val.mostSigBits ? -1 : //
|
||||
(this.mostSigBits > val.mostSigBits ? 1 : //
|
||||
(this.leastSigBits < val.leastSigBits ? -1 : //
|
||||
(this.leastSigBits > val.leastSigBits ? 1 : //
|
||||
0))));
|
||||
int compare = Long.compare(this.mostSigBits, val.mostSigBits);
|
||||
if(0 == compare){
|
||||
compare = Long.compare(this.leastSigBits, val.leastSigBits);
|
||||
}
|
||||
return compare;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------- Private method start
|
||||
|
@ -1,14 +1,14 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Random;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
|
||||
/**
|
||||
* 权重随机算法实现<br>
|
||||
* <p>
|
||||
@ -31,8 +31,8 @@ import cn.hutool.core.util.RandomUtil;
|
||||
public class WeightRandom<T> implements Serializable {
|
||||
private static final long serialVersionUID = -8244697995702786499L;
|
||||
|
||||
private TreeMap<Double, T> weightMap;
|
||||
private Random random;
|
||||
private final TreeMap<Double, T> weightMap;
|
||||
private final Random random;
|
||||
|
||||
/**
|
||||
* 创建权重随机获取器
|
||||
@ -157,7 +157,7 @@ public class WeightRandom<T> implements Serializable {
|
||||
/** 对象 */
|
||||
private T obj;
|
||||
/** 权重 */
|
||||
private double weight;
|
||||
private final double weight;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -16,7 +16,7 @@ import java.util.List;
|
||||
public class Tree<T> extends LinkedHashMap<String, Object> implements Node<T> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private TreeNodeConfig treeNodeConfig;
|
||||
private final TreeNodeConfig treeNodeConfig;
|
||||
private Tree<T> parent;
|
||||
|
||||
public Tree() {
|
||||
|
@ -13,7 +13,7 @@ import java.util.Map;
|
||||
public class MapBuilder<K, V> implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Map<K, V> map;
|
||||
private final Map<K, V> map;
|
||||
|
||||
/**
|
||||
* 创建Builder,默认HashMap实现
|
||||
|
@ -1,5 +1,12 @@
|
||||
package cn.hutool.core.map;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.getter.OptNullBasicTypeFromObjectGetter;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.ClassLoaderUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
@ -8,13 +15,6 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.getter.OptNullBasicTypeFromObjectGetter;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.ClassLoaderUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* Map代理,提供各种getXXX方法,并提供默认值支持
|
||||
*
|
||||
@ -123,7 +123,7 @@ public class MapProxy implements Map<Object, Object>, OptNullBasicTypeFromObject
|
||||
final Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (ArrayUtil.isEmpty(parameterTypes)) {
|
||||
final Class<?> returnType = method.getReturnType();
|
||||
if (null != returnType && void.class != returnType) {
|
||||
if (void.class != returnType) {
|
||||
// 匹配Getter
|
||||
final String methodName = method.getName();
|
||||
String fieldName = null;
|
||||
|
@ -27,8 +27,8 @@ import java.util.Set;
|
||||
public class TableMap<K, V> implements Map<K, V>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<K> keys;
|
||||
private List<V> values;
|
||||
private final List<K> keys;
|
||||
private final List<V> values;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -168,8 +168,8 @@ public class TableMap<K, V> implements Map<K, V>, Serializable {
|
||||
|
||||
private static class Entry<K, V> implements Map.Entry<K, V> {
|
||||
|
||||
private K key;
|
||||
private V value;
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
public Entry(K key, V value) {
|
||||
this.key = key;
|
||||
|
@ -19,185 +19,185 @@ import java.util.function.Function;
|
||||
*/
|
||||
public class TolerantMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4158133823263496197L;
|
||||
private static final long serialVersionUID = -4158133823263496197L;
|
||||
|
||||
private transient Map<K, V> map;
|
||||
private transient Map<K, V> map;
|
||||
|
||||
private transient V defaultValue;
|
||||
private transient V defaultValue;
|
||||
|
||||
public TolerantMap(V defaultValue) {
|
||||
this(new HashMap<>(), defaultValue);
|
||||
}
|
||||
public TolerantMap(V defaultValue) {
|
||||
this(new HashMap<>(), defaultValue);
|
||||
}
|
||||
|
||||
public TolerantMap(int initialCapacity, float loadFactor, V defaultValue) {
|
||||
this(new HashMap<>(initialCapacity, loadFactor), defaultValue);
|
||||
}
|
||||
public TolerantMap(int initialCapacity, float loadFactor, V defaultValue) {
|
||||
this(new HashMap<>(initialCapacity, loadFactor), defaultValue);
|
||||
}
|
||||
|
||||
public TolerantMap(int initialCapacity, V defaultValue) {
|
||||
this(new HashMap<>(initialCapacity), defaultValue);
|
||||
}
|
||||
public TolerantMap(int initialCapacity, V defaultValue) {
|
||||
this(new HashMap<>(initialCapacity), defaultValue);
|
||||
}
|
||||
|
||||
public TolerantMap(Map<K, V> map, V defaultValue) {
|
||||
this.map = map;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
public TolerantMap(Map<K, V> map, V defaultValue) {
|
||||
this.map = map;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public static <K, V> TolerantMap<K, V> of(Map<K, V> map, V defaultValue) {
|
||||
return new TolerantMap<>(map, defaultValue);
|
||||
}
|
||||
public static <K, V> TolerantMap<K, V> of(Map<K, V> map, V defaultValue) {
|
||||
return new TolerantMap<>(map, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
return getOrDefault(key, defaultValue);
|
||||
}
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
return getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
return map.put(key, value);
|
||||
}
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
return map.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
return map.remove(key);
|
||||
}
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
return map.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
map.putAll(m);
|
||||
}
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
map.putAll(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
@Override
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
return map.values();
|
||||
}
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getOrDefault(Object key, V defaultValue) {
|
||||
return map.getOrDefault(key, defaultValue);
|
||||
}
|
||||
@Override
|
||||
public V getOrDefault(Object key, V defaultValue) {
|
||||
return map.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
map.forEach(action);
|
||||
}
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
map.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
map.replaceAll(function);
|
||||
}
|
||||
@Override
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
map.replaceAll(function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
return map.putIfAbsent(key, value);
|
||||
}
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
return map.putIfAbsent(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
return map.remove(key, value);
|
||||
}
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
return map.remove(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
return map.replace(key, oldValue, newValue);
|
||||
}
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
return map.replace(key, oldValue, newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
return map.replace(key, value);
|
||||
}
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
return map.replace(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
return map.computeIfAbsent(key, mappingFunction);
|
||||
}
|
||||
@Override
|
||||
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
return map.computeIfAbsent(key, mappingFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
return map.computeIfPresent(key, remappingFunction);
|
||||
}
|
||||
@Override
|
||||
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
return map.computeIfPresent(key, remappingFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
return map.compute(key, remappingFunction);
|
||||
}
|
||||
@Override
|
||||
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
return map.compute(key, remappingFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
return map.merge(key, value, remappingFunction);
|
||||
}
|
||||
@Override
|
||||
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
return map.merge(key, value, remappingFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
TolerantMap<?, ?> that = (TolerantMap<?, ?>) o;
|
||||
return map.equals(that.map) && Objects.equals(defaultValue, that.defaultValue);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
TolerantMap<?, ?> that = (TolerantMap<?, ?>) o;
|
||||
return map.equals(that.map) && Objects.equals(defaultValue, that.defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(map, defaultValue);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(map, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TolerantMap{" + "map=" + map + ", defaultValue=" + defaultValue + '}';
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TolerantMap{" + "map=" + map + ", defaultValue=" + defaultValue + '}';
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.writeObject(ObjectUtil.serialize(map));
|
||||
s.writeObject(ObjectUtil.serialize(defaultValue));
|
||||
}
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.writeObject(ObjectUtil.serialize(map));
|
||||
s.writeObject(ObjectUtil.serialize(defaultValue));
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
|
||||
map = ObjectUtil.deserialize((byte[]) s.readObject());
|
||||
defaultValue = ObjectUtil.deserialize((byte[]) s.readObject());
|
||||
}
|
||||
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
|
||||
map = ObjectUtil.deserialize((byte[]) s.readObject());
|
||||
defaultValue = ObjectUtil.deserialize((byte[]) s.readObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public class Money implements Serializable, Comparable<Money> {
|
||||
/**
|
||||
* 币种。
|
||||
*/
|
||||
private Currency currency;
|
||||
private final Currency currency;
|
||||
|
||||
// 构造器 ====================================================
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package cn.hutool.core.swing.clipboard;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
@ -7,9 +10,6 @@ import java.io.Closeable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
/**
|
||||
* 剪贴板监听
|
||||
*
|
||||
@ -189,6 +189,7 @@ public enum ClipboardMonitor implements ClipboardOwner, Runnable, Closeable {
|
||||
for (int i = 0; i < this.tryCount; i++) {
|
||||
if (this.delay > 0 && i > 0) {
|
||||
// 第一次获取不等待,只有从第二次获取时才开始等待
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(this.delay);
|
||||
}
|
||||
|
||||
@ -201,7 +202,7 @@ public enum ClipboardMonitor implements ClipboardOwner, Runnable, Closeable {
|
||||
return newContents;
|
||||
}
|
||||
}
|
||||
return newContents;
|
||||
return null;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------------------------------- Private method end
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import java.awt.Image;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
@ -17,7 +16,7 @@ import java.io.Serializable;
|
||||
public class ImageSelection implements Transferable, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Image image;
|
||||
private final Image image;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -56,7 +55,7 @@ public class ImageSelection implements Transferable, Serializable {
|
||||
* @return 转换后的对象
|
||||
*/
|
||||
@Override
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
|
||||
if (false == DataFlavor.imageFlavor.equals(flavor)) {
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
|
@ -1,16 +1,14 @@
|
||||
package cn.hutool.core.text;
|
||||
|
||||
import cn.hutool.core.lang.hash.MurmurHash;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
|
||||
import cn.hutool.core.lang.hash.MurmurHash;
|
||||
import java.util.concurrent.locks.StampedLock;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -35,8 +33,8 @@ public class Simhash {
|
||||
private final int hammingThresh;
|
||||
|
||||
/** 按照分段存储simhash,查找更快速 */
|
||||
private List<Map<String, List<Long>>> storage;
|
||||
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private final List<Map<String, List<Long>>> storage;
|
||||
private final StampedLock lock = new StampedLock();
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -57,7 +55,7 @@ public class Simhash {
|
||||
this.hammingThresh = hammingThresh;
|
||||
this.storage = new ArrayList<>(fracCount);
|
||||
for (int i = 0; i < fracCount; i++) {
|
||||
storage.add(new HashMap<String, List<Long>>());
|
||||
storage.add(new HashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,8 +102,7 @@ public class Simhash {
|
||||
|
||||
String frac;
|
||||
Map<String, List<Long>> fracMap;
|
||||
final ReadLock readLock = this.lock.readLock();
|
||||
readLock.lock();
|
||||
final long stamp = this.lock.readLock();
|
||||
try {
|
||||
for (int i = 0; i < fracCount; i++) {
|
||||
frac = fracList.get(i);
|
||||
@ -120,7 +117,7 @@ public class Simhash {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
this.lock.unlockRead(stamp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -137,8 +134,7 @@ public class Simhash {
|
||||
|
||||
String frac;
|
||||
Map<String, List<Long>> fracMap;
|
||||
final WriteLock writeLock = this.lock.writeLock();
|
||||
writeLock.lock();
|
||||
final long stamp = this.lock.writeLock();
|
||||
try {
|
||||
for (int i = 0; i < fracCount; i++) {
|
||||
frac = lFrac.get(i);
|
||||
@ -152,7 +148,7 @@ public class Simhash {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
this.lock.unlockWrite(stamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
package cn.hutool.core.text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import cn.hutool.core.lang.PatternPool;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 字符串切分器
|
||||
* @author Looly
|
||||
@ -149,10 +149,10 @@ public class StrSpliter {
|
||||
*/
|
||||
public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase){
|
||||
if(StrUtil.isEmpty(str)){
|
||||
return new ArrayList<String>(0);
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
if(limit == 1){
|
||||
return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
|
||||
return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty);
|
||||
}
|
||||
|
||||
final ArrayList<String> list = new ArrayList<>(limit > 0 ? limit : 16);
|
||||
@ -288,10 +288,10 @@ public class StrSpliter {
|
||||
*/
|
||||
public static List<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase){
|
||||
if(StrUtil.isEmpty(str)){
|
||||
return new ArrayList<String>(0);
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
if(limit == 1){
|
||||
return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
|
||||
return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty);
|
||||
}
|
||||
|
||||
if(StrUtil.isEmpty(separator)){//分隔符为空时按照空白符切分
|
||||
@ -350,10 +350,10 @@ public class StrSpliter {
|
||||
*/
|
||||
public static List<String> split(String str, int limit){
|
||||
if(StrUtil.isEmpty(str)){
|
||||
return new ArrayList<String>(0);
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
if(limit == 1){
|
||||
return addToList(new ArrayList<String>(1), str, true, true);
|
||||
return addToList(new ArrayList<>(1), str, true, true);
|
||||
}
|
||||
|
||||
final ArrayList<String> list = new ArrayList<>();
|
||||
@ -413,10 +413,10 @@ public class StrSpliter {
|
||||
*/
|
||||
public static List<String> split(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty){
|
||||
if(StrUtil.isEmpty(str)){
|
||||
return new ArrayList<String>(0);
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
if(limit == 1){
|
||||
return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
|
||||
return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty);
|
||||
}
|
||||
|
||||
if(null == separatorPattern){//分隔符为空时按照空白符切分
|
||||
@ -507,7 +507,7 @@ public class StrSpliter {
|
||||
* @return Array
|
||||
*/
|
||||
private static String[] toArray(List<String> list){
|
||||
return list.toArray(new String[list.size()]);
|
||||
return list.toArray(new String[0]);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------- Private method end
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class UnicodeUtil {
|
||||
pos = i + 2;
|
||||
}
|
||||
} else {
|
||||
pos = i;//非Unicode符,结束
|
||||
//非Unicode符,结束
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
package cn.hutool.core.text.csv;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@ -11,13 +18,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* CSV行解析器,参考:FastCSV
|
||||
*
|
||||
@ -96,12 +96,8 @@ public final class CsvParser implements Closeable, Serializable {
|
||||
while (false == finished) {
|
||||
startingLineNo = ++lineNo;
|
||||
currentFields = readLine();
|
||||
if(null == currentFields) {
|
||||
break;
|
||||
}
|
||||
fieldCount = currentFields.size();
|
||||
// 末尾
|
||||
if (fieldCount == 0) {
|
||||
if(fieldCount < 1){
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class NumericEntityUnescaper extends StrReplacer {
|
||||
return 0;
|
||||
}
|
||||
out.append((char)entityValue);
|
||||
return 2 + end - start + (isHex ? 1 : 0) + (isSemiNext ? 1 : 0);
|
||||
return 2 + end - start + (isHex ? 1 : 0) + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1,12 +1,12 @@
|
||||
package cn.hutool.core.text.replacer;
|
||||
|
||||
import cn.hutool.core.lang.Chain;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.lang.Chain;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
|
||||
/**
|
||||
* 字符串替换链,用于组合多个字符串替换逻辑
|
||||
*
|
||||
@ -16,7 +16,7 @@ import cn.hutool.core.text.StrBuilder;
|
||||
public class ReplacerChain extends StrReplacer implements Chain<StrReplacer, ReplacerChain> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<StrReplacer> replacers = new LinkedList<>();
|
||||
private final List<StrReplacer> replacers = new LinkedList<>();
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -17,8 +17,8 @@ import cn.hutool.core.date.TimeInterval;
|
||||
* @author kwer
|
||||
*/
|
||||
public class ConcurrencyTester {
|
||||
private SyncFinisher sf;
|
||||
private TimeInterval timeInterval;
|
||||
private final SyncFinisher sf;
|
||||
private final TimeInterval timeInterval;
|
||||
private long interval;
|
||||
|
||||
public ConcurrencyTester(int threadSize) {
|
||||
|
@ -23,7 +23,7 @@ public enum RejectPolicy {
|
||||
/** 由主线程来直接执行 */
|
||||
CALLER_RUNS(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
|
||||
private RejectedExecutionHandler value;
|
||||
private final RejectedExecutionHandler value;
|
||||
|
||||
RejectPolicy(RejectedExecutionHandler handler) {
|
||||
this.value = handler;
|
||||
|
@ -16,9 +16,9 @@ import java.util.concurrent.Semaphore;
|
||||
public class SemaphoreRunnable implements Runnable {
|
||||
|
||||
/** 实际执行的逻辑 */
|
||||
private Runnable runnable;
|
||||
private final Runnable runnable;
|
||||
/** 信号量 */
|
||||
private Semaphore semaphore;
|
||||
private final Semaphore semaphore;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,13 +1,13 @@
|
||||
package cn.hutool.core.thread;
|
||||
|
||||
import cn.hutool.core.exceptions.NotInitedException;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import cn.hutool.core.exceptions.NotInitedException;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
|
||||
/**
|
||||
* 线程同步结束器<br>
|
||||
* 在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
|
||||
@ -27,13 +27,13 @@ import cn.hutool.core.exceptions.UtilException;
|
||||
*/
|
||||
public class SyncFinisher {
|
||||
|
||||
private Set<Worker> workers;
|
||||
private int threadSize;
|
||||
private ExecutorService executorService;
|
||||
private final Set<Worker> workers;
|
||||
private final int threadSize;
|
||||
private final ExecutorService executorService;
|
||||
|
||||
private boolean isBeginAtSameTime;
|
||||
/** 启动同步器,用于保证所有worker线程同时开始 */
|
||||
private CountDownLatch beginLatch;
|
||||
private final CountDownLatch beginLatch;
|
||||
/** 结束同步器,用于等待所有worker线程同时结束 */
|
||||
private CountDownLatch endLatch;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import java.util.concurrent.locks.StampedLock;
|
||||
*/
|
||||
public class LockUtil {
|
||||
|
||||
private static NoLock NO_LOCK = new NoLock();
|
||||
private static final NoLock NO_LOCK = new NoLock();
|
||||
|
||||
/**
|
||||
* 创建{@link StampedLock}锁
|
||||
|
@ -38,7 +38,7 @@ public class NoLock implements Lock{
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@Override
|
||||
public Condition newCondition() {
|
||||
return null;
|
||||
throw new UnsupportedOperationException("NoLock`s newCondition method is unsupported");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,23 +7,24 @@ import cn.hutool.core.lang.UUID;
|
||||
|
||||
/**
|
||||
* ID生成器工具类,此工具类中主要封装:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 1. 唯一性ID生成器:UUID、ObjectId(MongoDB)、Snowflake
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* ID相关文章见:http://calvin1978.blogcn.com/articles/uuid.html
|
||||
*
|
||||
*
|
||||
* @author looly
|
||||
* @since 4.1.13
|
||||
*/
|
||||
public class IdUtil {
|
||||
|
||||
// ------------------------------------------------------------------- UUID
|
||||
|
||||
/**
|
||||
* 获取随机UUID
|
||||
*
|
||||
*
|
||||
* @return 随机UUID
|
||||
*/
|
||||
public static String randomUUID() {
|
||||
@ -32,7 +33,7 @@ public class IdUtil {
|
||||
|
||||
/**
|
||||
* 简化的UUID,去掉了横线
|
||||
*
|
||||
*
|
||||
* @return 简化的UUID,去掉了横线
|
||||
*/
|
||||
public static String simpleUUID() {
|
||||
@ -41,7 +42,7 @@ public class IdUtil {
|
||||
|
||||
/**
|
||||
* 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
|
||||
*
|
||||
*
|
||||
* @return 随机UUID
|
||||
* @since 4.1.19
|
||||
*/
|
||||
@ -51,7 +52,7 @@ public class IdUtil {
|
||||
|
||||
/**
|
||||
* 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
|
||||
*
|
||||
*
|
||||
* @return 简化的UUID,去掉了横线
|
||||
* @since 4.1.19
|
||||
*/
|
||||
@ -62,16 +63,16 @@ public class IdUtil {
|
||||
/**
|
||||
* 创建MongoDB ID生成策略实现<br>
|
||||
* ObjectId由以下几部分组成:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 1. Time 时间戳。
|
||||
* 2. Machine 所在主机的唯一标识符,一般是机器主机名的散列值。
|
||||
* 3. PID 进程ID。确保同一机器中不冲突
|
||||
* 4. INC 自增计数器。确保同一秒内产生objectId的唯一性。
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 参考:http://blog.csdn.net/qxc1281/article/details/54021882
|
||||
*
|
||||
*
|
||||
* @return ObjectId
|
||||
*/
|
||||
public static String objectId() {
|
||||
@ -79,24 +80,27 @@ public class IdUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Twitter的Snowflake 算法生成器<br>
|
||||
* 创建Twitter的Snowflake 算法生成器。
|
||||
* <p>
|
||||
* 特别注意:此方法调用后会创建独立的{@link Snowflake}对象,每个独立的对象ID不互斥,会导致ID重复,请自行保证单例!
|
||||
* </p>
|
||||
* 分布式系统中,有一些需要使用全局唯一ID的场景,有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* snowflake的结构如下(每部分用-分开):<br>
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年)<br>
|
||||
* 然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点)<br>
|
||||
* 最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* 参考:http://www.cnblogs.com/relucent/p/4955340.html
|
||||
*
|
||||
* @param workerId 终端ID
|
||||
*
|
||||
* @param workerId 终端ID
|
||||
* @param datacenterId 数据中心ID
|
||||
* @return {@link Snowflake}
|
||||
*/
|
||||
@ -107,22 +111,22 @@ public class IdUtil {
|
||||
/**
|
||||
* 获取单例的Twitter的Snowflake 算法生成器对象<br>
|
||||
* 分布式系统中,有一些需要使用全局唯一ID的场景,有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* snowflake的结构如下(每部分用-分开):<br>
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年)<br>
|
||||
* 然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点)<br>
|
||||
* 最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* 参考:http://www.cnblogs.com/relucent/p/4955340.html
|
||||
*
|
||||
* @param workerId 终端ID
|
||||
*
|
||||
* @param workerId 终端ID
|
||||
* @param datacenterId 数据中心ID
|
||||
* @return {@link Snowflake}
|
||||
* @since 4.5.9
|
||||
|
@ -41,91 +41,91 @@ public class IdcardUtil {
|
||||
/**
|
||||
* 省市代码表
|
||||
*/
|
||||
private static Map<String, String> cityCodes = new HashMap<>();
|
||||
private static final Map<String, String> CITY_CODES = new HashMap<>();
|
||||
/**
|
||||
* 台湾身份首字母对应数字
|
||||
*/
|
||||
private static Map<String, Integer> twFirstCode = new HashMap<>();
|
||||
private static final Map<String, Integer> TW_FIRST_CODE = new HashMap<>();
|
||||
/**
|
||||
* 香港身份首字母对应数字
|
||||
*/
|
||||
private static Map<String, Integer> hkFirstCode = new HashMap<>();
|
||||
private static final Map<String, Integer> HK_FIRST_CODE = new HashMap<>();
|
||||
|
||||
static {
|
||||
cityCodes.put("11", "北京");
|
||||
cityCodes.put("12", "天津");
|
||||
cityCodes.put("13", "河北");
|
||||
cityCodes.put("14", "山西");
|
||||
cityCodes.put("15", "内蒙古");
|
||||
cityCodes.put("21", "辽宁");
|
||||
cityCodes.put("22", "吉林");
|
||||
cityCodes.put("23", "黑龙江");
|
||||
cityCodes.put("31", "上海");
|
||||
cityCodes.put("32", "江苏");
|
||||
cityCodes.put("33", "浙江");
|
||||
cityCodes.put("34", "安徽");
|
||||
cityCodes.put("35", "福建");
|
||||
cityCodes.put("36", "江西");
|
||||
cityCodes.put("37", "山东");
|
||||
cityCodes.put("41", "河南");
|
||||
cityCodes.put("42", "湖北");
|
||||
cityCodes.put("43", "湖南");
|
||||
cityCodes.put("44", "广东");
|
||||
cityCodes.put("45", "广西");
|
||||
cityCodes.put("46", "海南");
|
||||
cityCodes.put("50", "重庆");
|
||||
cityCodes.put("51", "四川");
|
||||
cityCodes.put("52", "贵州");
|
||||
cityCodes.put("53", "云南");
|
||||
cityCodes.put("54", "西藏");
|
||||
cityCodes.put("61", "陕西");
|
||||
cityCodes.put("62", "甘肃");
|
||||
cityCodes.put("63", "青海");
|
||||
cityCodes.put("64", "宁夏");
|
||||
cityCodes.put("65", "新疆");
|
||||
cityCodes.put("71", "台湾");
|
||||
cityCodes.put("81", "香港");
|
||||
cityCodes.put("82", "澳门");
|
||||
cityCodes.put("91", "国外");
|
||||
CITY_CODES.put("11", "北京");
|
||||
CITY_CODES.put("12", "天津");
|
||||
CITY_CODES.put("13", "河北");
|
||||
CITY_CODES.put("14", "山西");
|
||||
CITY_CODES.put("15", "内蒙古");
|
||||
CITY_CODES.put("21", "辽宁");
|
||||
CITY_CODES.put("22", "吉林");
|
||||
CITY_CODES.put("23", "黑龙江");
|
||||
CITY_CODES.put("31", "上海");
|
||||
CITY_CODES.put("32", "江苏");
|
||||
CITY_CODES.put("33", "浙江");
|
||||
CITY_CODES.put("34", "安徽");
|
||||
CITY_CODES.put("35", "福建");
|
||||
CITY_CODES.put("36", "江西");
|
||||
CITY_CODES.put("37", "山东");
|
||||
CITY_CODES.put("41", "河南");
|
||||
CITY_CODES.put("42", "湖北");
|
||||
CITY_CODES.put("43", "湖南");
|
||||
CITY_CODES.put("44", "广东");
|
||||
CITY_CODES.put("45", "广西");
|
||||
CITY_CODES.put("46", "海南");
|
||||
CITY_CODES.put("50", "重庆");
|
||||
CITY_CODES.put("51", "四川");
|
||||
CITY_CODES.put("52", "贵州");
|
||||
CITY_CODES.put("53", "云南");
|
||||
CITY_CODES.put("54", "西藏");
|
||||
CITY_CODES.put("61", "陕西");
|
||||
CITY_CODES.put("62", "甘肃");
|
||||
CITY_CODES.put("63", "青海");
|
||||
CITY_CODES.put("64", "宁夏");
|
||||
CITY_CODES.put("65", "新疆");
|
||||
CITY_CODES.put("71", "台湾");
|
||||
CITY_CODES.put("81", "香港");
|
||||
CITY_CODES.put("82", "澳门");
|
||||
CITY_CODES.put("91", "国外");
|
||||
|
||||
twFirstCode.put("A", 10);
|
||||
twFirstCode.put("B", 11);
|
||||
twFirstCode.put("C", 12);
|
||||
twFirstCode.put("D", 13);
|
||||
twFirstCode.put("E", 14);
|
||||
twFirstCode.put("F", 15);
|
||||
twFirstCode.put("G", 16);
|
||||
twFirstCode.put("H", 17);
|
||||
twFirstCode.put("J", 18);
|
||||
twFirstCode.put("K", 19);
|
||||
twFirstCode.put("L", 20);
|
||||
twFirstCode.put("M", 21);
|
||||
twFirstCode.put("N", 22);
|
||||
twFirstCode.put("P", 23);
|
||||
twFirstCode.put("Q", 24);
|
||||
twFirstCode.put("R", 25);
|
||||
twFirstCode.put("S", 26);
|
||||
twFirstCode.put("T", 27);
|
||||
twFirstCode.put("U", 28);
|
||||
twFirstCode.put("V", 29);
|
||||
twFirstCode.put("X", 30);
|
||||
twFirstCode.put("Y", 31);
|
||||
twFirstCode.put("W", 32);
|
||||
twFirstCode.put("Z", 33);
|
||||
twFirstCode.put("I", 34);
|
||||
twFirstCode.put("O", 35);
|
||||
TW_FIRST_CODE.put("A", 10);
|
||||
TW_FIRST_CODE.put("B", 11);
|
||||
TW_FIRST_CODE.put("C", 12);
|
||||
TW_FIRST_CODE.put("D", 13);
|
||||
TW_FIRST_CODE.put("E", 14);
|
||||
TW_FIRST_CODE.put("F", 15);
|
||||
TW_FIRST_CODE.put("G", 16);
|
||||
TW_FIRST_CODE.put("H", 17);
|
||||
TW_FIRST_CODE.put("J", 18);
|
||||
TW_FIRST_CODE.put("K", 19);
|
||||
TW_FIRST_CODE.put("L", 20);
|
||||
TW_FIRST_CODE.put("M", 21);
|
||||
TW_FIRST_CODE.put("N", 22);
|
||||
TW_FIRST_CODE.put("P", 23);
|
||||
TW_FIRST_CODE.put("Q", 24);
|
||||
TW_FIRST_CODE.put("R", 25);
|
||||
TW_FIRST_CODE.put("S", 26);
|
||||
TW_FIRST_CODE.put("T", 27);
|
||||
TW_FIRST_CODE.put("U", 28);
|
||||
TW_FIRST_CODE.put("V", 29);
|
||||
TW_FIRST_CODE.put("X", 30);
|
||||
TW_FIRST_CODE.put("Y", 31);
|
||||
TW_FIRST_CODE.put("W", 32);
|
||||
TW_FIRST_CODE.put("Z", 33);
|
||||
TW_FIRST_CODE.put("I", 34);
|
||||
TW_FIRST_CODE.put("O", 35);
|
||||
|
||||
//来自http://shenfenzheng.bajiu.cn/?rid=40
|
||||
hkFirstCode.put("A", 1);// 持证人拥有香港居留权
|
||||
hkFirstCode.put("B", 2);// 持证人所报称的出生日期或地点自首次登记以后,曾作出更改
|
||||
hkFirstCode.put("C", 3);// 持证人登记领证时在香港的居留受到入境事务处处长的限制
|
||||
hkFirstCode.put("N", 14);// 持证人所报的姓名自首次登记以后,曾作出更改
|
||||
hkFirstCode.put("O", 15);// 持证人报称在香港、澳门及中国以外其他地区或国家出生
|
||||
hkFirstCode.put("R", 18);// 持证人拥有香港入境权
|
||||
hkFirstCode.put("U", 21);// 持证人登记领证时在香港的居留不受入境事务处处长的限制
|
||||
hkFirstCode.put("W", 23);// 持证人报称在澳门地区出生
|
||||
hkFirstCode.put("X", 24);// 持证人报称在中国大陆出生
|
||||
hkFirstCode.put("Z", 26);// 持证人报称在香港出生
|
||||
HK_FIRST_CODE.put("A", 1);// 持证人拥有香港居留权
|
||||
HK_FIRST_CODE.put("B", 2);// 持证人所报称的出生日期或地点自首次登记以后,曾作出更改
|
||||
HK_FIRST_CODE.put("C", 3);// 持证人登记领证时在香港的居留受到入境事务处处长的限制
|
||||
HK_FIRST_CODE.put("N", 14);// 持证人所报的姓名自首次登记以后,曾作出更改
|
||||
HK_FIRST_CODE.put("O", 15);// 持证人报称在香港、澳门及中国以外其他地区或国家出生
|
||||
HK_FIRST_CODE.put("R", 18);// 持证人拥有香港入境权
|
||||
HK_FIRST_CODE.put("U", 21);// 持证人登记领证时在香港的居留不受入境事务处处长的限制
|
||||
HK_FIRST_CODE.put("W", 23);// 持证人报称在澳门地区出生
|
||||
HK_FIRST_CODE.put("X", 24);// 持证人报称在中国大陆出生
|
||||
HK_FIRST_CODE.put("Z", 26);// 持证人报称在香港出生
|
||||
}
|
||||
|
||||
/**
|
||||
@ -248,7 +248,7 @@ public class IdcardUtil {
|
||||
if (ReUtil.isMatch(PatternPool.NUMBERS, idCard)) {
|
||||
// 省份
|
||||
String proCode = idCard.substring(0, 2);
|
||||
if (null == cityCodes.get(proCode)) {
|
||||
if (null == CITY_CODES.get(proCode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -314,7 +314,7 @@ public class IdcardUtil {
|
||||
return false;
|
||||
}
|
||||
String start = idCard.substring(0, 1);
|
||||
Integer iStart = twFirstCode.get(start);
|
||||
Integer iStart = TW_FIRST_CODE.get(start);
|
||||
if (null == iStart) {
|
||||
return false;
|
||||
}
|
||||
@ -352,7 +352,7 @@ public class IdcardUtil {
|
||||
sum = 522 + (Character.toUpperCase(card.charAt(0)) - 55) * 8;
|
||||
}
|
||||
String start = idCard.substring(0, 1);
|
||||
Integer iStart = hkFirstCode.get(start);
|
||||
Integer iStart = HK_FIRST_CODE.get(start);
|
||||
if (null == iStart) {
|
||||
return false;
|
||||
}
|
||||
@ -512,7 +512,7 @@ public class IdcardUtil {
|
||||
int len = idCard.length();
|
||||
if (len == CHINA_ID_MIN_LENGTH || len == CHINA_ID_MAX_LENGTH) {
|
||||
String sProvinNum = idCard.substring(0, 2);
|
||||
return cityCodes.get(sProvinNum);
|
||||
return CITY_CODES.get(sProvinNum);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class ModifierUtil {
|
||||
STRICT(Modifier.STRICT);
|
||||
|
||||
/** 修饰符枚举对应的int修饰符值 */
|
||||
private int value;
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -569,7 +569,7 @@ public class ObjectUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存都为{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素
|
||||
* 是否全都为{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素
|
||||
*
|
||||
* @param objs 被检查的对象,一个或者多个
|
||||
* @return 是否都为空
|
||||
@ -579,7 +579,7 @@ public class ObjectUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存都不为{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素
|
||||
* 是否全都不为{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素
|
||||
*
|
||||
* @param objs 被检查的对象,一个或者多个
|
||||
* @return 是否都不为空
|
||||
|
@ -1,5 +1,8 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -7,12 +10,9 @@ import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
|
||||
/**
|
||||
* 系统运行时工具类,用于执行系统命令的工具
|
||||
*
|
||||
*
|
||||
* @author Looly
|
||||
* @since 3.1.1
|
||||
*/
|
||||
@ -20,7 +20,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 执行系统命令,使用系统默认编码
|
||||
*
|
||||
*
|
||||
* @param cmds 命令列表,每个元素代表一条命令
|
||||
* @return 执行结果
|
||||
* @throws IORuntimeException IO异常
|
||||
@ -31,9 +31,9 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 执行系统命令,使用系统默认编码
|
||||
*
|
||||
*
|
||||
* @param charset 编码
|
||||
* @param cmds 命令列表,每个元素代表一条命令
|
||||
* @param cmds 命令列表,每个元素代表一条命令
|
||||
* @return 执行结果
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.1.2
|
||||
@ -44,7 +44,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 执行系统命令,使用系统默认编码
|
||||
*
|
||||
*
|
||||
* @param cmds 命令列表,每个元素代表一条命令
|
||||
* @return 执行结果,按行区分
|
||||
* @throws IORuntimeException IO异常
|
||||
@ -55,9 +55,9 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 执行系统命令,使用系统默认编码
|
||||
*
|
||||
*
|
||||
* @param charset 编码
|
||||
* @param cmds 命令列表,每个元素代表一条命令
|
||||
* @param cmds 命令列表,每个元素代表一条命令
|
||||
* @return 执行结果,按行区分
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.1.2
|
||||
@ -69,7 +69,7 @@ public class RuntimeUtil {
|
||||
/**
|
||||
* 执行命令<br>
|
||||
* 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入
|
||||
*
|
||||
*
|
||||
* @param cmds 命令
|
||||
* @return {@link Process}
|
||||
*/
|
||||
@ -99,7 +99,7 @@ public class RuntimeUtil {
|
||||
/**
|
||||
* 执行命令<br>
|
||||
* 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入
|
||||
*
|
||||
*
|
||||
* @param envp 环境变量参数,传入形式为key=value,null表示继承系统环境变量
|
||||
* @param cmds 命令
|
||||
* @return {@link Process}
|
||||
@ -112,9 +112,9 @@ public class RuntimeUtil {
|
||||
/**
|
||||
* 执行命令<br>
|
||||
* 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入
|
||||
*
|
||||
*
|
||||
* @param envp 环境变量参数,传入形式为key=value,null表示继承系统环境变量
|
||||
* @param dir 执行命令所在目录(用于相对路径命令执行),null表示使用当前进程执行的目录
|
||||
* @param dir 执行命令所在目录(用于相对路径命令执行),null表示使用当前进程执行的目录
|
||||
* @param cmds 命令
|
||||
* @return {@link Process}
|
||||
* @since 4.1.6
|
||||
@ -140,9 +140,10 @@ public class RuntimeUtil {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------- result
|
||||
|
||||
/**
|
||||
* 获取命令执行结果,使用系统默认编码,获取后销毁进程
|
||||
*
|
||||
*
|
||||
* @param process {@link Process} 进程
|
||||
* @return 命令执行结果列表
|
||||
*/
|
||||
@ -152,7 +153,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 获取命令执行结果,使用系统默认编码,获取后销毁进程
|
||||
*
|
||||
*
|
||||
* @param process {@link Process} 进程
|
||||
* @param charset 编码
|
||||
* @return 命令执行结果列表
|
||||
@ -162,7 +163,7 @@ public class RuntimeUtil {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = process.getInputStream();
|
||||
return IoUtil.readLines(in, charset, new ArrayList<String>());
|
||||
return IoUtil.readLines(in, charset, new ArrayList<>());
|
||||
} finally {
|
||||
IoUtil.close(in);
|
||||
destroy(process);
|
||||
@ -171,7 +172,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 获取命令执行结果,使用系统默认编码,,获取后销毁进程
|
||||
*
|
||||
*
|
||||
* @param process {@link Process} 进程
|
||||
* @return 命令执行结果列表
|
||||
* @since 3.1.2
|
||||
@ -182,7 +183,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 获取命令执行结果,获取后销毁进程
|
||||
*
|
||||
*
|
||||
* @param process {@link Process} 进程
|
||||
* @param charset 编码
|
||||
* @return 命令执行结果列表
|
||||
@ -201,7 +202,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 获取命令执行异常结果,使用系统默认编码,,获取后销毁进程
|
||||
*
|
||||
*
|
||||
* @param process {@link Process} 进程
|
||||
* @return 命令执行结果列表
|
||||
* @since 4.1.21
|
||||
@ -212,7 +213,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 获取命令执行异常结果,获取后销毁进程
|
||||
*
|
||||
*
|
||||
* @param process {@link Process} 进程
|
||||
* @param charset 编码
|
||||
* @return 命令执行结果列表
|
||||
@ -231,7 +232,7 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 销毁进程
|
||||
*
|
||||
*
|
||||
* @param process 进程
|
||||
* @since 3.1.2
|
||||
*/
|
||||
@ -243,11 +244,61 @@ public class RuntimeUtil {
|
||||
|
||||
/**
|
||||
* 增加一个JVM关闭后的钩子,用于在JVM关闭时执行某些操作
|
||||
*
|
||||
*
|
||||
* @param hook 钩子
|
||||
* @since 4.0.5
|
||||
*/
|
||||
public static void addShutdownHook(Runnable hook) {
|
||||
Runtime.getRuntime().addShutdownHook((hook instanceof Thread) ? (Thread) hook : new Thread(hook));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得JVM可用的处理器数量(一般为CPU核心数)
|
||||
*
|
||||
* @return 可用的处理器数量
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public static int getProcessorCount() {
|
||||
return Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得JVM中剩余的内存数,单位byte
|
||||
*
|
||||
* @return JVM中剩余的内存数,单位byte
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public static long getFreeMemory() {
|
||||
return Runtime.getRuntime().freeMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得JVM已经从系统中获取到的总共的内存数,单位byte
|
||||
*
|
||||
* @return JVM中剩余的内存数,单位byte
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public static long getTotalMemory() {
|
||||
return Runtime.getRuntime().totalMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得JVM中可以从系统中获取的最大的内存数,单位byte,以-Xmx参数为准
|
||||
*
|
||||
* @return JVM中剩余的内存数,单位byte
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public static long getMaxMemory() {
|
||||
return Runtime.getRuntime().maxMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得JVM最大可用内存,计算方法为:<br>
|
||||
* 最大内存-总内存+剩余内存
|
||||
*
|
||||
* @return 最大可用内存
|
||||
*/
|
||||
public final long getUsableMemory() {
|
||||
return getMaxMemory() - getTotalMemory() + getFreeMemory();
|
||||
}
|
||||
}
|
||||
|
@ -59,11 +59,7 @@ public class TypeUtil {
|
||||
if (null == field) {
|
||||
return null;
|
||||
}
|
||||
Type type = field.getGenericType();
|
||||
if (null == type) {
|
||||
type = field.getType();
|
||||
}
|
||||
return type;
|
||||
return field.getGenericType();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,10 @@
|
||||
package cn.hutool.core.convert;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -7,12 +12,6 @@ import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
|
||||
/**
|
||||
* 转换为集合测试
|
||||
*
|
||||
@ -107,7 +106,7 @@ public class ConvertToCollectionTest {
|
||||
public void numberToListTest() {
|
||||
Integer i = 1;
|
||||
ArrayList<?> list = Convert.convert(ArrayList.class, i);
|
||||
Assert.assertTrue(i == list.get(0));
|
||||
Assert.assertSame(i, list.get(0));
|
||||
|
||||
BigDecimal b = BigDecimal.ONE;
|
||||
ArrayList<?> list2 = Convert.convert(ArrayList.class, b);
|
||||
|
@ -67,12 +67,12 @@ public class DateTimeTest {
|
||||
|
||||
// 默认情况下DateTime为可变对象
|
||||
DateTime offsite = dateTime.offset(DateField.YEAR, 0);
|
||||
Assert.assertTrue(offsite == dateTime);
|
||||
Assert.assertSame(offsite, dateTime);
|
||||
|
||||
// 设置为不可变对象后变动将返回新对象
|
||||
dateTime.setMutable(false);
|
||||
offsite = dateTime.offset(DateField.YEAR, 0);
|
||||
Assert.assertFalse(offsite == dateTime);
|
||||
Assert.assertNotSame(offsite, dateTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -86,6 +86,7 @@ public class DateTimeTest {
|
||||
|
||||
@Test
|
||||
public void monthTest() {
|
||||
//noinspection ConstantConditions
|
||||
int month = DateUtil.parse("2017-07-01").month();
|
||||
Assert.assertEquals(6, month);
|
||||
}
|
||||
@ -93,6 +94,7 @@ public class DateTimeTest {
|
||||
@Test
|
||||
public void weekOfYearTest() {
|
||||
DateTime date = DateUtil.parse("2016-12-27");
|
||||
//noinspection ConstantConditions
|
||||
Assert.assertEquals(2016, date.year());
|
||||
//跨年的周返回的总是1
|
||||
Assert.assertEquals(1, date.weekOfYear());
|
||||
|
@ -1,5 +1,10 @@
|
||||
package cn.hutool.core.img;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Image;
|
||||
@ -7,14 +12,6 @@ import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
|
||||
public class ImgUtilTest {
|
||||
|
||||
@Test
|
||||
|
@ -1,12 +1,10 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Range;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* {@link Range} 单元测试
|
||||
@ -20,16 +18,11 @@ public class RangeTest {
|
||||
DateTime start = DateUtil.parse("2017-01-01");
|
||||
DateTime end = DateUtil.parse("2017-01-02");
|
||||
|
||||
final Range<DateTime> range = new Range<DateTime>(start, end, new Range.Steper<DateTime>(){
|
||||
|
||||
@Override
|
||||
public DateTime step(DateTime current, DateTime end, int index) {
|
||||
if(current.isAfterOrEquals(end)) {
|
||||
return null;
|
||||
}
|
||||
return current.offsetNew(DateField.DAY_OF_YEAR, 1);
|
||||
final Range<DateTime> range = new Range<>(start, end, (current, end1, index) -> {
|
||||
if (current.isAfterOrEquals(end1)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return current.offsetNew(DateField.DAY_OF_YEAR, 1);
|
||||
});
|
||||
|
||||
Assert.assertTrue(range.hasNext());
|
||||
@ -41,14 +34,7 @@ public class RangeTest {
|
||||
|
||||
@Test
|
||||
public void intRangeTest() {
|
||||
final Range<Integer> range = new Range<Integer>(1, 1, new Range.Steper<Integer>(){
|
||||
|
||||
@Override
|
||||
public Integer step(Integer current, Integer end, int index) {
|
||||
return current >= end ? null : current +10;
|
||||
}
|
||||
|
||||
});
|
||||
final Range<Integer> range = new Range<>(1, 1, (current, end, index) -> current >= end ? null : current + 10);
|
||||
|
||||
Assert.assertTrue(range.hasNext());
|
||||
Assert.assertEquals(Integer.valueOf(1), range.next());
|
||||
|
@ -0,0 +1,30 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import lombok.Data;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SingletonTest {
|
||||
|
||||
@Test
|
||||
public void getTest(){
|
||||
// 此测试中使用1000个线程获取单例对象,其间对象只被创建一次
|
||||
ThreadUtil.concurrencyTest(1000, ()-> Singleton.get(TestBean.class));
|
||||
}
|
||||
|
||||
@Data
|
||||
static class TestBean{
|
||||
private static volatile TestBean testSingleton;
|
||||
|
||||
public TestBean(){
|
||||
if(null != testSingleton){
|
||||
throw new UtilException("单例测试中,对象被创建了两次!");
|
||||
}
|
||||
testSingleton = this;
|
||||
}
|
||||
|
||||
private String name;
|
||||
private String age;
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package cn.hutool.core.math;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 组合单元测试
|
||||
*
|
||||
@ -49,6 +49,6 @@ public class CombinationTest {
|
||||
Assert.assertEquals(Combination.countAll(5), selectAll.size());
|
||||
|
||||
List<String[]> list2 = combination.select(0);
|
||||
Assert.assertTrue(1 == list2.size());
|
||||
Assert.assertEquals(1, list2.size());
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +1,27 @@
|
||||
package cn.hutool.core.swing;
|
||||
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.swing.clipboard.ClipboardUtil;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.swing.clipboard.ClipboardListener;
|
||||
import cn.hutool.core.swing.clipboard.ClipboardUtil;
|
||||
|
||||
public class ClipboardMonitorTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void monitorTest() {
|
||||
// 第一个监听
|
||||
ClipboardUtil.listen(new ClipboardListener() {
|
||||
|
||||
@Override
|
||||
public Transferable onChange(Clipboard clipboard, Transferable contents) {
|
||||
Object object = ClipboardUtil.getStr(contents);
|
||||
Console.log("1# {}", object);
|
||||
return contents;
|
||||
}
|
||||
|
||||
ClipboardUtil.listen((clipboard, contents) -> {
|
||||
Object object = ClipboardUtil.getStr(contents);
|
||||
Console.log("1# {}", object);
|
||||
return contents;
|
||||
}, false);
|
||||
|
||||
// 第二个监听
|
||||
ClipboardUtil.listen(new ClipboardListener() {
|
||||
|
||||
@Override
|
||||
public Transferable onChange(Clipboard clipboard, Transferable contents) {
|
||||
Object object = ClipboardUtil.getStr(contents);
|
||||
Console.log("2# {}", object);
|
||||
return contents;
|
||||
}
|
||||
|
||||
ClipboardUtil.listen((clipboard, contents) -> {
|
||||
Object object = ClipboardUtil.getStr(contents);
|
||||
Console.log("2# {}", object);
|
||||
return contents;
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
package cn.hutool.core.text.csv;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
public class CsvParserTest {
|
||||
|
||||
@ -15,6 +14,7 @@ public class CsvParserTest {
|
||||
StringReader reader = StrUtil.getReader("aaa,b\"bba\",ccc");
|
||||
CsvParser parser = new CsvParser(reader, null);
|
||||
CsvRow row = parser.nextRow();
|
||||
//noinspection ConstantConditions
|
||||
Assert.assertEquals("b\"bba\"", row.getRawList().get(1));
|
||||
IoUtil.close(parser);
|
||||
}
|
||||
@ -24,6 +24,7 @@ public class CsvParserTest {
|
||||
StringReader reader = StrUtil.getReader("aaa,\"bba\"bbb,ccc");
|
||||
CsvParser parser = new CsvParser(reader, null);
|
||||
CsvRow row = parser.nextRow();
|
||||
//noinspection ConstantConditions
|
||||
Assert.assertEquals("\"bba\"bbb", row.getRawList().get(1));
|
||||
IoUtil.close(parser);
|
||||
}
|
||||
@ -33,6 +34,7 @@ public class CsvParserTest {
|
||||
StringReader reader = StrUtil.getReader("aaa,\"bba\",ccc");
|
||||
CsvParser parser = new CsvParser(reader, null);
|
||||
CsvRow row = parser.nextRow();
|
||||
//noinspection ConstantConditions
|
||||
Assert.assertEquals("bba", row.getRawList().get(1));
|
||||
IoUtil.close(parser);
|
||||
}
|
||||
@ -42,6 +44,7 @@ public class CsvParserTest {
|
||||
StringReader reader = StrUtil.getReader("aaa,\"\",ccc");
|
||||
CsvParser parser = new CsvParser(reader, null);
|
||||
CsvRow row = parser.nextRow();
|
||||
//noinspection ConstantConditions
|
||||
Assert.assertEquals("", row.getRawList().get(1));
|
||||
IoUtil.close(parser);
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ public class CsvUtilTest {
|
||||
@Test
|
||||
public void readTest2() {
|
||||
CsvReader reader = CsvUtil.getReader();
|
||||
reader.read(FileUtil.getUtf8Reader("test.csv"), (csvRow)->{
|
||||
Assert.notEmpty(csvRow.getRawList());
|
||||
});
|
||||
reader.read(FileUtil.getUtf8Reader("test.csv"), (csvRow)-> Assert.notEmpty(csvRow.getRawList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -11,14 +11,10 @@ public class ConcurrencyTesterTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void concurrencyTesterTest() {
|
||||
ConcurrencyTester tester = ThreadUtil.concurrencyTest(100, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long delay = RandomUtil.randomLong(100, 1000);
|
||||
ThreadUtil.sleep(delay);
|
||||
Console.log("{} test finished, delay: {}", Thread.currentThread().getName(), delay);
|
||||
}
|
||||
ConcurrencyTester tester = ThreadUtil.concurrencyTest(100, () -> {
|
||||
long delay = RandomUtil.randomLong(100, 1000);
|
||||
ThreadUtil.sleep(delay);
|
||||
Console.log("{} test finished, delay: {}", Thread.currentThread().getName(), delay);
|
||||
});
|
||||
Console.log(tester.getInterval());
|
||||
}
|
||||
|
@ -9,13 +9,7 @@ public class ThreadUtilTest {
|
||||
public void executeTest() {
|
||||
final boolean isValid = true;
|
||||
|
||||
ThreadUtil.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Assert.assertTrue(isValid);
|
||||
}
|
||||
});
|
||||
ThreadUtil.execute(() -> Assert.assertTrue(isValid));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* EnumUtil单元测试
|
||||
@ -49,17 +48,18 @@ public class EnumUtilTest {
|
||||
@Test
|
||||
public void getNameFieldMapTest() {
|
||||
Map<String, Object> enumMap = EnumUtil.getNameFieldMap(TestEnum.class, "type");
|
||||
assert enumMap != null;
|
||||
Assert.assertEquals("type1", enumMap.get("TEST1"));
|
||||
}
|
||||
|
||||
public enum TestEnum{
|
||||
TEST1("type1"), TEST2("type2"), TEST3("type3");
|
||||
|
||||
|
||||
TestEnum(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private String type;
|
||||
|
||||
private final String type;
|
||||
private String name;
|
||||
|
||||
public String getType() {
|
||||
|
@ -1,13 +1,5 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.collection.ConcurrentHashSet;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
@ -15,6 +7,13 @@ import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.lang.Snowflake;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* {@link IdUtil} 单元测试
|
||||
@ -56,6 +55,7 @@ public class IdUtilTest {
|
||||
|
||||
timer.restart();
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
Console.log(timer.interval());
|
||||
@ -85,17 +85,13 @@ public class IdUtilTest {
|
||||
final int idCountPerThread = 10000;
|
||||
final CountDownLatch latch = new CountDownLatch(threadCount);
|
||||
for(int i =0; i < threadCount; i++) {
|
||||
ThreadUtil.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for(int i =0; i < idCountPerThread; i++) {
|
||||
long id = snowflake.nextId();
|
||||
set.add(id);
|
||||
ThreadUtil.execute(() -> {
|
||||
for(int i1 = 0; i1 < idCountPerThread; i1++) {
|
||||
long id = snowflake.nextId();
|
||||
set.add(id);
|
||||
// Console.log("Add new id: {}", id);
|
||||
}
|
||||
latch.countDown();
|
||||
}
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
|
||||
@ -118,17 +114,13 @@ public class IdUtilTest {
|
||||
final int idCountPerThread = 10000;
|
||||
final CountDownLatch latch = new CountDownLatch(threadCount);
|
||||
for(int i =0; i < threadCount; i++) {
|
||||
ThreadUtil.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for(int i =0; i < idCountPerThread; i++) {
|
||||
long id = IdUtil.getSnowflake(1, 1).nextId();
|
||||
set.add(id);
|
||||
ThreadUtil.execute(() -> {
|
||||
for(int i1 = 0; i1 < idCountPerThread; i1++) {
|
||||
long id = IdUtil.getSnowflake(1, 1).nextId();
|
||||
set.add(id);
|
||||
// Console.log("Add new id: {}", id);
|
||||
}
|
||||
latch.countDown();
|
||||
}
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user