This commit is contained in:
Looly 2020-04-11 13:08:46 +08:00
parent 73fd3b849f
commit bc486cdac4
207 changed files with 1329 additions and 1355 deletions

View File

@ -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重启报错问题

View File

@ -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) {

View File

@ -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;
/**
* 构造

View File

@ -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);
}

View File

@ -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;
/**
* 构造

View File

@ -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;
/**
* 构造

View File

@ -24,7 +24,7 @@ public enum GlobalPruneTimer {
/**
* 缓存任务计数
*/
private AtomicInteger cacheTaskNumber = new AtomicInteger(1);
private final AtomicInteger cacheTaskNumber = new AtomicInteger(1);
/**
* 定时器

View File

@ -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

View File

@ -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

View File

@ -16,7 +16,7 @@ public class MathGenerator implements CodeGenerator {
private static final String operators = "+-*";
/** 参与计算数字最大长度 */
private int numberLength;
private final int numberLength;
/**
* 构造

View File

@ -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);

View File

@ -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());

View File

@ -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}

View File

@ -16,7 +16,7 @@ import java.util.Map;
*/
public class MapValueProvider implements ValueProvider<String> {
private Map<?, ?> map;
private final Map<?, ?> map;
/**
* 构造

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
/**
* 构造

View File

@ -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() {

View File

@ -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));
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
/**
* 构造

View File

@ -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;
/**
* 构造

View File

@ -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);
}

View File

@ -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>

View File

@ -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;
/**
* 构造

View File

@ -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;
/**
* 日期格式化
*/

View File

@ -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>

View File

@ -103,7 +103,7 @@ public enum DateField {
MILLISECOND(Calendar.MILLISECOND);
// ---------------------------------------------------------------
private int value;
private final int value;
DateField(int value) {
this.value = value;

View File

@ -19,7 +19,7 @@ public enum DateUnit {
/**一周的毫秒数 */
WEEK(DAY.getMillis() * 7);
private long millis;
private final long millis;
DateUnit(long millis){
this.millis = millis;
}

View File

@ -53,7 +53,7 @@ public enum Month {
UNDECIMBER(Calendar.UNDECIMBER);
// ---------------------------------------------------------------
private int value;
private final int value;
Month(int value) {
this.value = value;

View File

@ -23,7 +23,7 @@ public enum Quarter {
Q4(4);
// ---------------------------------------------------------------
private int value;
private final int value;
Quarter(int value) {
this.value = value;

View File

@ -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();

View File

@ -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;
/**
* 构造默认使用毫秒计数

View File

@ -36,7 +36,7 @@ public enum Week {
// ---------------------------------------------------------------
/** 星期对应{@link Calendar} 中的Week值 */
private int value;
private final int value;
/**
* 构造

View File

@ -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;) {

View File

@ -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;
/**
* 目标图片文件格式用于写出

View File

@ -35,7 +35,7 @@ public enum ScaleType {
this.value = value;
}
private int value;
private final int value;
public int getValue() {
return this.value;

View File

@ -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文件扩展名

View File

@ -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);
/**
* 构造

View File

@ -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;
/**
* 构造

View File

@ -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;

View File

@ -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编码

View File

@ -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;
/**
* 构造

View File

@ -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;
/**

View File

@ -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编码

View File

@ -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);
}

View File

@ -45,7 +45,7 @@ public enum WatchKind {
DELETE.getValue() //删除
};
private WatchEvent.Kind<?> value;
private final WatchEvent.Kind<?> value;
/**
* 构造

View File

@ -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>

View File

@ -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;

View File

@ -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;
/**
* 构造

View File

@ -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;
/**
* 构造

View File

@ -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;

View File

@ -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 移除的值
*/

View File

@ -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) {

View File

@ -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;
/**
* 构造

View File

@ -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 identifierUUID实现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

View File

@ -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;
/**
* 构造

View File

@ -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() {

View File

@ -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实现

View File

@ -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;

View File

@ -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;

View File

@ -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();
}
}

View File

@ -77,7 +77,7 @@ public class Money implements Serializable, Comparable<Money> {
/**
* 币种
*/
private Currency currency;
private final Currency currency;
// 构造器 ====================================================

View File

@ -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
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -43,7 +43,7 @@ public class UnicodeUtil {
pos = i + 2;
}
} else {
pos = i;//非Unicode符结束
//非Unicode符结束
break;
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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<>();
/**
* 构造

View File

@ -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) {

View File

@ -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;

View File

@ -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;
/**
* 构造

View File

@ -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;

View File

@ -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}

View File

@ -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");
}
}

View File

@ -7,23 +7,24 @@ import cn.hutool.core.lang.UUID;
/**
* ID生成器工具类此工具类中主要封装
*
*
* <pre>
* 1. 唯一性ID生成器UUIDObjectIdMongoDBSnowflake
* </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

View File

@ -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;
}

View File

@ -45,7 +45,7 @@ public class ModifierUtil {
STRICT(Modifier.STRICT);
/** 修饰符枚举对应的int修饰符值 */
private int value;
private final int value;
/**
* 构造

View File

@ -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 是否都不为空

View File

@ -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=valuenull表示继承系统环境变量
* @param cmds 命令
* @return {@link Process}
@ -112,9 +112,9 @@ public class RuntimeUtil {
/**
* 执行命令<br>
* 命令带参数时参数可作为其中一个参数也可以将命令和参数组合为一个字符串传入
*
*
* @param envp 环境变量参数传入形式为key=valuenull表示继承系统环境变量
* @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();
}
}

View File

@ -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();
}
/**

View File

@ -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);

View File

@ -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());

View File

@ -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

View File

@ -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());

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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;
});
}

View File

@ -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);
}

View File

@ -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

View File

@ -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());
}

View File

@ -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));
}
}

View File

@ -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() {

View File

@ -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