Merge remote-tracking branch 'upstream/v5-dev' into v5-dev

This commit is contained in:
totalo
2021-03-10 14:53:49 +08:00
201 changed files with 1959 additions and 1047 deletions

View File

@@ -43,7 +43,7 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa
/**
* 构造
*
*
* @param element 需要解析注解的元素可以是Class、Method、Field、Constructor、ReflectPermission
*/
public CombinationAnnotationElement(AnnotatedElement element) {
@@ -73,17 +73,17 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa
final Collection<Annotation> annotations = this.declaredAnnotationMap.values();
return annotations.toArray(new Annotation[0]);
}
/**
* 初始化
*
*
* @param element 元素
*/
private void init(AnnotatedElement element) {
final Annotation[] declaredAnnotations = element.getDeclaredAnnotations();
this.declaredAnnotationMap = new HashMap<>();
parseDeclared(declaredAnnotations);
final Annotation[] annotations = element.getAnnotations();
if(Arrays.equals(declaredAnnotations, annotations)) {
this.annotationMap = this.declaredAnnotationMap;
@@ -109,7 +109,7 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa
}
}
}
/**
* 进行递归解析注解,直到全部都是元注解为止
*

View File

@@ -1,6 +1,6 @@
/**
* 注解包,提供增强型注解和注解工具类
*
*
* @author looly
*
*/

View File

@@ -11,9 +11,9 @@ import cn.hutool.core.lang.func.Func0;
*/
public enum BeanDescCache {
INSTANCE;
private final SimpleCache<Class<?>, BeanDesc> bdCache = new SimpleCache<>();
/**
* 获得属性名和{@link BeanDesc}Map映射
* @param beanClass Bean的类

View File

@@ -13,19 +13,19 @@ public class BeanException extends RuntimeException{
public BeanException(Throwable e) {
super(ExceptionUtil.getMessage(e), e);
}
public BeanException(String message) {
super(message);
}
public BeanException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public BeanException(String message, Throwable throwable) {
super(message, throwable);
}
public BeanException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}

View File

@@ -23,9 +23,9 @@ import java.util.Map;
* <li>.表达式可以获取Bean对象中的属性字段值或者Map中key对应的值</li>
* <li>[]表达式可以获取集合等对象中对应index的值</li>
* </ol>
*
*
* 表达式栗子:
*
*
* <pre>
* persion
* persion.name
@@ -33,7 +33,7 @@ import java.util.Map;
* person.friends[5].name
* ['person']['friends'][5]['name']
* </pre>
*
*
* @author Looly
* @since 4.0.6
*/
@@ -54,9 +54,9 @@ public class BeanPath implements Serializable{
* <li>.表达式可以获取Bean对象中的属性字段值或者Map中key对应的值</li>
* <li>[]表达式可以获取集合等对象中对应index的值</li>
* </ol>
*
*
* 表达式栗子:
*
*
* <pre>
* persion
* persion.name
@@ -64,7 +64,7 @@ public class BeanPath implements Serializable{
* person.friends[5].name
* ['person']['friends'][5]['name']
* </pre>
*
*
* @param expression 表达式
* @return BeanPath
*/
@@ -74,7 +74,7 @@ public class BeanPath implements Serializable{
/**
* 构造
*
*
* @param expression 表达式
*/
public BeanPath(String expression) {
@@ -83,7 +83,7 @@ public class BeanPath implements Serializable{
/**
* 获取Bean中对应表达式的值
*
*
* @param bean Bean对象或Map或List等
* @return 值如果对应值不存在则返回null
*/
@@ -95,29 +95,29 @@ public class BeanPath implements Serializable{
* 设置表达式指定位置或filed对应的值<br>
* 若表达式指向一个List则设置其坐标对应位置的值若指向Map则put对应key的值Bean则设置字段的值<br>
* 注意:
*
*
* <pre>
* 1. 如果为List如果下标不大于List长度则替换原有值否则追加值
* 2. 如果为数组,如果下标不大于数组长度,则替换原有值,否则追加值
* </pre>
*
*
* @param bean Bean、Map或List
* @param value 值
*/
public void set(Object bean, Object value) {
set(bean, this.patternParts, value);
}
/**
* 设置表达式指定位置或filed对应的值<br>
* 若表达式指向一个List则设置其坐标对应位置的值若指向Map则put对应key的值Bean则设置字段的值<br>
* 注意:
*
*
* <pre>
* 1. 如果为List如果下标不大于List长度则替换原有值否则追加值
* 2. 如果为数组,如果下标不大于数组长度,则替换原有值,否则追加值
* </pre>
*
*
* @param bean Bean、Map或List
* @param patternParts 表达式块列表
* @param value 值
@@ -135,7 +135,7 @@ public class BeanPath implements Serializable{
// ------------------------------------------------------------------------------------------------------------------------------------- Private method start
/**
* 获取Bean中对应表达式的值
*
*
* @param patternParts 表达式分段列表
* @param bean Bean对象或Map或List等
* @param ignoreLast 是否忽略最后一个值忽略最后一个值则用于set否则用于read
@@ -215,7 +215,7 @@ public class BeanPath implements Serializable{
/**
* 初始化
*
*
* @param expression 表达式
*/
private void init(String expression) {
@@ -277,7 +277,7 @@ public class BeanPath implements Serializable{
/**
* 对于非表达式去除单引号
*
*
* @param expression 表达式
* @return 表达式
*/

View File

@@ -25,7 +25,7 @@ import java.util.Map;
* 3. Map 转 Bean
* 4. Map 转 Map
* </pre>
*
*
* @author looly
*
* @param <T> 目标对象类型
@@ -33,7 +33,7 @@ import java.util.Map;
*/
public class BeanCopier<T> implements Copier<T>, Serializable {
private static final long serialVersionUID = 1L;
/** 源对象 */
private final Object source;
/** 目标对象 */
@@ -45,7 +45,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* 创建BeanCopier
*
*
* @param <T> 目标Bean类型
* @param source 来源对象可以是Bean或者Map
* @param dest 目标Bean对象
@@ -58,7 +58,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* 创建BeanCopier
*
*
* @param <T> 目标Bean类型
* @param source 来源对象可以是Bean或者Map
* @param dest 目标Bean对象
@@ -72,7 +72,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* 构造
*
*
* @param source 来源对象可以是Bean或者Map
* @param dest 目标Bean对象
* @param destType 目标的泛型类型用于标注有泛型参数的Bean对象
@@ -115,7 +115,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* Bean和Bean之间属性拷贝
*
*
* @param providerBean 来源Bean
* @param destBean 目标Bean
*/
@@ -125,7 +125,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* Map转Bean属性拷贝
*
*
* @param map Map
* @param bean Bean
*/
@@ -138,7 +138,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* Map转Map
*
*
* @param source 源Map
* @param dest 目标Map
*/
@@ -151,7 +151,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* 对象转Map
*
*
* @param bean bean对象
* @param targetMap 目标的Map
* @since 4.1.22
@@ -201,7 +201,7 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
/**
* 值提供器转Bean<br>
* 此方法通过遍历目标Bean的字段从ValueProvider查找对应值
*
*
* @param valueProvider 值提供器
* @param bean Bean
*/

View File

@@ -6,17 +6,17 @@ import java.lang.reflect.Type;
* 值提供者用于提供Bean注入时参数对应值得抽象接口<br>
* 继承或匿名实例化此接口<br>
* 在Bean注入过程中Bean获得字段名通过外部方式根据这个字段名查找相应的字段值然后注入Bean<br>
*
*
* @author Looly
* @param <T> KEY类型一般情况下为 {@link String}
*
*/
public interface ValueProvider<T>{
/**
* 获取值<br>
* 返回值一般需要匹配被注入类型,如果不匹配会调用默认转换 Convert#convert(Type, Object)实现转换
*
*
* @param key Bean对象中参数名
* @param valueType 被注入的值的类型
* @return 对应参数名的值
@@ -26,7 +26,7 @@ public interface ValueProvider<T>{
/**
* 是否包含指定KEY如果不包含则忽略注入<br>
* 此接口方法单独需要实现的意义在于有些值提供者比如Mapkey是存在的但是value为null此时如果需要注入这个null需要根据此方法判断
*
*
* @param key Bean对象中参数名
* @return 是否包含指定KEY
*/

View File

@@ -1,6 +1,6 @@
/**
* Bean拷贝实现包括拷贝选项等
*
*
* @author looly
*
*/

View File

@@ -1,6 +1,6 @@
/**
* Bean值提供者方式封装
*
*
* @author looly
*
*/

View File

@@ -1,6 +1,6 @@
/**
* Bean相关操作包括Bean信息描述Bean路径表达式、动态Bean、Bean工具等
*
*
* @author looly
*
*/

View File

@@ -4,7 +4,7 @@ import java.io.Serializable;
/**
* 建造者模式接口定义
*
*
* @param <T> 建造对象类型
* @author Looly
* @since 4.2.2
@@ -12,7 +12,7 @@ import java.io.Serializable;
public interface Builder<T> extends Serializable{
/**
* 构建
*
*
* @return 被构建的对象
*/
T build();

View File

@@ -8,7 +8,7 @@ import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Comparator;
/**
/**
* 用于构建 {@link java.lang.Comparable#compareTo(Object)} 方法的辅助工具
*
* <p>
@@ -33,7 +33,7 @@ import java.util.Comparator;
* }
* }
* </pre>
*
*
* 字段值按照顺序比较如果某个字段返回非0结果比较终止使用{@code toComparison()}返回结果,后续比较忽略。
*
* <p>
@@ -52,7 +52,7 @@ import java.util.Comparator;
*/
public class CompareToBuilder implements Builder<Integer> {
private static final long serialVersionUID = 1L;
/** 当前比较状态 */
private int comparison;
@@ -60,12 +60,11 @@ public class CompareToBuilder implements Builder<Integer> {
* 构造构造后调用append方法增加比较项然后调用{@link #toComparison()}获取结果
*/
public CompareToBuilder() {
super();
comparison = 0;
}
//-----------------------------------------------------------------------
/**
/**
* 通过反射比较两个Bean对象对象字段可以为private。比较规则如下
*
* <ul>
@@ -94,7 +93,7 @@ public class CompareToBuilder implements Builder<Integer> {
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
@@ -126,7 +125,7 @@ public class CompareToBuilder implements Builder<Integer> {
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
@@ -159,7 +158,7 @@ public class CompareToBuilder implements Builder<Integer> {
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
@@ -192,7 +191,7 @@ public class CompareToBuilder implements Builder<Integer> {
* <p>Compares two <code>Object</code>s via reflection.</p>
*
* <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
* is used to bypass normal access control checks. This will fail under a
* is used to bypass normal access control checks. This will fail under a
* security manager unless the appropriate permissions are set.</p>
*
* <ul>
@@ -221,10 +220,10 @@ public class CompareToBuilder implements Builder<Integer> {
* @since 2.2 (2.0 as <code>reflectionCompare(Object, Object, boolean, Class)</code>)
*/
public static int reflectionCompare(
final Object lhs,
final Object rhs,
final boolean compareTransients,
final Class<?> reflectUpToClass,
final Object lhs,
final Object rhs,
final boolean compareTransients,
final Class<?> reflectUpToClass,
final String... excludeFields) {
if (lhs == rhs) {
@@ -249,7 +248,7 @@ public class CompareToBuilder implements Builder<Integer> {
/**
* <p>Appends to <code>builder</code> the comparison of <code>lhs</code>
* to <code>rhs</code> using the fields defined in <code>clazz</code>.</p>
*
*
* @param lhs left-hand object
* @param rhs right-hand object
* @param clazz <code>Class</code> that defines fields to be compared
@@ -264,7 +263,7 @@ public class CompareToBuilder implements Builder<Integer> {
final CompareToBuilder builder,
final boolean useTransients,
final String[] excludeFields) {
final Field[] fields = clazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
@@ -300,7 +299,7 @@ public class CompareToBuilder implements Builder<Integer> {
comparison = superCompareTo;
return this;
}
//-----------------------------------------------------------------------
/**
* <p>Appends to the <code>builder</code> the comparison of
@@ -312,7 +311,7 @@ public class CompareToBuilder implements Builder<Integer> {
* a <code>null</code> object is less than a non-<code>null</code> object</li>
* <li>Check the object contents</li>
* </ol>
*
*
* <p><code>lhs</code> must either be an array or implement {@link Comparable}.</p>
*
* @param lhs left-hand object
@@ -441,7 +440,7 @@ public class CompareToBuilder implements Builder<Integer> {
/**
* Appends to the <code>builder</code> the comparison of
* two <code>short</code>s.
*
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
@@ -473,7 +472,7 @@ public class CompareToBuilder implements Builder<Integer> {
/**
* Appends to the <code>builder</code> the comparison of
* two <code>byte</code>s.
*
*
* @param lhs left-hand value
* @param rhs right-hand value
* @return this - used to chain append calls
@@ -575,7 +574,7 @@ public class CompareToBuilder implements Builder<Integer> {
public CompareToBuilder append(final Object[] lhs, final Object[] rhs) {
return append(lhs, rhs, null);
}
/**
* <p>Appends to the <code>builder</code> the deep comparison of
* two <code>Object</code> arrays.</p>
@@ -950,7 +949,7 @@ public class CompareToBuilder implements Builder<Integer> {
* the <code>builder</code> has judged the "left-hand" side
* as less than, greater than, or equal to the "right-hand"
* side.
*
*
* @return final comparison result
* @see #build()
*/
@@ -963,7 +962,7 @@ public class CompareToBuilder implements Builder<Integer> {
* the <code>builder</code> has judged the "left-hand" side
* as less than, greater than, or equal to the "right-hand"
* side.
*
*
* @return final comparison result as an Integer
* @see #toComparison()
* @since 3.0

View File

@@ -85,17 +85,17 @@ import cn.hutool.core.util.ArrayUtil;
*/
public class HashCodeBuilder implements Builder<Integer> {
private static final long serialVersionUID = 1L;
/**
* The default initial value to use in reflection hash code building.
*/
private static final int DEFAULT_INITIAL_VALUE = 17;
/**
* The default multipler value to use in reflection hash code building.
*/
private static final int DEFAULT_MULTIPLIER_VALUE = 37;
/**
* <p>
* A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops.
@@ -103,7 +103,7 @@ public class HashCodeBuilder implements Builder<Integer> {
*
* @since 2.3
*/
private static final ThreadLocal<Set<IDKey>> REGISTRY = new ThreadLocal<Set<IDKey>>();
private static final ThreadLocal<Set<IDKey>> REGISTRY = new ThreadLocal<>();
/*
* NOTE: we cannot store the actual objects in a HashSet, as that would use the very hashCode()
@@ -380,7 +380,7 @@ public class HashCodeBuilder implements Builder<Integer> {
* if the object is <code>null</code>
*/
public static int reflectionHashCode(final Object object, final boolean testTransients) {
return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object,
return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object,
testTransients, null);
}
@@ -457,7 +457,7 @@ public class HashCodeBuilder implements Builder<Integer> {
* if the object is <code>null</code>
*/
public static int reflectionHashCode(final Object object, final String... excludeFields) {
return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, false,
return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, false,
null, excludeFields);
}

View File

@@ -13,13 +13,13 @@ import java.io.Serializable;
*/
final class IDKey implements Serializable{
private static final long serialVersionUID = 1L;
private final Object value;
private final int id;
/**
* 构造
*
*
* @param obj 计算唯一ID的对象
*/
public IDKey(final Object obj) {
@@ -32,7 +32,7 @@ final class IDKey implements Serializable{
/**
* returns hashcode - i.e. the system identity hashcode.
*
*
* @return the hashcode
*/
@Override
@@ -42,7 +42,7 @@ final class IDKey implements Serializable{
/**
* checks if instances are equal
*
*
* @param other The other object to compare to
* @return if the instances are for the same object
*/

View File

@@ -1,7 +1,7 @@
/**
* 建造者工具<br>
* 用于建造特定对象或结果
*
*
* @author looly
*
*/

View File

@@ -13,19 +13,19 @@ public class CloneRuntimeException extends RuntimeException{
public CloneRuntimeException(Throwable e) {
super(ExceptionUtil.getMessage(e), e);
}
public CloneRuntimeException(String message) {
super(message);
}
public CloneRuntimeException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public CloneRuntimeException(String message, Throwable throwable) {
super(message, throwable);
}
public CloneRuntimeException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}

View File

@@ -7,7 +7,7 @@ package cn.hutool.core.clone;
* @param <T> 继承类的类型
*/
public class CloneSupport<T> implements Cloneable<T>{
@SuppressWarnings("unchecked")
@Override
public T clone() {
@@ -17,5 +17,5 @@ public class CloneSupport<T> implements Cloneable<T>{
throw new CloneRuntimeException(e);
}
}
}

View File

@@ -7,7 +7,7 @@ package cn.hutool.core.clone;
* @param <T> 实现克隆接口的类型
*/
public interface Cloneable<T> extends java.lang.Cloneable{
/**
* 克隆当前对象,浅复制
* @return 克隆后的对象

View File

@@ -1,6 +1,6 @@
/**
* 克隆封装
*
*
* @author looly
*
*/

View File

@@ -10,7 +10,7 @@ import cn.hutool.core.lang.Assert;
*
*/
public class BCD {
/**
* 字符串转BCD码
* @param asc ASCII字符串
@@ -53,7 +53,7 @@ public class BCD {
}
return bbt;
}
/**
* ASCII转BCD
* @param ascii ASCII byte数组
@@ -100,8 +100,8 @@ public class BCD {
}
return new String(temp);
}
//----------------------------------------------------------------- Private method start
/**
* 转换单个byte为BCD

View File

@@ -14,7 +14,7 @@ import cn.hutool.core.util.StrUtil;
*
*/
public class Base32 {
private Base32() {}
private static final String BASE32_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
@@ -73,10 +73,10 @@ public class Base32 {
return base32.toString();
}
/**
* base32编码
*
*
* @param source 被编码的base32字符串
* @return 被加密后的字符串
*/
@@ -86,7 +86,7 @@ public class Base32 {
/**
* base32编码
*
*
* @param source 被编码的base32字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -97,7 +97,7 @@ public class Base32 {
/**
* base32编码
*
*
* @param source 被编码的base32字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -155,10 +155,10 @@ public class Base32 {
}
return bytes;
}
/**
* base32解码
*
*
* @param source 被解码的base32字符串
* @return 被加密后的字符串
*/
@@ -168,7 +168,7 @@ public class Base32 {
/**
* base32解码
*
*
* @param source 被解码的base32字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -176,10 +176,10 @@ public class Base32 {
public static String decodeStr(String source, String charset) {
return StrUtil.str(decode(source), charset);
}
/**
* base32解码
*
*
* @param source 被解码的base32字符串
* @param charset 字符集
* @return 被加密后的字符串

View File

@@ -12,7 +12,7 @@ import cn.hutool.core.util.StrUtil;
/**
* Base62工具类提供Base62的编码和解码方案<br>
*
*
* @author Looly
* @since 4.5.9
*/
@@ -24,7 +24,7 @@ public class Base62 {
// -------------------------------------------------------------------- encode
/**
* Base62编码
*
*
* @param source 被编码的Base62字符串
* @return 被加密后的字符串
*/
@@ -34,7 +34,7 @@ public class Base62 {
/**
* Base62编码
*
*
* @param source 被编码的Base62字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -45,7 +45,7 @@ public class Base62 {
/**
* Base62编码
*
*
* @param source 被编码的Base62字符串
* @return 被加密后的字符串
*/
@@ -55,7 +55,7 @@ public class Base62 {
/**
* Base62编码
*
*
* @param in 被编码Base62的流一般为图片流或者文件流
* @return 被加密后的字符串
*/
@@ -65,7 +65,7 @@ public class Base62 {
/**
* Base62编码
*
*
* @param file 被编码Base62的文件
* @return 被加密后的字符串
*/
@@ -76,7 +76,7 @@ public class Base62 {
// -------------------------------------------------------------------- decode
/**
* Base62解码
*
*
* @param source 被解码的Base62字符串
* @return 被加密后的字符串
*/
@@ -86,7 +86,7 @@ public class Base62 {
/**
* Base62解码
*
*
* @param source 被解码的Base62字符串
* @return 被加密后的字符串
*/
@@ -96,7 +96,7 @@ public class Base62 {
/**
* Base62解码
*
*
* @param source 被解码的Base62字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -107,7 +107,7 @@ public class Base62 {
/**
* Base62解码
*
*
* @param Base62 被解码的Base62字符串
* @param destFile 目标文件
* @return 目标文件
@@ -118,7 +118,7 @@ public class Base62 {
/**
* Base62解码
*
*
* @param base62Str 被解码的Base62字符串
* @param out 写出到的流
* @param isCloseOut 是否关闭输出流
@@ -129,7 +129,7 @@ public class Base62 {
/**
* Base62解码
*
*
* @param base62Str 被解码的Base62字符串
* @return 被加密后的字符串
*/
@@ -139,7 +139,7 @@ public class Base62 {
/**
* 解码Base62
*
*
* @param base62bytes Base62输入
* @return 解码后的bytes
*/

View File

@@ -48,16 +48,16 @@ public class Base62Codec implements Serializable{
/**
* 创建GMP风格的Base62编码解码器对象
*
*
* @return Base62Codec
*/
public static Base62Codec createGmp() {
return new Base62Codec(GMP);
}
/**
* 创建Inverted风格的Base62编码解码器对象
*
*
* @return Base62Codec
*/
public static Base62Codec createInverted() {
@@ -69,7 +69,7 @@ public class Base62Codec implements Serializable{
/**
* 构造
*
*
* @param alphabet 自定义字母表
*/
public Base62Codec(byte[] alphabet) {
@@ -93,7 +93,7 @@ public class Base62Codec implements Serializable{
/**
* 解码Base62消息
*
*
* @param encoded Base62内容
* @return 消息
*/
@@ -105,7 +105,7 @@ public class Base62Codec implements Serializable{
// --------------------------------------------------------------------------------------------------------------- Private method start
/**
* 按照字典转换bytes
*
*
* @param indices 内容
* @param dictionary 字典
* @return 转换值
@@ -122,7 +122,7 @@ public class Base62Codec implements Serializable{
/**
* 使用定义的字母表从源基准到目标基准
*
*
* @param message 消息bytes
* @param sourceBase 源基准长度
* @param targetBase 目标基准长度
@@ -167,7 +167,7 @@ public class Base62Codec implements Serializable{
/**
* 估算结果长度
*
*
* @param inputLength 输入长度
* @param sourceBase 源基准长度
* @param targetBase 目标基准长度

View File

@@ -8,7 +8,7 @@ import cn.hutool.core.util.StrUtil;
/**
* Base64解码实现
*
*
* @author looly
*
*/
@@ -41,7 +41,7 @@ public class Base64Decoder {
/**
* base64解码
*
*
* @param source 被解码的base64字符串
* @return 被加密后的字符串
*/
@@ -51,7 +51,7 @@ public class Base64Decoder {
/**
* base64解码
*
*
* @param source 被解码的base64字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -62,7 +62,7 @@ public class Base64Decoder {
/**
* base64解码
*
*
* @param source 被解码的base64字符串
* @return 被加密后的字符串
*/
@@ -72,7 +72,7 @@ public class Base64Decoder {
/**
* 解码Base64
*
*
* @param in 输入
* @return 解码后的bytes
*/
@@ -85,7 +85,7 @@ public class Base64Decoder {
/**
* 解码Base64
*
*
* @param in 输入
* @param pos 开始位置
* @param length 长度
@@ -133,7 +133,7 @@ public class Base64Decoder {
// ----------------------------------------------------------------------------------------------- Private start
/**
* 获取下一个有效的byte字符
*
*
* @param in 输入
* @param pos 当前位置,调用此方法后此位置保持在有效字符的下一个位置
* @param maxPos 最大位置
@@ -157,7 +157,7 @@ public class Base64Decoder {
/**
* int包装使之可变
*
*
* @author looly
*
*/

View File

@@ -7,7 +7,7 @@ import java.nio.charset.Charset;
/**
* Base64编码
*
*
* @author looly
* @since 3.2.0
*/
@@ -40,7 +40,7 @@ public class Base64Encoder {
// -------------------------------------------------------------------- encode
/**
* 编码为Base64非URL安全的
*
*
* @param arr 被编码的数组
* @param lineSep 在76个char之后是CRLF还是EOF
* @return 编码后的bytes
@@ -51,7 +51,7 @@ public class Base64Encoder {
/**
* 编码为Base64URL安全的
*
*
* @param arr 被编码的数组
* @param lineSep 在76个char之后是CRLF还是EOF
* @return 编码后的bytes
@@ -63,7 +63,7 @@ public class Base64Encoder {
/**
* base64编码
*
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
*/
@@ -73,7 +73,7 @@ public class Base64Encoder {
/**
* base64编码URL安全
*
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
* @since 3.0.6
@@ -84,7 +84,7 @@ public class Base64Encoder {
/**
* base64编码
*
*
* @param source 被编码的base64字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -95,7 +95,7 @@ public class Base64Encoder {
/**
* base64编码URL安全的
*
*
* @param source 被编码的base64字符串
* @param charset 字符集
* @return 被加密后的字符串
@@ -107,7 +107,7 @@ public class Base64Encoder {
/**
* base64编码
*
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
*/
@@ -117,7 +117,7 @@ public class Base64Encoder {
/**
* base64编码,URL安全的
*
*
* @param source 被编码的base64字符串
* @return 被加密后的字符串
* @since 3.0.6
@@ -129,7 +129,7 @@ public class Base64Encoder {
/**
* 编码为Base64<br>
* 如果isMultiLine为{@code true}则每76个字符一个换行符否则在一行显示
*
*
* @param arr 被编码的数组
* @param isMultiLine 在76个char之后是CRLF还是EOF
* @param isUrlSafe 是否使用URL安全字符一般为{@code false}

View File

@@ -11,7 +11,7 @@ import cn.hutool.core.util.StrUtil;
/**
* 莫尔斯电码的编码和解码实现<br>
* 参考https://github.com/TakWolf/Java-MorseCoder
*
*
* @author looly, TakWolf
* @since 4.4.1
*/
@@ -22,7 +22,7 @@ public class Morse {
/**
* 注册莫尔斯电码表
*
*
* @param abc 字母和字符
* @param dict 二进制
*/
@@ -104,7 +104,7 @@ public class Morse {
/**
* 构造
*
*
* @param dit 点表示的字符
* @param dah 横线表示的字符
* @param split 分隔符
@@ -117,13 +117,13 @@ public class Morse {
/**
* 编码
*
*
* @param text 文本
* @return 密文
*/
public String encode(String text) {
Assert.notNull(text, "Text should not be null.");
text = text.toUpperCase();
final StringBuilder morseBuilder = new StringBuilder();
final int len = text.codePointCount(0, text.length());
@@ -140,7 +140,7 @@ public class Morse {
/**
* 解码
*
*
* @param morse 莫尔斯电码
* @return 明文
*/

View File

@@ -3,7 +3,7 @@ package cn.hutool.core.codec;
/**
* RotNrotate by N places回转N位密码是一种简易的替换式密码也是过去在古罗马开发的凯撒加密的一种变体。<br>
* 代码来自https://github.com/orclight/jencrypt
*
*
* @author looly,shuzhilong
* @since 4.4.1
*/
@@ -18,7 +18,7 @@ public class Rot {
/**
* Rot-13编码同时编码数字
*
*
* @param message 被编码的消息
* @return 编码后的字符串
*/
@@ -28,7 +28,7 @@ public class Rot {
/**
* Rot-13编码
*
*
* @param message 被编码的消息
* @param isEnocdeNumber 是否编码数字
* @return 编码后的字符串
@@ -39,7 +39,7 @@ public class Rot {
/**
* RotN编码
*
*
* @param message 被编码的消息
* @param offset 位移常用位移13
* @param isEnocdeNumber 是否编码数字
@@ -57,7 +57,7 @@ public class Rot {
/**
* Rot-13解码同时解码数字
*
*
* @param rot 被解码的消息密文
* @return 解码后的字符串
*/
@@ -67,7 +67,7 @@ public class Rot {
/**
* Rot-13解码
*
*
* @param rot 被解码的消息密文
* @param isDecodeNumber 是否解码数字
* @return 解码后的字符串
@@ -78,7 +78,7 @@ public class Rot {
/**
* RotN解码
*
*
* @param rot 被解码的消息密文
* @param offset 位移常用位移13
* @param isDecodeNumber 是否解码数字
@@ -97,7 +97,7 @@ public class Rot {
// ------------------------------------------------------------------------------------------ Private method start
/**
* 解码字符
*
*
* @param c 字符
* @param offset 位移
* @param isDecodeNumber 是否解码数字
@@ -129,7 +129,7 @@ public class Rot {
/**
* 编码字符
*
*
* @param c 字符
* @param offset 位移
* @param isDecodeNumber 是否编码数字

View File

@@ -1,6 +1,6 @@
/**
* BaseN以及BCD编码封装
*
*
* @author looly
*
*/

View File

@@ -58,7 +58,7 @@ public class ArrayIter<E> implements Iterator<E>, Iterable<E>, Serializable{
if(endIndex > 0 && endIndex < this.endIndex){
this.endIndex = endIndex;
}
if(startIndex >=0 && startIndex < this.endIndex){
this.startIndex = startIndex;
}

View File

@@ -15,15 +15,15 @@ import java.util.PriorityQueue;
*/
public class BoundedPriorityQueue<E> extends PriorityQueue<E>{
private static final long serialVersionUID = 3794348988671694820L;
//容量
private final int capacity;
private final Comparator<? super E> comparator;
public BoundedPriorityQueue(int capacity) {
this(capacity, null);
}
/**
* 构造
* @param capacity 容量
@@ -63,7 +63,7 @@ public class BoundedPriorityQueue<E> extends PriorityQueue<E>{
}
return super.offer(e);
}
/**
* 添加多个元素<br>
* 参数为集合的情况请使用{@link PriorityQueue#addAll}
@@ -73,7 +73,7 @@ public class BoundedPriorityQueue<E> extends PriorityQueue<E>{
public boolean addAll(E[] c) {
return this.addAll(Arrays.asList(c));
}
/**
* @return 返回排序后的列表
*/
@@ -82,7 +82,7 @@ public class BoundedPriorityQueue<E> extends PriorityQueue<E>{
list.sort(comparator);
return list;
}
@Override
public Iterator<E> iterator() {
return toList().iterator();

View File

@@ -2780,11 +2780,11 @@ public class CollUtil {
}
/**
* 取最
* 取最
*
* @param <T> 元素类型
* @param coll 集合
* @return 最
* @return 最
* @see Collections#min(Collection)
* @since 4.6.5
*/
@@ -2988,4 +2988,25 @@ public class CollUtil {
}
return total;
}
/**
* 判断两个{@link Collection} 是否元素和顺序相同,返回{@code true}的条件是:
* <ul>
* <li>两个{@link Collection}必须长度相同</li>
* <li>两个{@link Collection}元素相同index的对象必须equals满足{@link Objects#equals(Object, Object)}</li>
* </ul>
* 此方法来自Apache-Commons-Collections4。
*
* @param list1 列表1
* @param list2 列表2
* @return 是否相同
* @since 5.6.0
*/
public static boolean isEqualList(final Collection<?> list1, final Collection<?> list2) {
if (list1 == null || list2 == null || list1.size() != list2.size()) {
return false;
}
return IterUtil.isEqualList(list1, list2);
}
}

View File

@@ -2,7 +2,7 @@ package cn.hutool.core.collection;
/**
* 集合相关工具类,包括数组,是{@link CollUtil} 的别名工具类类
*
*
* @author xiaoleilu
* @see CollUtil
*/

View File

@@ -7,7 +7,7 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* 通过{@link ConcurrentHashMap}实现的线程安全HashSet
*
*
* @author Looly
*
* @param <E> 元素类型
@@ -32,7 +32,7 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements java.io.Seri
/**
* 构造<br>
* 触发因子为默认的0.75
*
*
* @param initialCapacity 初始大小
*/
public ConcurrentHashSet(int initialCapacity) {
@@ -41,7 +41,7 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements java.io.Seri
/**
* 构造
*
*
* @param initialCapacity 初始大小
* @param loadFactor 加载因子。此参数决定数据增长时触发的百分比
*/
@@ -51,7 +51,7 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements java.io.Seri
/**
* 构造
*
*
* @param initialCapacity 初始大小
* @param loadFactor 触发因子。此参数决定数据增长时触发的百分比
* @param concurrencyLevel 线程并发度
@@ -59,7 +59,7 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements java.io.Seri
public ConcurrentHashSet(int initialCapacity, float loadFactor, int concurrencyLevel) {
map = new ConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel);
}
/**
* 从已有集合中构造
* @param iter {@link Iterable}

View File

@@ -8,14 +8,14 @@ import java.util.List;
* 复制 {@link Iterator}<br>
* 为了解决并发情况下{@link Iterator}遍历导致的问题当Iterator被修改会抛出ConcurrentModificationException
* 故使用复制原Iterator的方式解决此问题。
*
*
* <p>
* 解决方法为在构造方法中遍历Iterator中的元素装入新的List中然后遍历之。
* 当然修改这个复制后的Iterator是没有意义的因此remove方法将会抛出异常。
*
*
* <p>
* 需要注意的是,在构造此对象时需要保证原子性(原对象不被修改),最好加锁构造此对象,构造完毕后解锁。
*
*
*
* @param <E> 元素类型
* @author Looly
@@ -25,7 +25,7 @@ public class CopiedIter<E> implements Iterator<E>, Iterable<E>, Serializable {
private static final long serialVersionUID = 1L;
private final Iterator<E> listIterator;
public static <V> CopiedIter<V> copyOf(Iterator<V> iterator){
return new CopiedIter<>(iterator);
}

View File

@@ -13,9 +13,9 @@ import java.util.Iterator;
*/
public class EnumerationIter<E> implements Iterator<E>, Iterable<E>, Serializable{
private static final long serialVersionUID = 1L;
private final Enumeration<E> e;
/**
* 构造
* @param enumeration {@link Enumeration}对象

View File

@@ -18,6 +18,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.function.Function;
/**
@@ -612,7 +613,7 @@ public class IterUtil {
/**
* Enumeration转换为Iterator
* <p>
* Adapt the specified <code>Enumeration</code> to the <code>Iterator</code> interface
* Adapt the specified {@code Enumeration} to the {@code Iterator} interface
*
* @param <E> 集合元素类型
* @param e {@link Enumeration}
@@ -859,4 +860,39 @@ public class IterUtil {
}
return size;
}
/**
* 判断两个{@link Iterable} 是否元素和顺序相同,返回{@code true}的条件是:
* <ul>
* <li>两个{@link Iterable}必须长度相同</li>
* <li>两个{@link Iterable}元素相同index的对象必须equals满足{@link Objects#equals(Object, Object)}</li>
* </ul>
* 此方法来自Apache-Commons-Collections4。
*
* @param list1 列表1
* @param list2 列表2
* @return 是否相同
* @since 5.6.0
*/
public static boolean isEqualList(final Iterable<?> list1, final Iterable<?> list2) {
if (list1 == list2) {
return true;
}
final Iterator<?> it1 = list1.iterator();
final Iterator<?> it2 = list2.iterator();
Object obj1;
Object obj2;
while (it1.hasNext() && it2.hasNext()) {
obj1 = it1.next();
obj2 = it2.next();
if (false == Objects.equals(obj1, obj2)) {
return false;
}
}
// 当两个Iterable长度不一致时返回false
return false == (it1.hasNext() || it2.hasNext());
}
}

View File

@@ -13,9 +13,9 @@ import java.util.Iterator;
*/
public class IteratorEnumeration<E> implements Enumeration<E>, Serializable{
private static final long serialVersionUID = 1L;
private final Iterator<E> iterator;
/**
* 构造
* @param iterator {@link Iterator}对象

View File

@@ -17,7 +17,7 @@ import cn.hutool.core.lang.Assert;
/**
* 将Reader包装为一个按照行读取的Iterator<br>
* 此对象遍历结束后,应关闭之,推荐使用方式:
*
*
* <pre>
* LineIterator it = null;
* try {
@@ -30,7 +30,7 @@ import cn.hutool.core.lang.Assert;
* it.close();
* }
* </pre>
*
*
* 此类来自于Apache Commons io
*
* @author looly
@@ -45,7 +45,7 @@ public class LineIter implements Iterator<String>, Iterable<String>, Closeable,
private String cachedLine;
/** A flag indicating if the iterator has been fully read. */
private boolean finished = false;
/**
* 构造
*
@@ -148,7 +148,7 @@ public class LineIter implements Iterator<String>, Iterable<String>, Closeable,
/**
* 重写此方法来判断是否每一行都被返回默认全部为true
*
*
* @param line 需要验证的行
* @return 是否通过验证
*/

View File

@@ -246,7 +246,7 @@ public class ListUtil {
// 每页条目数大于总数直接返回所有
if (resultSize <= pageSize) {
if (pageNo < (PageUtil.getFirstPageNo() + 1)) {
return Collections.unmodifiableList(list);
return unmodifiable(list);
} else {
// 越界直接返回空
return new ArrayList<>(0);
@@ -262,11 +262,11 @@ public class ListUtil {
if (startEnd[1] > resultSize) {
startEnd[1] = resultSize;
if (startEnd[0] > startEnd[1]) {
return empty();
return new ArrayList<>(0);
}
}
return list.subList(startEnd[0], startEnd[1]);
return sub(list, startEnd[0], startEnd[1]);
}
/**
@@ -366,7 +366,8 @@ public class ListUtil {
}
/**
* 截取集合的部分
* 截取集合的部分<br>
* 此方法与{@link List#subList(int, int)} 不同在于子列表是新的副本,操作子列表不会影响原列表。
*
* @param <T> 集合元素类型
* @param list 被截取的数组
@@ -407,8 +408,8 @@ public class ListUtil {
end = size;
}
if (step <= 1) {
return list.subList(start, end);
if (step < 1) {
step = 1;
}
final List<T> result = new ArrayList<>();

View File

@@ -21,7 +21,6 @@ public class ComparableComparator<E extends Comparable<? super E>> implements Co
* 构造
*/
public ComparableComparator() {
super();
}
/**

View File

@@ -28,9 +28,9 @@ import java.util.concurrent.TimeUnit;
/**
* 类型转换器
*
*
* @author xiaoleilu
*
*
*/
public class Convert {
@@ -38,7 +38,7 @@ public class Convert {
* 转换为字符串<br>
* 如果给定的值为null或者转换失败返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -51,17 +51,17 @@ public class Convert {
* 转换为字符串<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
public static String toStr(Object value) {
return toStr(value, null);
}
/**
* 转换为String数组
*
*
* @param value 被转换的值
* @return String数组
* @since 3.2.0
@@ -74,7 +74,7 @@ public class Convert {
* 转换为字符<br>
* 如果给定的值为null或者转换失败返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -87,17 +87,17 @@ public class Convert {
* 转换为字符<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
public static Character toChar(Object value) {
return toChar(value, null);
}
/**
* 转换为Character数组
*
*
* @param value 被转换的值
* @return Character数组
* @since 3.2.0
@@ -110,7 +110,7 @@ public class Convert {
* 转换为byte<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -123,17 +123,17 @@ public class Convert {
* 转换为byte<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
public static Byte toByte(Object value) {
return toByte(value, null);
}
/**
* 转换为Byte数组
*
*
* @param value 被转换的值
* @return Byte数组
* @since 3.2.0
@@ -157,7 +157,7 @@ public class Convert {
* 转换为Short<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -170,17 +170,17 @@ public class Convert {
* 转换为Short<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
public static Short toShort(Object value) {
return toShort(value, null);
}
/**
* 转换为Short数组
*
*
* @param value 被转换的值
* @return Short数组
* @since 3.2.0
@@ -193,7 +193,7 @@ public class Convert {
* 转换为Number<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -206,17 +206,17 @@ public class Convert {
* 转换为Number<br>
* 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
public static Number toNumber(Object value) {
return toNumber(value, null);
}
/**
* 转换为Number数组
*
*
* @param value 被转换的值
* @return Number数组
* @since 3.2.0
@@ -229,7 +229,7 @@ public class Convert {
* 转换为int<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -242,7 +242,7 @@ public class Convert {
* 转换为int<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -264,7 +264,7 @@ public class Convert {
* 转换为long<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -277,7 +277,7 @@ public class Convert {
* 转换为long<br>
* 如果给定的值为{@code null},或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -287,7 +287,7 @@ public class Convert {
/**
* 转换为Long数组<br>
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -299,7 +299,7 @@ public class Convert {
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -312,7 +312,7 @@ public class Convert {
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -322,7 +322,7 @@ public class Convert {
/**
* 转换为Double数组<br>
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -334,7 +334,7 @@ public class Convert {
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -347,7 +347,7 @@ public class Convert {
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -357,7 +357,7 @@ public class Convert {
/**
* 转换为Float数组<br>
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -369,7 +369,7 @@ public class Convert {
* 转换为boolean<br>
* String支持的值为true、false、yes、ok、no1,0 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -382,7 +382,7 @@ public class Convert {
* 转换为boolean<br>
* 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -392,7 +392,7 @@ public class Convert {
/**
* 转换为Boolean数组<br>
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -404,7 +404,7 @@ public class Convert {
* 转换为BigInteger<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -417,7 +417,7 @@ public class Convert {
* 转换为BigInteger<br>
* 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
@@ -429,7 +429,7 @@ public class Convert {
* 转换为BigDecimal<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -442,19 +442,19 @@ public class Convert {
* 转换为BigDecimal<br>
* 如果给定的值为空或者转换失败返回null<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
*/
public static BigDecimal toBigDecimal(Object value) {
return toBigDecimal(value, null);
}
/**
* 转换为Date<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
@@ -489,7 +489,7 @@ public class Convert {
public static LocalDateTime toLocalDateTime(Object value) {
return toLocalDateTime(value, null);
}
/**
* Instant<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
@@ -508,7 +508,7 @@ public class Convert {
* 转换为Date<br>
* 如果给定的值为空,或者转换失败,返回{@code null}<br>
* 转换失败不会报错
*
*
* @param value 被转换的值
* @return 结果
* @since 4.1.6
@@ -516,11 +516,11 @@ public class Convert {
public static Date toDate(Object value) {
return toDate(value, null);
}
/**
* 转换为Enum对象<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
*
*
* @param <E> 枚举类型
* @param clazz Enum的Class
* @param value 值
@@ -535,7 +535,7 @@ public class Convert {
/**
* 转换为Enum对象<br>
* 如果给定的值为空,或者转换失败,返回默认值{@code null}<br>
*
*
* @param <E> 枚举类型
* @param clazz Enum的Class
* @param value 值
@@ -547,7 +547,7 @@ public class Convert {
/**
* 转换为集合类
*
*
* @param collectionType 集合类型
* @param elementType 集合中元素类型
* @param value 被转换的值
@@ -557,10 +557,10 @@ public class Convert {
public static Collection<?> toCollection(Class<?> collectionType, Class<?> elementType, Object value) {
return new CollectionConverter(collectionType, elementType).convert(value, null);
}
/**
* 转换为ArrayList元素类型默认Object
*
*
* @param value 被转换的值
* @return {@link List}
* @since 4.1.11
@@ -568,10 +568,10 @@ public class Convert {
public static List<?> toList(Object value) {
return convert(List.class, value);
}
/**
* 转换为ArrayList
*
*
* @param <T> 元素类型
* @param elementType 集合中元素类型
* @param value 被转换的值
@@ -598,10 +598,10 @@ public class Convert {
public static <K, V> Map<K, V> toMap(Class<K> keyType, Class<V> valueType, Object value) {
return (Map<K, V>) new MapConverter(HashMap.class, keyType, valueType).convert(value, null);
}
/**
* 转换值为指定类型,类型采用字符串表示
*
*
* @param <T> 目标类型
* @param className 类的字符串表示
* @param value 值
@@ -612,10 +612,10 @@ public class Convert {
public static <T> T convertByClassName(String className, Object value) throws ConvertException{
return convert(ClassUtil.loadClass(className), value);
}
/**
* 转换值为指定类型
*
*
* @param <T> 目标类型
* @param type 类型
* @param value 值
@@ -626,10 +626,10 @@ public class Convert {
public static <T> T convert(Class<T> type, Object value) throws ConvertException{
return convert((Type)type, value);
}
/**
* 转换值为指定类型
*
*
* @param <T> 目标类型
* @param reference 类型参考,用于持有转换后的泛型类型
* @param value 值
@@ -642,7 +642,7 @@ public class Convert {
/**
* 转换值为指定类型
*
*
* @param <T> 目标类型
* @param type 类型
* @param value 值
@@ -652,10 +652,10 @@ public class Convert {
public static <T> T convert(Type type, Object value) throws ConvertException{
return convert(type, value, null);
}
/**
* 转换值为指定类型
*
*
* @param <T> 目标类型
* @param type 类型
* @param value 值
@@ -667,10 +667,10 @@ public class Convert {
public static <T> T convert(Class<T> type, Object value, T defaultValue) throws ConvertException {
return convert((Type)type, value, defaultValue);
}
/**
* 转换值为指定类型
*
*
* @param <T> 目标类型
* @param type 类型
* @param value 值
@@ -681,11 +681,11 @@ public class Convert {
public static <T> T convert(Type type, Object value, T defaultValue) throws ConvertException {
return convertWithCheck(type, value, defaultValue, false);
}
/**
* 转换值为指定类型,不抛异常转换<br>
* 当转换失败时返回{@code null}
*
*
* @param <T> 目标类型
* @param type 目标类型
* @param value 值
@@ -695,11 +695,11 @@ public class Convert {
public static <T> T convertQuietly(Type type, Object value) {
return convertQuietly(type, value, null);
}
/**
* 转换值为指定类型,不抛异常转换<br>
* 当转换失败时返回默认值
*
*
* @param <T> 目标类型
* @param type 目标类型
* @param value 值
@@ -734,11 +734,11 @@ public class Convert {
throw e;
}
}
// ----------------------------------------------------------------------- 全角半角转换
/**
* 半角转全角
*
*
* @param input String.
* @return 全角字符串.
*/
@@ -748,7 +748,7 @@ public class Convert {
/**
* 半角转全角
*
*
* @param input String
* @param notConvertSet 不替换的字符集合
* @return 全角字符串.
@@ -773,7 +773,7 @@ public class Convert {
/**
* 全角转半角
*
*
* @param input String.
* @return 半角字符串
*/
@@ -783,7 +783,7 @@ public class Convert {
/**
* 替换全角为半角
*
*
* @param text 文本
* @param notConvertSet 不替换的字符集合
* @return 替换后的字符
@@ -813,7 +813,7 @@ public class Convert {
// --------------------------------------------------------------------- hex
/**
* 字符串转换成十六进制字符串,结果为小写
*
*
* @param str 待转换的ASCII字符串
* @param charset 编码
* @return 16进制字符串
@@ -825,7 +825,7 @@ public class Convert {
/**
* byte数组转16进制串
*
*
* @param bytes 被转换的byte数组
* @return 转换后的值
* @see HexUtil#encodeHexStr(byte[])
@@ -836,7 +836,7 @@ public class Convert {
/**
* Hex字符串转换为Byte值
*
*
* @param src Byte字符串每个Byte之间没有分隔符
* @return byte[]
* @see HexUtil#decodeHex(char[])
@@ -847,7 +847,7 @@ public class Convert {
/**
* 十六进制转换字符串
*
*
* @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
* @param charset 编码 {@link Charset}
* @return 对应的字符串
@@ -858,10 +858,10 @@ public class Convert {
public static String hexStrToStr(String hexStr, Charset charset) {
return hexToStr(hexStr, charset);
}
/**
* 十六进制转换字符串
*
*
* @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
* @param charset 编码 {@link Charset}
* @return 对应的字符串
@@ -874,7 +874,7 @@ public class Convert {
/**
* String的字符串转换成unicode的String
*
*
* @param strText 全角字符串
* @return String 每个unicode之间无分隔符
* @see UnicodeUtil#toUnicode(String)
@@ -885,7 +885,7 @@ public class Convert {
/**
* unicode的String转换成String的字符串
*
*
* @param unicode Unicode符
* @return String 字符串
* @see UnicodeUtil#toString(String)
@@ -897,7 +897,7 @@ public class Convert {
/**
* 给定字符串转换字符编码<br>
* 如果参数为空,则返回原字符串,不报错。
*
*
* @param str 被转码的字符串
* @param sourceCharset 原字符集
* @param destCharset 目标字符集
@@ -914,7 +914,7 @@ public class Convert {
/**
* 转换时间单位
*
*
* @param sourceDuration 时长
* @param sourceUnit 源单位
* @param destUnit 目标单位
@@ -929,7 +929,7 @@ public class Convert {
// --------------------------------------------------------------- 原始包装类型转换
/**
* 原始类转为包装类,非原始类返回原类
*
*
* @see BasicType#wrap(Class)
* @param clazz 原始类
* @return 包装类
@@ -941,7 +941,7 @@ public class Convert {
/**
* 包装类转为原始类,非包装类返回原类
*
*
* @see BasicType#unWrap(Class)
* @param clazz 包装类
* @return 原始类
@@ -954,7 +954,7 @@ public class Convert {
// -------------------------------------------------------------------------- 数字和英文转换
/**
* 将阿拉伯数字转为英文表达方式
*
*
* @param number {@link Number}对象
* @return 英文表达式
* @since 3.0.9
@@ -962,10 +962,25 @@ public class Convert {
public static String numberToWord(Number number) {
return NumberWordFormatter.format(number);
}
/**
* 将阿拉伯数字转为精简表示形式,例如:
*
* <pre>
* 1200 -》 1.2k
* </pre>
*
* @param number {@link Number}对象
* @return 英文表达式
* @since 5.5.9
*/
public static String numberToSimple(Number number) {
return NumberWordFormatter.formatSimple(number.longValue());
}
/**
* 将阿拉伯数字转为中文表达方式
*
*
* @param number 数字
* @param isUseTraditonal 是否使用繁体字(金额形式)
* @return 中文
@@ -974,10 +989,10 @@ public class Convert {
public static String numberToChinese(double number, boolean isUseTraditonal) {
return NumberChineseFormatter.format(number, isUseTraditonal);
}
/**
* 金额转为中文形式
*
*
* @param n 数字
* @return 中文大写数字
* @since 3.2.3
@@ -988,11 +1003,11 @@ public class Convert {
}
return NumberChineseFormatter.format(n.doubleValue(), true, true);
}
// -------------------------------------------------------------------------- 数字转换
/**
* int转byte
*
*
* @param intValue int值
* @return byte值
* @since 3.2.0
@@ -1003,7 +1018,7 @@ public class Convert {
/**
* byte转无符号int
*
*
* @param byteValue byte值
* @return 无符号int值
* @since 3.2.0
@@ -1015,7 +1030,7 @@ public class Convert {
/**
* byte数组转short
*
*
* @param bytes byte数组
* @return short值
* @since 3.2.0
@@ -1039,7 +1054,7 @@ public class Convert {
/**
* byte[]转int值
*
*
* @param bytes byte数组
* @return int值
* @since 3.2.0
@@ -1053,7 +1068,7 @@ public class Convert {
/**
* int转byte数组
*
*
* @param intValue int值
* @return byte数组
* @since 3.2.0
@@ -1070,7 +1085,7 @@ public class Convert {
/**
* long转byte数组<br>
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
*
*
* @param longValue long值
* @return byte数组
* @since 3.2.0
@@ -1088,7 +1103,7 @@ public class Convert {
/**
* byte数组转long<br>
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
*
*
* @param bytes byte数组
* @return long值
* @since 3.2.0

View File

@@ -1,180 +1,182 @@
package cn.hutool.core.convert;
import cn.hutool.core.util.StrUtil;
import java.text.DecimalFormat;
/**
* 将浮点数类型的number转换成英语的表达方式 <br>
* 参考博客http://blog.csdn.net/eric_sunah/article/details/8713226
*
* @author Looly
* @since 3.0.9
*/
public class NumberWordFormatter {
private static final String[] NUMBER = new String[]{"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
"EIGHT", "NINE"};
private static final String[] NUMBER_TEEN = new String[]{"TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN",
"FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"};
private static final String[] NUMBER_TEN = new String[]{"TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY",
"SEVENTY", "EIGHTY", "NINETY"};
private static final String[] NUMBER_MORE = new String[]{"", "THOUSAND", "MILLION", "BILLION"};
private static final String[] NUMBER_SUFFIX = new String[]{"k", "w", "", "m", "", "", "b", "", "", "t", "", "", "p", "", "", "e"};
/**
* 将阿拉伯数字转为英文表达式
*
* @param x 阿拉伯数字,可以为{@link Number}对象,也可以是普通对象,最后会使用字符串方式处理
* @return 英文表达式
*/
public static String format(Object x) {
if (x != null) {
return format(x.toString());
} else {
return "";
}
}
/**
* 将阿拉伯数字转化为简介计数单位,例如 2100 => 2.1k
* 范围默认只到w
* @param value
* @return
*/
public static String formatValue(long value) {
return formatValue(value, true);
}
/**
* 将阿拉伯数字转化为简介计数单位,例如 2100 => 2.1k
* @param value 对应数字的值
* @param isTwo 控制是否为k、w
* @return
*/
public static String formatValue(long value, boolean isTwo) {
if (value < 1000) {
return String.valueOf(value);
}
int index = -1;
double res = value * 1.0d;
while (res > 10 && (!isTwo || index < 1)) {
if (res > 1000) {
res = res / 1000;
index++;
}
if (res > 10) {
res = res / 10;
index++;
}
}
DecimalFormat decimalFormat = new DecimalFormat("#.##");
return String.format("%s%s", decimalFormat.format(res), NUMBER_SUFFIX[index]);
}
/**
* 将阿拉伯数字转为英文表达式
*
* @param x 阿拉伯数字字符串
* @return 英文表达式
*/
private static String format(String x) {
int z = x.indexOf("."); // 取小数点位置
String lstr, rstr = "";
if (z > -1) { // 看是否有小数,如果有,则分别取左边和右边
lstr = x.substring(0, z);
rstr = x.substring(z + 1);
} else {
// 否则就是全部
lstr = x;
}
String lstrrev = StrUtil.reverse(lstr); // 对左边的字串取反
String[] a = new String[5]; // 定义5个字串变量来存放解析出来的叁位一组的字串
switch (lstrrev.length() % 3) {
case 1:
lstrrev += "00";
break;
case 2:
lstrrev += "0";
break;
}
StringBuilder lm = new StringBuilder(); // 用来存放转换后的整数部分
for (int i = 0; i < lstrrev.length() / 3; i++) {
a[i] = StrUtil.reverse(lstrrev.substring(3 * i, 3 * i + 3)); // 截取第一个三位
if (false == "000".equals(a[i])) { // 用来避免这种情况1000000 = one million
// thousand only
if (i != 0) {
lm.insert(0, transThree(a[i]) + " " + parseMore(i) + " "); // 加:
// thousand、million、billion
} else {
// 防止i=0时 在多加两个空格.
lm = new StringBuilder(transThree(a[i]));
}
} else {
lm.append(transThree(a[i]));
}
}
String xs = ""; // 用来存放转换后小数部分
if (z > -1) {
xs = "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数
}
return lm.toString().trim() + " " + xs + "ONLY";
}
private static String parseFirst(String s) {
return NUMBER[Integer.parseInt(s.substring(s.length() - 1))];
}
private static String parseTeen(String s) {
return NUMBER_TEEN[Integer.parseInt(s) - 10];
}
private static String parseTen(String s) {
return NUMBER_TEN[Integer.parseInt(s.substring(0, 1)) - 1];
}
private static String parseMore(int i) {
return NUMBER_MORE[i];
}
// 两位
private static String transTwo(String s) {
String value;
// 判断位数
if (s.length() > 2) {
s = s.substring(0, 2);
} else if (s.length() < 2) {
s = "0" + s;
}
if (s.startsWith("0")) {// 07 - seven 是否小於10
value = parseFirst(s);
} else if (s.startsWith("1")) {// 17 seventeen 是否在10和20之间
value = parseTeen(s);
} else if (s.endsWith("0")) {// 是否在10与100之间的能被10整除的数
value = parseTen(s);
} else {
value = parseTen(s) + " " + parseFirst(s);
}
return value;
}
// 制作叁位的数
// s.length = 3
private static String transThree(String s) {
String value;
if (s.startsWith("0")) {// 是否小於100
value = transTwo(s.substring(1));
} else if ("00".equals(s.substring(1))) {// 是否100整除
value = parseFirst(s.substring(0, 1)) + " HUNDRED";
} else {
value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1));
}
return value;
}
}
package cn.hutool.core.convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
/**
* 将浮点数类型的number转换成英语的表达方式 <br>
* 参考博客http://blog.csdn.net/eric_sunah/article/details/8713226
*
* @author Looly,totalo
* @since 3.0.9
*/
public class NumberWordFormatter {
private static final String[] NUMBER = new String[]{"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
"EIGHT", "NINE"};
private static final String[] NUMBER_TEEN = new String[]{"TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN",
"FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"};
private static final String[] NUMBER_TEN = new String[]{"TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY",
"SEVENTY", "EIGHTY", "NINETY"};
private static final String[] NUMBER_MORE = new String[]{"", "THOUSAND", "MILLION", "BILLION"};
private static final String[] NUMBER_SUFFIX = new String[]{"k", "w", "", "m", "", "", "b", "", "", "t", "", "", "p", "", "", "e"};
/**
* 将阿拉伯数字转为英文表达式
*
* @param x 阿拉伯数字,可以为{@link Number}对象,也可以是普通对象,最后会使用字符串方式处理
* @return 英文表达式
*/
public static String format(Object x) {
if (x != null) {
return format(x.toString());
} else {
return StrUtil.EMPTY;
}
}
/**
* 将阿拉伯数字转化为简洁计数单位,例如 2100 =》 2.1k
* 范围默认只到w
*
* @param value 被格式化的数字
* @return 格式化后的数字
* @since 5.5.9
*/
public static String formatSimple(long value) {
return formatSimple(value, true);
}
/**
* 将阿拉伯数字转化为简介计数单位,例如 2100 =》 2.1k
*
* @param value 对应数字的值
* @param isTwo 控制是否为只为k、w例如当为{@code false}时返回4.38m{@code true}返回438.43w
* @return 格式化后的数字
* @since 5.5.9
*/
public static String formatSimple(long value, boolean isTwo) {
if (value < 1000) {
return String.valueOf(value);
}
int index = -1;
double res = value;
while (res > 10 && (false == isTwo || index < 1)) {
if (res > 1000) {
res = res / 1000;
index++;
}
if (res > 10) {
res = res / 10;
index++;
}
}
return String.format("%s%s", NumberUtil.decimalFormat("#.##", res), NUMBER_SUFFIX[index]);
}
/**
* 将阿拉伯数字转为英文表达式
*
* @param x 阿拉伯数字字符串
* @return 英文表达式
*/
private static String format(String x) {
int z = x.indexOf("."); // 取小数点位置
String lstr, rstr = "";
if (z > -1) { // 看是否有小数,如果有,则分别取左边和右边
lstr = x.substring(0, z);
rstr = x.substring(z + 1);
} else {
// 否则就是全部
lstr = x;
}
String lstrrev = StrUtil.reverse(lstr); // 对左边的字串取反
String[] a = new String[5]; // 定义5个字串变量来存放解析出来的叁位一组的字串
switch (lstrrev.length() % 3) {
case 1:
lstrrev += "00";
break;
case 2:
lstrrev += "0";
break;
}
StringBuilder lm = new StringBuilder(); // 用来存放转换后的整数部分
for (int i = 0; i < lstrrev.length() / 3; i++) {
a[i] = StrUtil.reverse(lstrrev.substring(3 * i, 3 * i + 3)); // 截取第一个三位
if (false == "000".equals(a[i])) { // 用来避免这种情况1000000 = one million
// thousand only
if (i != 0) {
lm.insert(0, transThree(a[i]) + " " + parseMore(i) + " "); // 加:
// thousand、million、billion
} else {
// 防止i=0时 在多加两个空格.
lm = new StringBuilder(transThree(a[i]));
}
} else {
lm.append(transThree(a[i]));
}
}
String xs = ""; // 用来存放转换小数部分
if (z > -1) {
xs = "AND CENTS " + transTwo(rstr) + " "; // 小数部分存在时转换小数
}
return lm.toString().trim() + " " + xs + "ONLY";
}
private static String parseFirst(String s) {
return NUMBER[Integer.parseInt(s.substring(s.length() - 1))];
}
private static String parseTeen(String s) {
return NUMBER_TEEN[Integer.parseInt(s) - 10];
}
private static String parseTen(String s) {
return NUMBER_TEN[Integer.parseInt(s.substring(0, 1)) - 1];
}
private static String parseMore(int i) {
return NUMBER_MORE[i];
}
// 两位
private static String transTwo(String s) {
String value;
// 判断位数
if (s.length() > 2) {
s = s.substring(0, 2);
} else if (s.length() < 2) {
s = "0" + s;
}
if (s.startsWith("0")) {// 07 - seven 是否小於10
value = parseFirst(s);
} else if (s.startsWith("1")) {// 17 seventeen 是否在10和20之间
value = parseTeen(s);
} else if (s.endsWith("0")) {// 是否在10与100之间的能被10整除的数
value = parseTen(s);
} else {
value = parseTen(s) + " " + parseFirst(s);
}
return value;
}
// 制作叁位的数
// s.length = 3
private static String transThree(String s) {
String value;
if (s.startsWith("0")) {// 是否小於100
value = transTwo(s.substring(1));
} else if ("00".equals(s.substring(1))) {// 是否被100整除
value = parseFirst(s.substring(0, 1)) + " HUNDRED";
} else {
value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1));
}
return value;
}
}

View File

@@ -694,7 +694,6 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
*
*/
UnpaddedMonthField() {
super();
}
/**
@@ -833,7 +832,6 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
* Constructs an instance of {@code TwoDigitYearField}.
*/
TwoDigitYearField() {
super();
}
/**
@@ -873,7 +871,6 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
* Constructs an instance of {@code TwoDigitMonthField}.
*/
TwoDigitMonthField() {
super();
}
/**

View File

@@ -27,7 +27,6 @@ public final class FastStringWriter extends Writer {
* @param initialSize 初始容量
*/
public FastStringWriter(int initialSize) {
super();
if (initialSize < 0) {
initialSize = StrBuilder.DEFAULT_CAPACITY;
}

View File

@@ -5,7 +5,7 @@ import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import cn.hutool.core.util.StrUtil;
@@ -23,7 +23,15 @@ public class FileTypeUtil {
private static final Map<String, String> FILE_TYPE_MAP;
static {
FILE_TYPE_MAP = new ConcurrentHashMap<>();
FILE_TYPE_MAP = new ConcurrentSkipListMap<>((s1, s2) -> {
int len1 = s1.length();
int len2 = s2.length();
if (len1 == len2) {
return s1.compareTo(s2);
} else {
return len2 - len1;
}
});
FILE_TYPE_MAP.put("ffd8ff", "jpg"); // JPEG (jpg)
FILE_TYPE_MAP.put("89504e47", "png"); // PNG (png)
@@ -50,22 +58,23 @@ public class FileTypeUtil {
FILE_TYPE_MAP.put("52494646e27807005741", "wav"); // Wave (wav)
FILE_TYPE_MAP.put("52494646d07d60074156", "avi");
FILE_TYPE_MAP.put("4d546864000000060001", "mid"); // MIDI (mid)
FILE_TYPE_MAP.put("526172211a0700cf9073", "rar");// WinRAR
FILE_TYPE_MAP.put("526172211a0700cf9073", "rar"); // WinRAR
FILE_TYPE_MAP.put("235468697320636f6e66", "ini");
FILE_TYPE_MAP.put("504B0304140000000800", "ofd"); // ofd文件 国标版式文件
FILE_TYPE_MAP.put("504B03040a0000000000", "jar");
FILE_TYPE_MAP.put("504B0304140008000800", "jar");
// MS Excel 注意word、msi 和 excel的文件头一样
FILE_TYPE_MAP.put("d0cf11e0a1b11ae10", "xls");
FILE_TYPE_MAP.put("504B0304", "zip");
FILE_TYPE_MAP.put("4d5a9000030000000400", "exe");// 可执行文件
FILE_TYPE_MAP.put("3c25402070616765206c", "jsp");// jsp文件
FILE_TYPE_MAP.put("4d616e69666573742d56", "mf");// MF文件
FILE_TYPE_MAP.put("7061636b616765207765", "java");// java文件
FILE_TYPE_MAP.put("406563686f206f66660d", "bat");// bat文件
FILE_TYPE_MAP.put("1f8b0800000000000000", "gz");// gz文件
FILE_TYPE_MAP.put("cafebabe0000002e0041", "class");// bat文件
FILE_TYPE_MAP.put("49545346030000006000", "chm");// bat文件
FILE_TYPE_MAP.put("04000000010000001300", "mxp");// bat文件
FILE_TYPE_MAP.put("4d5a9000030000000400", "exe"); // 可执行文件
FILE_TYPE_MAP.put("3c25402070616765206c", "jsp"); // jsp文件
FILE_TYPE_MAP.put("4d616e69666573742d56", "mf"); // MF文件
FILE_TYPE_MAP.put("7061636b616765207765", "java"); // java文件
FILE_TYPE_MAP.put("406563686f206f66660d", "bat"); // bat文件
FILE_TYPE_MAP.put("1f8b0800000000000000", "gz"); // gz文件
FILE_TYPE_MAP.put("cafebabe0000002e0041", "class"); // class文件
FILE_TYPE_MAP.put("49545346030000006000", "chm"); // chm文件
FILE_TYPE_MAP.put("04000000010000001300", "mxp"); // mxp文件
FILE_TYPE_MAP.put("6431303a637265617465", "torrent");
FILE_TYPE_MAP.put("6D6F6F76", "mov"); // Quicktime (mov)
FILE_TYPE_MAP.put("FF575043", "wpd"); // WordPerfect (wpd)
@@ -85,7 +94,7 @@ public class FileTypeUtil {
* @return 之前已经存在的文件扩展名
*/
public static String putFileType(String fileStreamHexHead, String extName) {
return FILE_TYPE_MAP.put(fileStreamHexHead.toLowerCase(), extName);
return FILE_TYPE_MAP.put(fileStreamHexHead, extName);
}
/**
@@ -95,7 +104,7 @@ public class FileTypeUtil {
* @return 移除的文件扩展名
*/
public static String removeFileType(String fileStreamHexHead) {
return FILE_TYPE_MAP.remove(fileStreamHexHead.toLowerCase());
return FILE_TYPE_MAP.remove(fileStreamHexHead);
}
/**

View File

@@ -19,7 +19,6 @@ public class MultiFileResource extends MultiResource{
* @param files 文件资源列表
*/
public MultiFileResource(Collection<File> files) {
super();
add(files);
}
@@ -29,7 +28,6 @@ public class MultiFileResource extends MultiResource{
* @param files 文件资源列表
*/
public MultiFileResource(File... files) {
super();
add(files);
}

View File

@@ -44,7 +44,7 @@ public enum DataUnit {
*/
TERABYTES("TB", DataSize.ofTerabytes(1));
public static final String[] UNIT_NAMES = new String[]{"B", "kB", "MB", "GB", "TB", "EB"};
public static final String[] UNIT_NAMES = new String[]{"B", "kB", "MB", "GB", "TB", "PB", "EB"};
private final String suffix;
@@ -77,4 +77,4 @@ public enum DataUnit {
throw new IllegalArgumentException("Unknown data unit suffix '" + suffix + "'");
}
}
}

View File

@@ -30,7 +30,6 @@ public final class Holder<T> extends MutableObj<T>{
* 构造
*/
public Holder() {
super();
}
/**

View File

@@ -17,7 +17,6 @@ public class MutableBool implements Comparable<MutableBool>, Mutable<Boolean>, S
* 构造默认值0
*/
public MutableBool() {
super();
}
/**
@@ -25,7 +24,6 @@ public class MutableBool implements Comparable<MutableBool>, Mutable<Boolean>, S
* @param value 值
*/
public MutableBool(final boolean value) {
super();
this.value = value;
}
@@ -35,7 +33,6 @@ public class MutableBool implements Comparable<MutableBool>, Mutable<Boolean>, S
* @throws NumberFormatException 转为Boolean错误
*/
public MutableBool(final String value) throws NumberFormatException {
super();
this.value = Boolean.parseBoolean(value);
}

View File

@@ -17,7 +17,6 @@ public class MutableByte extends Number implements Comparable<MutableByte>, Muta
* 构造默认值0
*/
public MutableByte() {
super();
}
/**
@@ -25,7 +24,6 @@ public class MutableByte extends Number implements Comparable<MutableByte>, Muta
* @param value 值
*/
public MutableByte(final byte value) {
super();
this.value = value;
}
@@ -43,7 +41,6 @@ public class MutableByte extends Number implements Comparable<MutableByte>, Muta
* @throws NumberFormatException 转为Byte错误
*/
public MutableByte(final String value) throws NumberFormatException {
super();
this.value = Byte.parseByte(value);
}

View File

@@ -17,7 +17,6 @@ public class MutableDouble extends Number implements Comparable<MutableDouble>,
* 构造默认值0
*/
public MutableDouble() {
super();
}
/**
@@ -25,7 +24,6 @@ public class MutableDouble extends Number implements Comparable<MutableDouble>,
* @param value 值
*/
public MutableDouble(final double value) {
super();
this.value = value;
}
@@ -43,7 +41,6 @@ public class MutableDouble extends Number implements Comparable<MutableDouble>,
* @throws NumberFormatException 数字转换错误
*/
public MutableDouble(final String value) throws NumberFormatException {
super();
this.value = Double.parseDouble(value);
}

View File

@@ -17,7 +17,6 @@ public class MutableFloat extends Number implements Comparable<MutableFloat>, Mu
* 构造默认值0
*/
public MutableFloat() {
super();
}
/**
@@ -25,7 +24,6 @@ public class MutableFloat extends Number implements Comparable<MutableFloat>, Mu
* @param value 值
*/
public MutableFloat(final float value) {
super();
this.value = value;
}
@@ -43,7 +41,6 @@ public class MutableFloat extends Number implements Comparable<MutableFloat>, Mu
* @throws NumberFormatException 数字转换错误
*/
public MutableFloat(final String value) throws NumberFormatException {
super();
this.value = Float.parseFloat(value);
}

View File

@@ -17,7 +17,6 @@ public class MutableInt extends Number implements Comparable<MutableInt>, Mutabl
* 构造默认值0
*/
public MutableInt() {
super();
}
/**
@@ -25,7 +24,6 @@ public class MutableInt extends Number implements Comparable<MutableInt>, Mutabl
* @param value 值
*/
public MutableInt(final int value) {
super();
this.value = value;
}
@@ -43,7 +41,6 @@ public class MutableInt extends Number implements Comparable<MutableInt>, Mutabl
* @throws NumberFormatException 数字转换错误
*/
public MutableInt(final String value) throws NumberFormatException {
super();
this.value = Integer.parseInt(value);
}

View File

@@ -17,7 +17,6 @@ public class MutableLong extends Number implements Comparable<MutableLong>, Muta
* 构造默认值0
*/
public MutableLong() {
super();
}
/**
@@ -25,7 +24,6 @@ public class MutableLong extends Number implements Comparable<MutableLong>, Muta
* @param value 值
*/
public MutableLong(final long value) {
super();
this.value = value;
}
@@ -43,7 +41,6 @@ public class MutableLong extends Number implements Comparable<MutableLong>, Muta
* @throws NumberFormatException 数字转换错误
*/
public MutableLong(final String value) throws NumberFormatException {
super();
this.value = Long.parseLong(value);
}

View File

@@ -17,7 +17,6 @@ public class MutableObj<T> implements Mutable<T>, Serializable {
* 构造,空值
*/
public MutableObj() {
super();
}
/**
@@ -26,7 +25,6 @@ public class MutableObj<T> implements Mutable<T>, Serializable {
* @param value 值
*/
public MutableObj(final T value) {
super();
this.value = value;
}

View File

@@ -17,7 +17,6 @@ public class MutableShort extends Number implements Comparable<MutableShort>, Mu
* 构造默认值0
*/
public MutableShort() {
super();
}
/**
@@ -25,7 +24,6 @@ public class MutableShort extends Number implements Comparable<MutableShort>, Mu
* @param value 值
*/
public MutableShort(final short value) {
super();
this.value = value;
}
@@ -43,7 +41,6 @@ public class MutableShort extends Number implements Comparable<MutableShort>, Mu
* @throws NumberFormatException 转为Short错误
*/
public MutableShort(final String value) throws NumberFormatException {
super();
this.value = Short.parseShort(value);
}

View File

@@ -29,7 +29,6 @@ public class Tree<T> extends LinkedHashMap<String, Object> implements Node<T> {
* @param treeNodeConfig TreeNode配置
*/
public Tree(TreeNodeConfig treeNodeConfig) {
super();
this.treeNodeConfig = ObjectUtil.defaultIfNull(
treeNodeConfig, TreeNodeConfig.DEFAULT_CONFIG);
}

View File

@@ -2,6 +2,7 @@ package cn.hutool.core.lang.tree;
import java.util.Map;
import java.util.Objects;
/**
* 树节点 每个属性都可以在{@link TreeNodeConfig}中被重命名<br>
@@ -129,4 +130,21 @@ public class TreeNode<T> implements Node<T> {
this.extra = extra;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TreeNode<?> treeNode = (TreeNode<?>) o;
return Objects.equals(id, treeNode.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

View File

@@ -0,0 +1,45 @@
package cn.hutool.core.map;
import java.util.Map;
import java.util.function.Function;
/**
* 自定义函数Key风格的Map
*
* @param <K> 键类型
* @param <V> 值类型
* @author Looly
* @since 5.6.0
*/
public class FuncKeyMap<K, V> extends CustomKeyMap<K, V> {
private static final long serialVersionUID = 1L;
private Function<Object, K> keyFunc;
// ------------------------------------------------------------------------- Constructor start
/**
* 构造
*
* @param m Map
* @param keyFunc 自定义KEY的函数
*/
public FuncKeyMap(Map<K, V> m, Function<Object, K> keyFunc) {
super(m);
}
// ------------------------------------------------------------------------- Constructor end
/**
* 将Key转为驼峰风格如果key为字符串的话
*
* @param key KEY
* @return 驼峰Key
*/
@Override
protected Object customKey(Object key) {
if (null != this.keyFunc) {
return keyFunc.apply(key);
}
return key;
}
}

View File

@@ -0,0 +1,116 @@
package cn.hutool.core.text;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 字符串模式匹配,使用${XXXXX}作为变量,例如:
*
* <pre>
* pattern: ${name}-${age}-${gender}-${country}-${province}-${city}-${status}
* text: "小明-19-男-中国-河南-郑州-已婚"
* result: {name=小明, age=19, gender=男, country=中国, province=河南, city=郑州, status=已婚}
* </pre>
*
* @author looly
* @since 5.6.0
*/
public class StrMatcher {
List<String> patterns;
/**
* 构造
*
* @param pattern 模式,变量用${XXX}占位
*/
public StrMatcher(String pattern) {
this.patterns = parse(pattern);
}
/**
* 匹配并提取匹配到的内容
* @param text 被匹配的文本
* @return 匹配的mapkey为变量名value为匹配到的值
*/
public Map<String, String> match(String text) {
final HashMap<String, String> result = MapUtil.newHashMap(true);
int from = 0;
String key = null;
int to;
for (String part : patterns) {
if (StrUtil.isWrap(part, "${", "}")) {
// 变量
key = StrUtil.sub(part, 2, part.length() - 1);
} else {
to = text.indexOf(part, from);
if(to < 0){
//普通字符串未匹配到,说明整个模式不能匹配,返回空
return MapUtil.empty();
}
if (null != key && to > from) {
// 变量对应部分有内容
result.put(key, text.substring(from, to));
}
// 下一个起始点是普通字符串的末尾
from = to + part.length();
key = null;
}
}
if (null != key && from < text.length()) {
// 变量对应部分有内容
result.put(key, text.substring(from));
}
return result;
}
/**
* 解析表达式
* @param pattern 表达式,使用${XXXX}作为变量占位符
* @return 表达式
*/
private static List<String> parse(String pattern) {
List<String> patterns = new ArrayList<>();
final int length = pattern.length();
char c = 0;
char pre;
boolean inVar = false;
StrBuilder part = StrUtil.strBuilder();
for (int i = 0; i < length; i++) {
pre = c;
c = pattern.charAt(i);
if (inVar) {
part.append(c);
if ('}' == c) {
// 变量结束
inVar = false;
patterns.add(part.toString());
part.clear();
}
} else if ('{' == c && '$' == pre) {
// 变量开始
inVar = true;
final String preText = part.subString(0, part.length() - 1);
if (StrUtil.isNotEmpty(preText)) {
patterns.add(preText);
}
part.reset().append(pre).append(c);
} else {
// 普通字符
part.append(c);
}
}
if (part.length() > 0) {
patterns.add(part.toString());
}
return patterns;
}
}

View File

@@ -200,7 +200,7 @@ public class ExecutorBuilder implements Builder<ThreadPoolExecutor> {
/**
* 创建ExecutorBuilder开始构建
*
* @return {@link ExecutorBuilder}
* @return this
*/
public static ExecutorBuilder create() {
return new ExecutorBuilder();
@@ -227,7 +227,7 @@ public class ExecutorBuilder implements Builder<ThreadPoolExecutor> {
/**
* 构建ThreadPoolExecutor
*
* @param builder {@link ExecutorBuilder}
* @param builder this
* @return {@link ThreadPoolExecutor}
*/
private static ThreadPoolExecutor build(ExecutorBuilder builder) {

View File

@@ -294,7 +294,7 @@ public class ClassUtil {
}
/**
* 查找指定Public方法 如果找不到对应的方法或方法不为public的则返回<code>null</code>
* 查找指定Public方法 如果找不到对应的方法或方法不为public的则返回{@code null}
*
* @param clazz 类
* @param methodName 方法名
@@ -341,7 +341,7 @@ public class ClassUtil {
}
/**
* 查找指定类中的所有方法包括非public方法也包括父类和Object类的方法 找不到方法会返回<code>null</code>
* 查找指定类中的所有方法包括非public方法也包括父类和Object类的方法 找不到方法会返回{@code null}
*
* @param clazz 被查找的类
* @param methodName 方法名
@@ -356,7 +356,7 @@ public class ClassUtil {
// ----------------------------------------------------------------------------------------- Field
/**
* 查找指定类中的所有字段包括非public字段 字段不存在则返回<code>null</code>
* 查找指定类中的所有字段包括非public字段 字段不存在则返回{@code null}
*
* @param clazz 被查找字段的类
* @param fieldName 字段名
@@ -558,7 +558,7 @@ public class ClassUtil {
}
/**
* 比较判断types1和types2两组类如果types1中所有的类都与types2对应位置的类相同或者是其父类或接口则返回<code>true</code>
* 比较判断types1和types2两组类如果types1中所有的类都与types2对应位置的类相同或者是其父类或接口则返回{@code true}
*
* @param types1 类组1
* @param types2 类组2
@@ -626,7 +626,7 @@ public class ClassUtil {
* 非单例模式,如果是非静态方法,每次创建一个新对象
*
* @param <T> 对象类型
* @param classNameWithMethodName 类名和方法名表达式,类名与方法名用<code>.</code>或<code>#</code>连接 例如com.xiaoleilu.hutool.StrUtil.isEmpty 或 com.xiaoleilu.hutool.StrUtil#isEmpty
* @param classNameWithMethodName 类名和方法名表达式,类名与方法名用{@code .}或{@code #}连接 例如com.xiaoleilu.hutool.StrUtil.isEmpty 或 com.xiaoleilu.hutool.StrUtil#isEmpty
* @param args 参数,必须严格对应指定方法的参数类型和数量
* @return 返回结果
*/
@@ -1092,4 +1092,4 @@ public class ClassUtil {
}
return location.getPath();
}
}
}

View File

@@ -26,7 +26,7 @@ public class HexUtil {
/**
* 判断给定字符串是否为16进制数<br>
* 如果是,需要使用对应数字类型对象的<code>decode</code>方法解码<br>
* 如果是,需要使用对应数字类型对象的{@code decode}方法解码<br>
* 例如:{@code Integer.decode}方法解码int类型的16进制数字
*
* @param value 值
@@ -74,7 +74,7 @@ public class HexUtil {
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @param toLowerCase <code>true</code> 传换成小写格式 <code>false</code> 传换成大写格式
* @param toLowerCase {@code true} 传换成小写格式 {@code false} 传换成大写格式
* @return 十六进制char[]
*/
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
@@ -116,7 +116,7 @@ public class HexUtil {
* 将字节数组转换为十六进制字符串
*
* @param data byte[]
* @param toLowerCase <code>true</code> 传换成小写格式 <code>false</code> 传换成大写格式
* @param toLowerCase {@code true} 传换成小写格式 {@code false} 传换成大写格式
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data, boolean toLowerCase) {
@@ -421,4 +421,4 @@ public class HexUtil {
return digit;
}
// ---------------------------------------------------------------------------------------- Private method end
}
}

View File

@@ -1428,10 +1428,62 @@ public class NumberUtil {
// ------------------------------------------------------------------------------------------- others
/**
* 计算阶乘
* <p>
* n! = n * (n-1) * ... * 2 * 1
* </p>
*
* @param n 阶乘起始
* @return 结果
* @since 5.6.0
*/
public static BigInteger factorial(BigInteger n) {
if(n.equals(BigInteger.ZERO)){
return BigInteger.ONE;
}
return factorial(n, BigInteger.ZERO);
}
/**
* 计算范围阶乘
* <p>
* factorial(start, end) = start * (start - 1) * ... * (end - 1)
* factorial(start, end) = start * (start - 1) * ... * (end + 1)
* </p>
*
* @param start 阶乘起始(包含)
* @param end 阶乘结束,必须小于起始(不包括)
* @return 结果
* @since 5.6.0
*/
public static BigInteger factorial(BigInteger start, BigInteger end) {
Assert.notNull(start, "Factorial start must be not null!");
Assert.notNull(end, "Factorial end must be not null!");
if(start.compareTo(BigInteger.ZERO) < 0 || end.compareTo(BigInteger.ZERO) < 0){
throw new IllegalArgumentException(StrUtil.format("Factorial start and end both must be > 0, but got start={}, end={}", start, end));
}
if (start.equals(BigInteger.ZERO)){
start = BigInteger.ONE;
}
if(end.compareTo(BigInteger.ONE) < 0){
end = BigInteger.ONE;
}
BigInteger result = start;
end = end.add(BigInteger.ONE);
while(start.compareTo(end) > 0) {
start = start.subtract(BigInteger.ONE);
result = result.multiply(start);
}
return result;
}
/**
* 计算范围阶乘
* <p>
* factorial(start, end) = start * (start - 1) * ... * (end + 1)
* </p>
*
* @param start 阶乘起始(包含)

View File

@@ -3,8 +3,6 @@ package cn.hutool.core.util;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.lang.Validator;
import java.util.regex.Pattern;
/**
* 手机号工具类

View File

@@ -3,8 +3,6 @@ package cn.hutool.core.codec;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.codec.BCD;
public class BCDTest {
@Test

View File

@@ -11,6 +11,7 @@ import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -694,4 +695,14 @@ public class CollUtilTest {
Assert.assertEquals(0, CollUtil.page(3, 5, objects).size());
}
@Test
public void subtractToListTest(){
List<Long> list1 = Arrays.asList(1L, 2L, 3L);
List<Long> list2 = Arrays.asList(2L, 3L);
List<Long> result = CollUtil.subtractToList(list1, list2);
Assert.assertEquals(1, result.size());
Assert.assertEquals(1L, result.get(0), 1);
}
}

View File

@@ -101,4 +101,15 @@ public class ListUtilTest {
int[] d1 = ListUtil.page(0,8,a).stream().mapToInt(Integer::valueOf).toArray();
Assert.assertArrayEquals(new int[]{1,2,3,4,5},d1);
}
@Test
public void subTest(){
final List<Integer> of = ListUtil.of(1, 2, 3, 4);
final List<Integer> sub = ListUtil.sub(of, 2, 4);
sub.remove(0);
// 对子列表操作不影响原列表
Assert.assertEquals(4, of.size());
Assert.assertEquals(1, sub.size());
}
}

View File

@@ -5,7 +5,6 @@ import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.CharsetUtil;
/**

View File

@@ -3,9 +3,6 @@ package cn.hutool.core.convert;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.convert.Converter;
import cn.hutool.core.convert.ConverterRegistry;
/**
* ConverterRegistry 单元测试
* @author Looly

View File

@@ -1,25 +1,34 @@
package cn.hutool.core.convert;
import org.junit.Assert;
import org.junit.Test;
public class NumberWordFormatTest {
@Test
public void formatTest() {
String format = NumberWordFormatter.format(100.23);
Assert.assertEquals("ONE HUNDRED AND CENTS TWENTY THREE ONLY", format);
String format2 = NumberWordFormatter.format("2100.00");
Assert.assertEquals("TWO THOUSAND ONE HUNDRED AND CENTS ONLY", format2);
String format3 = NumberWordFormatter.formatValue(4384324, false);
Assert.assertEquals("4.38m", format3);
String format4 = NumberWordFormatter.formatValue(4384324);
Assert.assertEquals("438.43w", format4);
String format5 = NumberWordFormatter.formatValue(438);
Assert.assertEquals("438", format5);
}
}
package cn.hutool.core.convert;
import org.junit.Assert;
import org.junit.Test;
public class NumberWordFormatTest {
@Test
public void formatTest() {
String format = NumberWordFormatter.format(100.23);
Assert.assertEquals("ONE HUNDRED AND CENTS TWENTY THREE ONLY", format);
String format2 = NumberWordFormatter.format("2100.00");
Assert.assertEquals("TWO THOUSAND ONE HUNDRED AND CENTS ONLY", format2);
}
@Test
public void formatSimpleTest() {
String format1 = NumberWordFormatter.formatSimple(1200, false);
Assert.assertEquals("1.2k", format1);
String format2 = NumberWordFormatter.formatSimple(4384324, false);
Assert.assertEquals("4.38m", format2);
String format3 = NumberWordFormatter.formatSimple(4384324, true);
Assert.assertEquals("438.43w", format3);
String format4 = NumberWordFormatter.formatSimple(4384324);
Assert.assertEquals("438.43w", format4);
String format5 = NumberWordFormatter.formatSimple(438);
Assert.assertEquals("438", format5);
}
}

View File

@@ -6,6 +6,9 @@ import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 文件类型判断单元测试
@@ -13,19 +16,19 @@ import java.io.File;
*
*/
public class FileTypeUtilTest {
@Test
@Ignore
public void fileTypeUtilTest() {
File file = FileUtil.file("hutool.jpg");
String type = FileTypeUtil.getType(file);
Assert.assertEquals("jpg", type);
FileTypeUtil.putFileType("ffd8ffe000104a464946", "new_jpg");
String newType = FileTypeUtil.getType(file);
Assert.assertEquals("new_jpg", newType);
}
@Test
@Ignore
public void emptyTest() {
@@ -41,4 +44,16 @@ public class FileTypeUtilTest {
String type = FileTypeUtil.getType(file);
Console.log(type);
}
@Test
@Ignore
public void ofdTest() {
File file = FileUtil.file("e:/test.ofd");
String hex = IoUtil.readHex28Upper(FileUtil.getInputStream(file));
Console.log(hex);
String type = FileTypeUtil.getType(file);
Console.log(type);
Assert.assertEquals("ofd", type);
}
}

View File

@@ -51,7 +51,13 @@ public class DataSizeUtilTest {
@Test
public void formatTest(){
final String format = DataSizeUtil.format(Long.MAX_VALUE);
Assert.assertEquals("8,192 EB", format);
String format = DataSizeUtil.format(Long.MAX_VALUE);
Assert.assertEquals("8 EB", format);
format = DataSizeUtil.format(1024L * 1024 * 1024 * 1024 * 1024);
Assert.assertEquals("1 PB", format);
format = DataSizeUtil.format(1024L * 1024 * 1024 * 1024);
Assert.assertEquals("1 TB", format);
}
}

View File

@@ -1,12 +1,12 @@
package cn.hutool.core.lang;
import java.util.Set;
import org.junit.Ignore;
import org.junit.Test;
import java.util.Set;
public class ClassScanerTest {
@Test
@Ignore
public void scanTest() {

View File

@@ -0,0 +1,35 @@
package cn.hutool.core.text;
import cn.hutool.core.lang.Console;
import org.junit.Assert;
import org.junit.Test;
import java.util.Map;
public class StrMatcherTest {
@Test
public void matcherTest(){
final StrMatcher strMatcher = new StrMatcher("${name}-${age}-${gender}-${country}-${province}-${city}-${status}");
final Map<String, String> match = strMatcher.match("小明-19-男-中国-河南-郑州-已婚");
Console.log(match);
}
@Test
public void matcherTest2(){
// 当有无匹配项的时候,按照全不匹配对待
final StrMatcher strMatcher = new StrMatcher("${name}-${age}-${gender}-${country}-${province}-${city}-${status}");
final Map<String, String> match = strMatcher.match("小明-19-男-中国-河南-郑州");
Assert.assertEquals(0, match.size());
}
@Test
public void matcherTest3(){
// 当有无匹配项的时候,按照全不匹配对待
final StrMatcher strMatcher = new StrMatcher("${name}经过${year}年");
final Map<String, String> match = strMatcher.match("小明经过20年成长为一个大人。");
Console.log(match);
Assert.assertEquals("小明", match.get("name"));
Assert.assertEquals("20", match.get("year"));
}
}

View File

@@ -17,7 +17,7 @@ import java.util.concurrent.CountDownLatch;
/**
* {@link IdUtil} 单元测试
*
*
* @author looly
*
*/
@@ -31,12 +31,12 @@ public class IdUtilTest {
String randomUUID = IdUtil.randomUUID();
Assert.assertEquals(36, randomUUID.length());
}
@Test
public void fastUUIDTest() {
String simpleUUID = IdUtil.fastSimpleUUID();
Assert.assertEquals(32, simpleUUID.length());
String randomUUID = IdUtil.fastUUID();
Assert.assertEquals(36, randomUUID.length());
}
@@ -60,25 +60,26 @@ public class IdUtilTest {
}
Console.log(timer.interval());
}
@Test
public void objectIdTest() {
String id = IdUtil.objectId();
Assert.assertEquals(24, id.length());
}
@Test
public void createSnowflakeTest() {
Snowflake snowflake = IdUtil.createSnowflake(1, 1);
long id = snowflake.nextId();
Assert.assertTrue(id > 0);
}
@Test
@Ignore
public void snowflakeBenchTest() {
final Set<Long> set = new ConcurrentHashSet<>();
final Snowflake snowflake = IdUtil.createSnowflake(1, 1);
//线程数
int threadCount = 100;
//每个线程生成的ID数
@@ -94,7 +95,7 @@ public class IdUtilTest {
latch.countDown();
});
}
//等待全部线程结束
try {
latch.await();
@@ -103,11 +104,12 @@ public class IdUtilTest {
}
Assert.assertEquals(threadCount * idCountPerThread, set.size());
}
@Test
@Ignore
public void snowflakeBenchTest2() {
final Set<Long> set = new ConcurrentHashSet<>();
//线程数
int threadCount = 100;
//每个线程生成的ID数
@@ -123,7 +125,7 @@ public class IdUtilTest {
latch.countDown();
});
}
//等待全部线程结束
try {
latch.await();

View File

@@ -5,17 +5,18 @@ import org.junit.Assert;
import org.junit.Test;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Set;
/**
* {@link NumberUtil} 单元测试类
*
*
* @author Looly
*
*/
public class NumberUtilTest {
@Test
public void addTest() {
Float a = 3.15f;
@@ -23,7 +24,7 @@ public class NumberUtilTest {
double result = NumberUtil.add(a, b).doubleValue();
Assert.assertEquals(7.37, result, 2);
}
@Test
public void addTest2() {
double a = 3.15f;
@@ -31,7 +32,7 @@ public class NumberUtilTest {
double result = NumberUtil.add(a, b);
Assert.assertEquals(7.37, result, 2);
}
@Test
public void addTest3() {
float a = 3.15f;
@@ -39,13 +40,13 @@ public class NumberUtilTest {
double result = NumberUtil.add(a, b, a, b).doubleValue();
Assert.assertEquals(14.74, result, 2);
}
@Test
public void addTest4() {
BigDecimal result = NumberUtil.add(new BigDecimal("133"), new BigDecimal("331"));
Assert.assertEquals(new BigDecimal("464"), result);
}
@Test
public void isIntegerTest() {
Assert.assertTrue(NumberUtil.isInteger("-12"));
@@ -54,7 +55,7 @@ public class NumberUtilTest {
Assert.assertTrue(NumberUtil.isInteger("0"));
Assert.assertFalse(NumberUtil.isInteger("23.4"));
}
@Test
public void isLongTest() {
Assert.assertTrue(NumberUtil.isLong("-12"));
@@ -63,7 +64,7 @@ public class NumberUtilTest {
Assert.assertTrue(NumberUtil.isLong("0"));
Assert.assertFalse(NumberUtil.isLong("23.4"));
}
@Test
public void isNumberTest() {
Assert.assertTrue(NumberUtil.isNumber("28.55"));
@@ -78,7 +79,7 @@ public class NumberUtilTest {
double result = NumberUtil.div(0, 1);
Assert.assertEquals(0.0, result, 0);
}
@Test
public void roundTest() {
@@ -93,7 +94,7 @@ public class NumberUtilTest {
String round4 = NumberUtil.roundStr("2.675", 2);
Assert.assertEquals("2.68", round3);
Assert.assertEquals("2.68", round4);
// 四舍六入五成双
String round31 = NumberUtil.roundStr(4.245, 2, RoundingMode.HALF_EVEN);
String round41 = NumberUtil.roundStr("4.2451", 2, RoundingMode.HALF_EVEN);
@@ -105,7 +106,7 @@ public class NumberUtilTest {
String round6 = NumberUtil.roundStr("2.6005", 2);
Assert.assertEquals("2.60", round5);
Assert.assertEquals("2.60", round6);
// 补0
String round7 = NumberUtil.roundStr(2.600, 2);
String round8 = NumberUtil.roundStr("2.600", 2);
@@ -118,7 +119,7 @@ public class NumberUtilTest {
String roundStr = NumberUtil.roundStr(2.647, 2);
Assert.assertEquals(roundStr, "2.65");
}
@Test
public void roundHalfEvenTest() {
String roundStr = NumberUtil.roundHalfEven(4.245, 2).toString();
@@ -129,7 +130,7 @@ public class NumberUtilTest {
Assert.assertEquals(roundStr, "4.25");
roundStr = NumberUtil.roundHalfEven(4.2250, 2).toString();
Assert.assertEquals(roundStr, "4.22");
roundStr = NumberUtil.roundHalfEven(1.2050, 2).toString();
Assert.assertEquals(roundStr, "1.20");
roundStr = NumberUtil.roundHalfEven(1.2150, 2).toString();
@@ -159,14 +160,14 @@ public class NumberUtilTest {
String format = NumberUtil.decimalFormat(",###", c);
Assert.assertEquals("299,792,458", format);
}
@Test
public void decimalFormatMoneyTest() {
double c = 299792400.543534534;
String format = NumberUtil.decimalFormatMoney(c);
Assert.assertEquals("299,792,400.54", format);
double value = 0.5;
String money = NumberUtil.decimalFormatMoney(value);
Assert.assertEquals("0.50", money);
@@ -176,17 +177,17 @@ public class NumberUtilTest {
public void equalsTest() {
Assert.assertTrue(NumberUtil.equals(new BigDecimal("0.00"), BigDecimal.ZERO));
}
@Test
public void formatPercentTest() {
String str = NumberUtil.formatPercent(0.33543545, 2);
Assert.assertEquals("33.54%", str);
}
@Test
public void toBigDecimalTest() {
double a = 3.14;
BigDecimal bigDecimal = NumberUtil.toBigDecimal(a);
Assert.assertEquals("3.14", bigDecimal.toString());
@@ -208,7 +209,7 @@ public class NumberUtilTest {
int min = NumberUtil.min(5,4,3,6,1);
Assert.assertEquals(1, min);
}
@Test
public void parseIntTest() {
int number = NumberUtil.parseInt("0xFF");
@@ -258,7 +259,7 @@ public class NumberUtilTest {
Number v2 = NumberUtil.parseNumber("1,482.00D");
Assert.assertEquals(1482L, v2);
}
@Test
public void parseLongTest() {
long number = NumberUtil.parseLong("0xFF");
@@ -303,18 +304,36 @@ public class NumberUtilTest {
Assert.assertEquals(120, factorial);
factorial = NumberUtil.factorial(5, 1);
Assert.assertEquals(120, factorial);
Assert.assertEquals(5, NumberUtil.factorial(5, 4));
Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(20, 0));
}
@Test
public void factorialTest2(){
long factorial = NumberUtil.factorial(new BigInteger("0")).longValue();
Assert.assertEquals(1, factorial);
Assert.assertEquals(1L, NumberUtil.factorial(new BigInteger("1")).longValue());
Assert.assertEquals(1307674368000L, NumberUtil.factorial(new BigInteger("15")).longValue());
Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(20));
factorial = NumberUtil.factorial(new BigInteger("5"), new BigInteger("0")).longValue();
Assert.assertEquals(120, factorial);
factorial = NumberUtil.factorial(new BigInteger("5"), BigInteger.ONE).longValue();
Assert.assertEquals(120, factorial);
Assert.assertEquals(5, NumberUtil.factorial(new BigInteger("5"), new BigInteger("4")).longValue());
Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(new BigInteger("20"), BigInteger.ZERO).longValue());
}
@Test
public void mulTest(){
final BigDecimal mul = NumberUtil.mul(new BigDecimal("10"), null);
Assert.assertEquals(BigDecimal.ZERO, mul);
}
@Test
public void isPowerOfTwoTest() {
Assert.assertFalse(NumberUtil.isPowerOfTwo(-1));