mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-08-18 20:38:02 +08:00
fix comment
This commit is contained in:
@@ -44,10 +44,11 @@ public class AnnotationUtil {
|
||||
* 获取指定注解
|
||||
*
|
||||
* @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
|
||||
* @param isToCombination 是否为转换为组合注解
|
||||
* @return 注解对象
|
||||
*/
|
||||
public static Annotation[] getAnnotations(AnnotatedElement annotationEle, boolean isCombination) {
|
||||
return (null == annotationEle) ? null : (isCombination ? toCombination(annotationEle) : annotationEle).getAnnotations();
|
||||
public static Annotation[] getAnnotations(AnnotatedElement annotationEle, boolean isToCombination) {
|
||||
return (null == annotationEle) ? null : (isToCombination ? toCombination(annotationEle) : annotationEle).getAnnotations();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -87,7 +87,7 @@ public class BeanUtil {
|
||||
final Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
if(method.getName().startsWith("get") || method.getName().startsWith("is")) {
|
||||
if (method.getName().startsWith("get") || method.getName().startsWith("is")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -160,6 +160,7 @@ public class BeanUtil {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------- PropertyDescriptor
|
||||
|
||||
/**
|
||||
* 获得Bean字段描述数组
|
||||
*
|
||||
@@ -277,7 +278,7 @@ public class BeanUtil {
|
||||
* @param fieldNameOrIndex 字段名或序号,序号支持负数
|
||||
* @param value 值
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static void setFieldValue(Object bean, String fieldNameOrIndex, Object value) {
|
||||
if (bean instanceof Map) {
|
||||
((Map) bean).put(fieldNameOrIndex, value);
|
||||
@@ -309,6 +310,7 @@ public class BeanUtil {
|
||||
*
|
||||
* @param bean Bean对象,支持Map、List、Collection、Array
|
||||
* @param expression 表达式,例如:person.friend[5].name
|
||||
* @param value 属性值
|
||||
* @see BeanPath#get(Object)
|
||||
* @since 4.0.6
|
||||
*/
|
||||
@@ -317,6 +319,7 @@ public class BeanUtil {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------- mapToBean
|
||||
|
||||
/**
|
||||
* Map转换为Bean对象
|
||||
*
|
||||
@@ -358,6 +361,7 @@ public class BeanUtil {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------- fillBeanWithMap
|
||||
|
||||
/**
|
||||
* 使用Map填充Bean对象
|
||||
*
|
||||
@@ -433,9 +437,11 @@ public class BeanUtil {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------- fillBean
|
||||
|
||||
/**
|
||||
* 对象或Map转Bean
|
||||
*
|
||||
* @param <T> 转换的Bean类型
|
||||
* @param source Bean对象或Map
|
||||
* @param clazz 目标的Bean类型
|
||||
* @return Bean对象
|
||||
@@ -478,6 +484,7 @@ public class BeanUtil {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------- beanToMap
|
||||
|
||||
/**
|
||||
* 对象转Map,不进行驼峰转下划线,不忽略值为空的字段
|
||||
*
|
||||
@@ -497,7 +504,7 @@ public class BeanUtil {
|
||||
* @return Map
|
||||
*/
|
||||
public static Map<String, Object> beanToMap(Object bean, boolean isToUnderlineCase, boolean ignoreNullValue) {
|
||||
return beanToMap(bean, new LinkedHashMap<String, Object>(), isToUnderlineCase, ignoreNullValue);
|
||||
return beanToMap(bean, new LinkedHashMap<>(), isToUnderlineCase, ignoreNullValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -575,6 +582,7 @@ public class BeanUtil {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------- copyProperties
|
||||
|
||||
/**
|
||||
* 复制Bean对象属性
|
||||
*
|
||||
@@ -639,13 +647,14 @@ public class BeanUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 把Bean里面的String属性做trim操作。
|
||||
*
|
||||
* 把Bean里面的String属性做trim操作。此方法直接对传入的Bean做修改。
|
||||
* <p>
|
||||
* 通常bean直接用来绑定页面的input,用户的输入可能首尾存在空格,通常保存数据库前需要把首尾空格去掉
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param bean Bean对象
|
||||
* @param ignoreFields 不需要trim的Field名称列表(不区分大小写)
|
||||
* @return 处理后的Bean对象
|
||||
*/
|
||||
public static <T> T trimStrFields(T bean, String... ignoreFields) {
|
||||
if (bean == null) {
|
||||
|
@@ -5,7 +5,6 @@ package cn.hutool.core.codec;
|
||||
* 算法来自:https://github.com/zhaorenjie110/SymmetricEncryptionAndDecryption
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class Caesar {
|
||||
|
||||
@@ -36,15 +35,16 @@ public class Caesar {
|
||||
/**
|
||||
* 传入明文解密到密文
|
||||
*
|
||||
* @param ciphertext 密文
|
||||
* @param cipherText 密文
|
||||
* @param offset 偏移量
|
||||
* @return 解密后的内容
|
||||
*/
|
||||
public static String decode(String ciphertext, int offset) {
|
||||
final int len = ciphertext.length();
|
||||
final char[] plain = ciphertext.toCharArray();
|
||||
public static String decode(String cipherText, int offset) {
|
||||
final int len = cipherText.length();
|
||||
final char[] plain = cipherText.toCharArray();
|
||||
char c;
|
||||
for (int i = 0; i < len; i++) {
|
||||
c = ciphertext.charAt(i);
|
||||
c = cipherText.charAt(i);
|
||||
if (false == Character.isLetter(c)) {
|
||||
continue;
|
||||
}
|
||||
@@ -54,6 +54,7 @@ public class Caesar {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 加密轮盘
|
||||
*
|
||||
|
@@ -55,8 +55,8 @@ import cn.hutool.core.util.TypeUtil;
|
||||
* 由于{@link Collection} 实现了{@link Iterable}接口,因此部分工具此类不提供,而是在{@link IterUtil} 中提供
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @since 3.1.1
|
||||
* @see IterUtil
|
||||
* @since 3.1.1
|
||||
*/
|
||||
public class CollUtil {
|
||||
|
||||
@@ -249,8 +249,8 @@ public class CollUtil {
|
||||
* @param coll1 集合1
|
||||
* @param coll2 集合2
|
||||
* @return 其中一个集合在另一个集合中是否至少包含一个元素
|
||||
* @since 2.1
|
||||
* @see #intersection
|
||||
* @since 2.1
|
||||
*/
|
||||
public static boolean containsAny(Collection<?> coll1, Collection<?> coll2) {
|
||||
if (isEmpty(coll1) || isEmpty(coll2)) {
|
||||
@@ -397,6 +397,7 @@ public class CollUtil {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- new HashMap
|
||||
|
||||
/**
|
||||
* 新建一个HashMap
|
||||
*
|
||||
@@ -417,8 +418,8 @@ public class CollUtil {
|
||||
* @param size 初始大小,由于默认负载因子0.75,传入的size会实际初始大小为size / 0.75
|
||||
* @param isOrder Map的Key是否有序,有序返回 {@link LinkedHashMap},否则返回 {@link HashMap}
|
||||
* @return HashMap对象
|
||||
* @since 3.0.4
|
||||
* @see MapUtil#newHashMap(int, boolean)
|
||||
* @since 3.0.4
|
||||
*/
|
||||
public static <K, V> HashMap<K, V> newHashMap(int size, boolean isOrder) {
|
||||
return MapUtil.newHashMap(size, isOrder);
|
||||
@@ -438,6 +439,7 @@ public class CollUtil {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- new HashSet
|
||||
|
||||
/**
|
||||
* 新建一个HashSet
|
||||
*
|
||||
@@ -474,10 +476,10 @@ public class CollUtil {
|
||||
@SafeVarargs
|
||||
public static <T> HashSet<T> newHashSet(boolean isSorted, T... ts) {
|
||||
if (null == ts) {
|
||||
return isSorted ? new LinkedHashSet<T>() : new HashSet<T>();
|
||||
return isSorted ? new LinkedHashSet<>() : new HashSet<>();
|
||||
}
|
||||
int initialCapacity = Math.max((int) (ts.length / .75f) + 1, 16);
|
||||
final HashSet<T> set = isSorted ? new LinkedHashSet<T>(initialCapacity) : new HashSet<T>(initialCapacity);
|
||||
final HashSet<T> set = isSorted ? new LinkedHashSet<>(initialCapacity) : new HashSet<>(initialCapacity);
|
||||
Collections.addAll(set, ts);
|
||||
return set;
|
||||
}
|
||||
@@ -518,7 +520,7 @@ public class CollUtil {
|
||||
if (null == iter) {
|
||||
return newHashSet(isSorted, (T[]) null);
|
||||
}
|
||||
final HashSet<T> set = isSorted ? new LinkedHashSet<T>() : new HashSet<T>();
|
||||
final HashSet<T> set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
|
||||
while (iter.hasNext()) {
|
||||
set.add(iter.next());
|
||||
}
|
||||
@@ -530,22 +532,23 @@ public class CollUtil {
|
||||
*
|
||||
* @param <T> 集合元素类型
|
||||
* @param isSorted 是否有序,有序返回 {@link LinkedHashSet},否则返回{@link HashSet}
|
||||
* @param enumration {@link Enumeration}
|
||||
* @param enumeration {@link Enumeration}
|
||||
* @return HashSet对象
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public static <T> HashSet<T> newHashSet(boolean isSorted, Enumeration<T> enumration) {
|
||||
if (null == enumration) {
|
||||
public static <T> HashSet<T> newHashSet(boolean isSorted, Enumeration<T> enumeration) {
|
||||
if (null == enumeration) {
|
||||
return newHashSet(isSorted, (T[]) null);
|
||||
}
|
||||
final HashSet<T> set = isSorted ? new LinkedHashSet<T>() : new HashSet<T>();
|
||||
while (enumration.hasMoreElements()) {
|
||||
set.add(enumration.nextElement());
|
||||
final HashSet<T> set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
set.add(enumeration.nextElement());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- List
|
||||
|
||||
/**
|
||||
* 新建一个空List
|
||||
*
|
||||
@@ -555,7 +558,7 @@ public class CollUtil {
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public static <T> List<T> list(boolean isLinked) {
|
||||
return isLinked ? new LinkedList<T>() : new ArrayList<T>();
|
||||
return isLinked ? new LinkedList<>() : new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -572,7 +575,7 @@ public class CollUtil {
|
||||
if (ArrayUtil.isEmpty(values)) {
|
||||
return list(isLinked);
|
||||
}
|
||||
final List<T> arrayList = isLinked ? new LinkedList<T>() : new ArrayList<T>(values.length);
|
||||
final List<T> arrayList = isLinked ? new LinkedList<>() : new ArrayList<>(values.length);
|
||||
Collections.addAll(arrayList, values);
|
||||
return arrayList;
|
||||
}
|
||||
@@ -726,6 +729,7 @@ public class CollUtil {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------new LinkedList
|
||||
|
||||
/**
|
||||
* 新建LinkedList
|
||||
*
|
||||
@@ -747,13 +751,14 @@ public class CollUtil {
|
||||
* @return {@link CopyOnWriteArrayList}
|
||||
*/
|
||||
public static <T> CopyOnWriteArrayList<T> newCopyOnWriteArrayList(Collection<T> collection) {
|
||||
return (null == collection) ? (new CopyOnWriteArrayList<T>()) : (new CopyOnWriteArrayList<>(collection));
|
||||
return (null == collection) ? (new CopyOnWriteArrayList<>()) : (new CopyOnWriteArrayList<>(collection));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建{@link BlockingQueue}<br>
|
||||
* 在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。
|
||||
*
|
||||
* @param <T> 集合类型
|
||||
* @param capacity 容量
|
||||
* @param isLinked 是否为链表形式
|
||||
* @return {@link BlockingQueue}
|
||||
@@ -777,7 +782,7 @@ public class CollUtil {
|
||||
* @return 集合类型对应的实例
|
||||
* @since 3.0.8
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static <T> Collection<T> create(Class<?> collectionType) {
|
||||
Collection<T> list;
|
||||
if (collectionType.isAssignableFrom(AbstractCollection.class)) {
|
||||
@@ -1023,7 +1028,7 @@ public class CollUtil {
|
||||
return list;
|
||||
}
|
||||
|
||||
final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<T>() : new ArrayList<T>(list.size());
|
||||
final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<>() : new ArrayList<>(list.size());
|
||||
T modified;
|
||||
for (T t : list) {
|
||||
modified = editor.edit(t);
|
||||
@@ -1087,7 +1092,7 @@ public class CollUtil {
|
||||
if (null == list || null == filter) {
|
||||
return list;
|
||||
}
|
||||
final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<T>() : new ArrayList<T>(list.size());
|
||||
final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<>() : new ArrayList<>(list.size());
|
||||
for (T t : list) {
|
||||
if (filter.accept(t)) {
|
||||
list2.add(t);
|
||||
@@ -1147,6 +1152,8 @@ public class CollUtil {
|
||||
/**
|
||||
* 去除{@code null}或者"" 元素,此方法直接修改原集合
|
||||
*
|
||||
* @param <T> 集合类型
|
||||
* @param <E> 集合元素类型
|
||||
* @param collection 集合
|
||||
* @return 处理后的集合
|
||||
* @since 3.2.2
|
||||
@@ -1163,6 +1170,8 @@ public class CollUtil {
|
||||
/**
|
||||
* 去除{@code null}或者""或者空白字符串 元素,此方法直接修改原集合
|
||||
*
|
||||
* @param <T> 集合类型
|
||||
* @param <E> 集合元素类型
|
||||
* @param collection 集合
|
||||
* @return 处理后的集合
|
||||
* @since 3.2.2
|
||||
@@ -1351,8 +1360,8 @@ public class CollUtil {
|
||||
* @param map Map
|
||||
* @param filter 编辑器接口
|
||||
* @return 过滤后的Map
|
||||
* @since 3.1.0
|
||||
* @see MapUtil#filter(Map, Filter)
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static <K, V> Map<K, V> filter(Map<K, V> map, Filter<Entry<K, V>> filter) {
|
||||
return MapUtil.filter(map, filter);
|
||||
@@ -1379,6 +1388,7 @@ public class CollUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------- isEmpty
|
||||
|
||||
/**
|
||||
* 集合是否为空
|
||||
*
|
||||
@@ -1399,7 +1409,7 @@ public class CollUtil {
|
||||
* @return 非空(empty)的原集合或默认集合
|
||||
* @since 4.6.9
|
||||
*/
|
||||
public static <T extends Collection<E>, E> T defaultIfEmpty(T collection, T defaultCollection){
|
||||
public static <T extends Collection<E>, E> T defaultIfEmpty(T collection, T defaultCollection) {
|
||||
return isEmpty(collection) ? defaultCollection : collection;
|
||||
}
|
||||
|
||||
@@ -1506,8 +1516,8 @@ public class CollUtil {
|
||||
*
|
||||
* @param iterable 被检查的Iterable对象,如果为{@code null} 返回false
|
||||
* @return 是否包含{@code null}元素
|
||||
* @since 3.0.7
|
||||
* @see IterUtil#hasNull(Iterable)
|
||||
* @since 3.0.7
|
||||
*/
|
||||
public static boolean hasNull(Iterable<?> iterable) {
|
||||
return IterUtil.hasNull(iterable);
|
||||
@@ -1612,13 +1622,13 @@ public class CollUtil {
|
||||
* {"GREEN", "#00FF00"},
|
||||
* {"BLUE", "#0000FF"}});
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 参考:commons-lang
|
||||
*
|
||||
* @param array 数组。元素类型为Map.Entry、数组、Iterable、Iterator
|
||||
* @return {@link HashMap}
|
||||
* @since 3.0.8
|
||||
* @see MapUtil#of(Object[])
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public static HashMap<Object, Object> toMap(Object[] array) {
|
||||
return MapUtil.of(array);
|
||||
@@ -1704,7 +1714,7 @@ public class CollUtil {
|
||||
* {a: 4}
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 结果是:
|
||||
*
|
||||
* <pre>
|
||||
@@ -1737,7 +1747,7 @@ public class CollUtil {
|
||||
* c: [1]
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 结果是:
|
||||
*
|
||||
* <pre>
|
||||
@@ -1782,7 +1792,7 @@ public class CollUtil {
|
||||
* @param elementType 元素类型,为空时,使用Object类型来接纳所有类型
|
||||
* @return 被加入集合
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static <T> Collection<T> addAll(Collection<T> collection, Object value, Type elementType) {
|
||||
if (null == collection || null == value) {
|
||||
return collection;
|
||||
@@ -1981,8 +1991,8 @@ public class CollUtil {
|
||||
* @param <T> 集合元素类型
|
||||
* @param iterable {@link Iterable}
|
||||
* @return 第一个元素
|
||||
* @since 3.0.1
|
||||
* @see IterUtil#getFirst(Iterable)
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public static <T> T getFirst(Iterable<T> iterable) {
|
||||
return IterUtil.getFirst(iterable);
|
||||
@@ -1994,8 +2004,8 @@ public class CollUtil {
|
||||
* @param <T> 集合元素类型
|
||||
* @param iterator {@link Iterator}
|
||||
* @return 第一个元素
|
||||
* @since 3.0.1
|
||||
* @see IterUtil#getFirst(Iterator)
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public static <T> T getFirst(Iterator<T> iterator) {
|
||||
return IterUtil.getFirst(iterator);
|
||||
@@ -2018,8 +2028,8 @@ public class CollUtil {
|
||||
*
|
||||
* @param iterable {@link Iterable}
|
||||
* @return 元素类型,当列表为空或元素全部为null时,返回null
|
||||
* @since 3.0.8
|
||||
* @see IterUtil#getElementType(Iterable)
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public static Class<?> getElementType(Iterable<?> iterable) {
|
||||
return IterUtil.getElementType(iterable);
|
||||
@@ -2030,8 +2040,8 @@ public class CollUtil {
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @return 元素类型,当列表为空或元素全部为null时,返回null
|
||||
* @since 3.0.8
|
||||
* @see IterUtil#getElementType(Iterator)
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public static Class<?> getElementType(Iterator<?> iterator) {
|
||||
return IterUtil.getElementType(iterator);
|
||||
@@ -2092,6 +2102,7 @@ public class CollUtil {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------- sort
|
||||
|
||||
/**
|
||||
* 将多个集合排序并显示不同的段落(分页)<br>
|
||||
* 采用{@link BoundedPriorityQueue}实现分页取局部
|
||||
@@ -2209,7 +2220,7 @@ public class CollUtil {
|
||||
* @return 排序后的List
|
||||
* @since 4.0.8
|
||||
*/
|
||||
public static <T> List<String> sortByPinyin(Collection<String> collection) {
|
||||
public static List<String> sortByPinyin(Collection<String> collection) {
|
||||
return sort(collection, new PinyinComparator());
|
||||
}
|
||||
|
||||
@@ -2220,7 +2231,7 @@ public class CollUtil {
|
||||
* @return 排序后的List
|
||||
* @since 4.0.8
|
||||
*/
|
||||
public static <T> List<String> sortByPinyin(List<String> list) {
|
||||
public static List<String> sortByPinyin(List<String> list) {
|
||||
return sort(list, new PinyinComparator());
|
||||
}
|
||||
|
||||
@@ -2287,7 +2298,7 @@ public class CollUtil {
|
||||
List<Entry<K, V>> list = new LinkedList<>(collection);
|
||||
Collections.sort(list, new Comparator<Entry<K, V>>() {
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Override
|
||||
public int compare(Entry<K, V> o1, Entry<K, V> o2) {
|
||||
V v1 = o1.getValue();
|
||||
@@ -2454,6 +2465,7 @@ public class CollUtil {
|
||||
/**
|
||||
* 设置或增加元素。当index小于List的长度时,替换指定位置的值,否则在尾部追加
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @param list List列表
|
||||
* @param index 位置
|
||||
* @param element 新元素
|
||||
@@ -2512,8 +2524,8 @@ public class CollUtil {
|
||||
* @param <T> 元素类型
|
||||
* @param coll 集合
|
||||
* @return 最大值
|
||||
* @since 4.6.5
|
||||
* @see Collections#max(Collection)
|
||||
* @since 4.6.5
|
||||
*/
|
||||
public static <T extends Comparable<? super T>> T max(Collection<T> coll) {
|
||||
return Collections.max(coll);
|
||||
@@ -2525,20 +2537,20 @@ public class CollUtil {
|
||||
* @param <T> 元素类型
|
||||
* @param coll 集合
|
||||
* @return 最大值
|
||||
* @since 4.6.5
|
||||
* @see Collections#min(Collection)
|
||||
* @since 4.6.5
|
||||
*/
|
||||
public static <T extends Comparable<? super T>> T min(Collection<T> coll) {
|
||||
return Collections.min(coll);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------- Interface start
|
||||
|
||||
/**
|
||||
* 针对一个参数做相应的操作
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
* @param <T> 处理参数类型
|
||||
* @author Looly
|
||||
*/
|
||||
public interface Consumer<T> {
|
||||
/**
|
||||
@@ -2553,10 +2565,9 @@ public class CollUtil {
|
||||
/**
|
||||
* 针对两个参数做相应的操作,例如Map中的KEY和VALUE
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
* @param <K> KEY类型
|
||||
* @param <V> VALUE类型
|
||||
* @author Looly
|
||||
*/
|
||||
public interface KVConsumer<K, V> {
|
||||
/**
|
||||
@@ -2572,9 +2583,8 @@ public class CollUtil {
|
||||
/**
|
||||
* Hash计算接口
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
* @param <T> 被计算hash的对象类型
|
||||
* @author looly
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public interface Hash<T> {
|
||||
|
@@ -1,7 +1,32 @@
|
||||
package cn.hutool.core.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class CompareUtil {
|
||||
|
||||
/**
|
||||
* 对象比较,比较结果取决于comparator,如果被比较对象为null,传入的comparator对象应处理此情况<br>
|
||||
* 如果传入comparator为null,则使用默认规则比较(此时被比较对象必须实现Comparable接口)
|
||||
*
|
||||
* <p>
|
||||
* 一般而言,如果c1 < c2,返回数小于0,c1==c2返回0,c1 > c2 大于0
|
||||
*
|
||||
* @param <T> 被比较对象类型
|
||||
* @param c1 对象1
|
||||
* @param c2 对象2
|
||||
* @param comparator 比较器
|
||||
* @return 比较结果
|
||||
* @see java.util.Comparator#compare(Object, Object)
|
||||
* @since 4.6.9
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static <T> int compare(T c1, T c2, Comparator<T> comparator) {
|
||||
if (null == comparator) {
|
||||
return compare((Comparable)c1, (Comparable)c2);
|
||||
}
|
||||
return comparator.compare(c1, c2);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code null}安全的对象比较,{@code null}对象小于任何对象
|
||||
*
|
||||
@@ -46,12 +71,13 @@ public class CompareUtil {
|
||||
* 4、比较toString值
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> 被比较对象类型
|
||||
* @param o1 对象1
|
||||
* @param o2 对象2
|
||||
* @param isNullGreater null值是否做为最大值
|
||||
* @return 比较结果,如果o1 < o2,返回数小于0,o1==o2返回0,o1 > o2 大于0
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static <T> int compare(T o1, T o2, boolean isNullGreater) {
|
||||
if (o1 == o2) {
|
||||
return 0;
|
||||
@@ -61,17 +87,17 @@ public class CompareUtil {
|
||||
return isNullGreater ? -1 : 1;
|
||||
}
|
||||
|
||||
if(o1 instanceof Comparable && o2 instanceof Comparable) {
|
||||
if (o1 instanceof Comparable && o2 instanceof Comparable) {
|
||||
//如果bean可比较,直接比较bean
|
||||
return ((Comparable)o1).compareTo(o2);
|
||||
return ((Comparable) o1).compareTo(o2);
|
||||
}
|
||||
|
||||
if(o1.equals(o2)) {
|
||||
if (o1.equals(o2)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = Integer.compare(o1.hashCode(), o2.hashCode());
|
||||
if(0 == result) {
|
||||
if (0 == result) {
|
||||
result = compare(o1.toString(), o2.toString());
|
||||
}
|
||||
|
||||
|
@@ -62,7 +62,7 @@ public class PropertyComparator<T> implements Comparator<T>, Serializable {
|
||||
return compare(o1, o2, v1, v2);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@SuppressWarnings({ "rawtypes"})
|
||||
private int compare(T o1, T o2, Comparable fieldValue1, Comparable fieldValue2) {
|
||||
int result = ObjectUtil.compare(fieldValue1, fieldValue2, isNullGreater);
|
||||
if(0 == result) {
|
||||
|
@@ -528,6 +528,8 @@ public class Convert {
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @param keyType 键类型
|
||||
* @param valueType 值类型
|
||||
* @param value 被转换的值
|
||||
* @return {@link Map}
|
||||
* @since 4.6.8
|
||||
|
@@ -366,7 +366,9 @@ public class StopWatch {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务名Get the name of this task.
|
||||
* 获取任务名
|
||||
*
|
||||
* @return 任务名
|
||||
*/
|
||||
public String getTaskName() {
|
||||
return this.taskName;
|
||||
@@ -375,6 +377,7 @@ public class StopWatch {
|
||||
/**
|
||||
* 获取任务花费时间(单位:纳秒)
|
||||
*
|
||||
* @return 任务花费时间(单位:纳秒)
|
||||
* @see #getTimeMillis()
|
||||
* @see #getTimeSeconds()
|
||||
*/
|
||||
@@ -385,6 +388,7 @@ public class StopWatch {
|
||||
/**
|
||||
* 获取任务花费时间(单位:毫秒)
|
||||
*
|
||||
* @return 任务花费时间(单位:毫秒)
|
||||
* @see #getTimeNanos()
|
||||
* @see #getTimeSeconds()
|
||||
*/
|
||||
@@ -395,6 +399,7 @@ public class StopWatch {
|
||||
/**
|
||||
* 获取任务花费时间(单位:秒)
|
||||
*
|
||||
* @return 任务花费时间(单位:秒)
|
||||
* @see #getTimeMillis()
|
||||
* @see #getTimeNanos()
|
||||
*/
|
||||
|
@@ -63,6 +63,7 @@ public class ExceptionUtil {
|
||||
/**
|
||||
* 包装一个异常
|
||||
*
|
||||
* @param <T> 被包装的异常类型
|
||||
* @param throwable 异常
|
||||
* @param wrapThrowable 包装后的异常类
|
||||
* @return 包装后的异常
|
||||
@@ -124,6 +125,7 @@ public class ExceptionUtil {
|
||||
/**
|
||||
* 获取指定层的堆栈信息
|
||||
*
|
||||
* @param i 层数
|
||||
* @return 指定层的堆栈信息
|
||||
* @since 4.1.4
|
||||
*/
|
||||
@@ -346,7 +348,7 @@ public class ExceptionUtil {
|
||||
* @since 4.6.2
|
||||
*/
|
||||
public static List<Throwable> getThrowableList(Throwable throwable) {
|
||||
final List<Throwable> list = new ArrayList<Throwable>();
|
||||
final List<Throwable> list = new ArrayList<>();
|
||||
while (throwable != null && false == list.contains(throwable)) {
|
||||
list.add(throwable);
|
||||
throwable = throwable.getCause();
|
||||
|
@@ -45,16 +45,22 @@ import cn.hutool.core.util.StrUtil;
|
||||
* @author looly
|
||||
* @since 4.1.5
|
||||
*/
|
||||
public class Img implements Serializable{
|
||||
public class Img implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private BufferedImage srcImage;
|
||||
private Image targetImage;
|
||||
/** 目标图片文件格式,用于写出 */
|
||||
/**
|
||||
* 目标图片文件格式,用于写出
|
||||
*/
|
||||
private String targetImageType = ImgUtil.IMAGE_TYPE_JPG;
|
||||
/** 计算x,y坐标的时候是否从中心做为原始坐标开始计算 */
|
||||
/**
|
||||
* 计算x,y坐标的时候是否从中心做为原始坐标开始计算
|
||||
*/
|
||||
private boolean positionBaseCentre = true;
|
||||
/** 图片输出质量,用于压缩 */
|
||||
/**
|
||||
* 图片输出质量,用于压缩
|
||||
*/
|
||||
private float quality = -1;
|
||||
|
||||
/**
|
||||
@@ -154,6 +160,7 @@ public class Img implements Serializable{
|
||||
* 计算x,y坐标的时候是否从中心做为原始坐标开始计算
|
||||
*
|
||||
* @param positionBaseCentre 是否从中心做为原始坐标开始计算
|
||||
* @return this
|
||||
* @since 4.1.15
|
||||
*/
|
||||
public Img setPositionBaseCentre(boolean positionBaseCentre) {
|
||||
@@ -165,6 +172,7 @@ public class Img implements Serializable{
|
||||
* 设置图片输出质量,数字为0~1(不包括0和1)表示质量压缩比,除此数字外设置表示不压缩
|
||||
*
|
||||
* @param quality 质量,数字为0~1(不包括0和1)表示质量压缩比,除此数字外设置表示不压缩
|
||||
* @return this
|
||||
* @since 4.3.2
|
||||
*/
|
||||
public Img setQuality(double quality) {
|
||||
@@ -175,6 +183,7 @@ public class Img implements Serializable{
|
||||
* 设置图片输出质量,数字为0~1(不包括0和1)表示质量压缩比,除此数字外设置表示不压缩
|
||||
*
|
||||
* @param quality 质量,数字为0~1(不包括0和1)表示质量压缩比,除此数字外设置表示不压缩
|
||||
* @return this
|
||||
* @since 4.3.2
|
||||
*/
|
||||
public Img setQuality(float quality) {
|
||||
@@ -525,6 +534,7 @@ public class Img implements Serializable{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------- Write
|
||||
|
||||
/**
|
||||
* 获取处理过的图片
|
||||
*
|
||||
@@ -589,6 +599,7 @@ public class Img implements Serializable{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 将图片绘制在背景上
|
||||
*
|
||||
@@ -660,7 +671,7 @@ public class Img implements Serializable{
|
||||
* @since 4.1.20
|
||||
*/
|
||||
private static Rectangle calcRotatedSize(int width, int height, int degree) {
|
||||
if(degree < 0){
|
||||
if (degree < 0) {
|
||||
// 负数角度转换为正数角度
|
||||
degree += 360;
|
||||
}
|
||||
|
@@ -63,6 +63,7 @@ public class ImgUtil {
|
||||
public static final String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- scale
|
||||
|
||||
/**
|
||||
* 缩放图像(按比例缩放),目标文件的扩展名决定目标文件类型
|
||||
*
|
||||
@@ -243,6 +244,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- cut
|
||||
|
||||
/**
|
||||
* 图像切割(按指定起点坐标和宽高切割)
|
||||
*
|
||||
@@ -285,8 +287,8 @@ public class ImgUtil {
|
||||
* @param srcImage 源图像
|
||||
* @param destFile 输出的文件
|
||||
* @param rectangle 矩形对象,表示矩形区域的x,y,width,height
|
||||
* @since 3.2.2
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public static void cut(Image srcImage, File destFile, Rectangle rectangle) throws IORuntimeException {
|
||||
write(cut(srcImage, rectangle), destFile);
|
||||
@@ -298,8 +300,8 @@ public class ImgUtil {
|
||||
* @param srcImage 源图像
|
||||
* @param out 切片后的图像输出流
|
||||
* @param rectangle 矩形对象,表示矩形区域的x,y,width,height
|
||||
* @since 3.1.0
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static void cut(Image srcImage, OutputStream out, Rectangle rectangle) throws IORuntimeException {
|
||||
cut(srcImage, getImageOutputStream(out), rectangle);
|
||||
@@ -311,8 +313,8 @@ public class ImgUtil {
|
||||
* @param srcImage 源图像
|
||||
* @param destImageStream 切片后的图像输出流
|
||||
* @param rectangle 矩形对象,表示矩形区域的x,y,width,height
|
||||
* @since 3.1.0
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static void cut(Image srcImage, ImageOutputStream destImageStream, Rectangle rectangle) throws IORuntimeException {
|
||||
writeJpg(cut(srcImage, rectangle), destImageStream);
|
||||
@@ -480,6 +482,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- convert
|
||||
|
||||
/**
|
||||
* 图像类型转换:GIF=》JPG、GIF=》PNG、PNG=》JPG、PNG=》GIF(X)、BMP=》PNG
|
||||
*
|
||||
@@ -569,6 +572,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- grey
|
||||
|
||||
/**
|
||||
* 彩色转为黑白
|
||||
*
|
||||
@@ -632,8 +636,8 @@ public class ImgUtil {
|
||||
*
|
||||
* @param srcImage 源图像流
|
||||
* @param destImageStream 目标图像流
|
||||
* @since 3.0.9
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static void gray(Image srcImage, ImageOutputStream destImageStream) throws IORuntimeException {
|
||||
writeJpg(gray(srcImage), destImageStream);
|
||||
@@ -651,6 +655,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- binary
|
||||
|
||||
/**
|
||||
* 彩色转为黑白二值化图片,根据目标文件扩展名确定转换后的格式
|
||||
*
|
||||
@@ -718,8 +723,8 @@ public class ImgUtil {
|
||||
* @param srcImage 源图像流
|
||||
* @param destImageStream 目标图像流
|
||||
* @param imageType 图片格式(扩展名)
|
||||
* @since 4.0.5
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 4.0.5
|
||||
*/
|
||||
public static void binary(Image srcImage, ImageOutputStream destImageStream, String imageType) throws IORuntimeException {
|
||||
write(binary(srcImage), imageType, destImageStream);
|
||||
@@ -737,6 +742,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- press
|
||||
|
||||
/**
|
||||
* 给图片添加文字水印
|
||||
*
|
||||
@@ -987,6 +993,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- rotate
|
||||
|
||||
/**
|
||||
* 旋转图片为指定角度<br>
|
||||
* 此方法不会关闭输出流
|
||||
@@ -994,8 +1001,8 @@ public class ImgUtil {
|
||||
* @param imageFile 被旋转图像文件
|
||||
* @param degree 旋转角度
|
||||
* @param outFile 输出文件
|
||||
* @since 3.2.2
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public static void rotate(File imageFile, int degree, File outFile) throws IORuntimeException {
|
||||
rotate(read(imageFile), degree, outFile);
|
||||
@@ -1008,8 +1015,8 @@ public class ImgUtil {
|
||||
* @param image 目标图像
|
||||
* @param degree 旋转角度
|
||||
* @param outFile 输出文件
|
||||
* @since 3.2.2
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public static void rotate(Image image, int degree, File outFile) throws IORuntimeException {
|
||||
write(rotate(image, degree), outFile);
|
||||
@@ -1022,8 +1029,8 @@ public class ImgUtil {
|
||||
* @param image 目标图像
|
||||
* @param degree 旋转角度
|
||||
* @param out 输出流
|
||||
* @since 3.2.2
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public static void rotate(Image image, int degree, OutputStream out) throws IORuntimeException {
|
||||
writeJpg(rotate(image, degree), getImageOutputStream(out));
|
||||
@@ -1036,8 +1043,8 @@ public class ImgUtil {
|
||||
* @param image 目标图像
|
||||
* @param degree 旋转角度
|
||||
* @param out 输出图像流
|
||||
* @since 3.2.2
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public static void rotate(Image image, int degree, ImageOutputStream out) throws IORuntimeException {
|
||||
writeJpg(rotate(image, degree), out);
|
||||
@@ -1057,6 +1064,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- flip
|
||||
|
||||
/**
|
||||
* 水平翻转图像
|
||||
*
|
||||
@@ -1117,11 +1125,13 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- compress
|
||||
|
||||
/**
|
||||
* 压缩图像,输出图像只支持jpg文件
|
||||
*
|
||||
* @param imageFile 图像文件
|
||||
* @param outFile 输出文件,只支持jpg文件
|
||||
* @param quality 压缩比例,必须为0~1
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 4.3.2
|
||||
*/
|
||||
@@ -1130,6 +1140,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------- other
|
||||
|
||||
/**
|
||||
* {@link Image} 转 {@link RenderedImage}<br>
|
||||
* 首先尝试强转,否则新建一个{@link BufferedImage}后重新绘制
|
||||
@@ -1360,8 +1371,8 @@ public class ImgUtil {
|
||||
* @param image {@link BufferedImage}
|
||||
* @param color {@link Color}背景颜色以及当前画笔颜色
|
||||
* @return {@link Graphics2D}
|
||||
* @since 3.2.3
|
||||
* @see GraphicsUtil#createGraphics(BufferedImage, Color)
|
||||
* @since 3.2.3
|
||||
*/
|
||||
public static Graphics2D createGraphics(BufferedImage image, Color color) {
|
||||
return GraphicsUtil.createGraphics(image, color);
|
||||
@@ -1704,6 +1715,7 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------- Color
|
||||
|
||||
/**
|
||||
* Color对象转16进制表示,例如#fcf6d6
|
||||
*
|
||||
@@ -1751,7 +1763,7 @@ public class ImgUtil {
|
||||
* 2. 16进制表示,例如:#fcf6d6或者$fcf6d6
|
||||
* 3. RGB形式,例如:13,148,252
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 方法来自:com.lnwazg.kit
|
||||
*
|
||||
* @param colorName 颜色的英文名,16进制表示或RGB表示
|
||||
|
@@ -364,7 +364,7 @@ public class FileUtil {
|
||||
* 此方法会检查slip漏洞,漏洞说明见http://blog.nsfocus.net/zip-slip-2/
|
||||
*
|
||||
* @param directory 父目录
|
||||
* @param names 元素名(多层目录名)
|
||||
* @param names 元素名(多层目录名),由外到内依次传入
|
||||
* @return the file 文件
|
||||
* @since 4.0.6
|
||||
*/
|
||||
@@ -388,6 +388,7 @@ public class FileUtil {
|
||||
* <p>
|
||||
* 元素名(多层目录名)
|
||||
*
|
||||
* @param names 多层文件的文件名,由外到内依次传入
|
||||
* @return the file 文件
|
||||
* @since 4.0.6
|
||||
*/
|
||||
@@ -1397,6 +1398,7 @@ public class FileUtil {
|
||||
* @param file1 文件1
|
||||
* @param file2 文件2
|
||||
* @param charset 编码,null表示使用平台默认编码 两个文件内容一致返回true,否则false
|
||||
* @return 是否相同
|
||||
* @throws IORuntimeException IO异常
|
||||
* @since 4.0.6
|
||||
*/
|
||||
@@ -1550,7 +1552,7 @@ public class FileUtil {
|
||||
// 统一使用斜杠
|
||||
pathToUse = pathToUse.replaceAll("[/\\\\]+", StrUtil.SLASH).trim();
|
||||
//兼容Windows下的共享目录路径(原始路径如果以\\开头,则保留这种路径)
|
||||
if(path.startsWith("\\\\")){
|
||||
if (path.startsWith("\\\\")) {
|
||||
pathToUse = "\\" + pathToUse;
|
||||
}
|
||||
|
||||
@@ -3354,10 +3356,10 @@ public class FileUtil {
|
||||
* 获取指定层级的父路径
|
||||
*
|
||||
* <pre>
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 0) -> "d:/aaa/bbb/cc/ddd"
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 2) -> "d:/aaa/bbb"
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 4) -> "d:/"
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 5) -> null
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 0) -》 "d:/aaa/bbb/cc/ddd"
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 2) -》 "d:/aaa/bbb"
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 4) -》 "d:/"
|
||||
* getParent("d:/aaa/bbb/cc/ddd", 5) -》 null
|
||||
* </pre>
|
||||
*
|
||||
* @param filePath 目录或文件路径
|
||||
@@ -3378,10 +3380,10 @@ public class FileUtil {
|
||||
* 获取指定层级的父路径
|
||||
*
|
||||
* <pre>
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 0)) -> "d:/aaa/bbb/cc/ddd"
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 2)) -> "d:/aaa/bbb"
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 4)) -> "d:/"
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 5)) -> null
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 0)) -》 "d:/aaa/bbb/cc/ddd"
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 2)) -》 "d:/aaa/bbb"
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 4)) -》 "d:/"
|
||||
* getParent(file("d:/aaa/bbb/cc/ddd", 5)) -》 null
|
||||
* </pre>
|
||||
*
|
||||
* @param file 目录或文件
|
||||
|
@@ -139,6 +139,7 @@ public class FileCopier extends SrcToDestCopier<File, FileCopier>{
|
||||
* 设置当拷贝来源是目录时是否只拷贝文件而忽略子目录
|
||||
*
|
||||
* @param isOnlyCopyFile 当拷贝来源是目录时是否只拷贝文件而忽略子目录
|
||||
* @return this
|
||||
* @since 4.1.5
|
||||
*/
|
||||
public FileCopier setOnlyCopyFile(boolean isOnlyCopyFile) {
|
||||
|
@@ -16,7 +16,7 @@ public class MultiFileResource extends MultiResource{
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param files
|
||||
* @param files 文件资源列表
|
||||
*/
|
||||
public MultiFileResource(Collection<File> files) {
|
||||
super();
|
||||
@@ -26,7 +26,7 @@ public class MultiFileResource extends MultiResource{
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param files
|
||||
* @param files 文件资源列表
|
||||
*/
|
||||
public MultiFileResource(File... files) {
|
||||
super();
|
||||
|
@@ -442,7 +442,7 @@ public class WatchMonitor extends Thread implements Closeable, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置监听选项,例如监听频率等,可设置项包括:<p>
|
||||
* 设置监听选项,例如监听频率等,可设置项包括:
|
||||
*
|
||||
* <pre>
|
||||
* 1、com.sun.nio.file.StandardWatchEventKinds
|
||||
|
@@ -525,14 +525,14 @@ public class Assert {
|
||||
* 检查下标(数组、集合、字符串)是否符合要求,下标必须满足:
|
||||
*
|
||||
* <pre>
|
||||
* 0 <= index < size
|
||||
* 0 ≤ index < size
|
||||
* </pre>
|
||||
*
|
||||
* @param index 下标
|
||||
* @param size 长度
|
||||
* @return 检查后的下标
|
||||
* @throws IllegalArgumentException 如果size < 0 抛出此异常
|
||||
* @throws IndexOutOfBoundsException 如果index < 0或者 index >= size 抛出此异常
|
||||
* @throws IllegalArgumentException 如果size < 0 抛出此异常
|
||||
* @throws IndexOutOfBoundsException 如果index < 0或者 index ≥ size 抛出此异常
|
||||
* @since 4.1.9
|
||||
*/
|
||||
public static int checkIndex(int index, int size) throws IllegalArgumentException, IndexOutOfBoundsException {
|
||||
@@ -543,7 +543,7 @@ public class Assert {
|
||||
* 检查下标(数组、集合、字符串)是否符合要求,下标必须满足:
|
||||
*
|
||||
* <pre>
|
||||
* 0 <= index < size
|
||||
* 0 ≤ index < size
|
||||
* </pre>
|
||||
*
|
||||
* @param index 下标
|
||||
@@ -551,8 +551,8 @@ public class Assert {
|
||||
* @param errorMsgTemplate 异常时的消息模板
|
||||
* @param params 参数列表
|
||||
* @return 检查后的下标
|
||||
* @throws IllegalArgumentException 如果size < 0 抛出此异常
|
||||
* @throws IndexOutOfBoundsException 如果index < 0或者 index >= size 抛出此异常
|
||||
* @throws IllegalArgumentException 如果size < 0 抛出此异常
|
||||
* @throws IndexOutOfBoundsException 如果index < 0或者 index ≥ size 抛出此异常
|
||||
* @since 4.1.9
|
||||
*/
|
||||
public static int checkIndex(int index, int size, String errorMsgTemplate, Object... params) throws IllegalArgumentException, IndexOutOfBoundsException {
|
||||
|
@@ -18,7 +18,6 @@ import cn.hutool.core.util.URLUtil;
|
||||
* 外部Jar的类加载器
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class JarClassLoader extends URLClassLoader {
|
||||
|
||||
@@ -61,7 +60,7 @@ public class JarClassLoader extends URLClassLoader {
|
||||
method.setAccessible(true);
|
||||
final List<File> jars = loopJar(jarFile);
|
||||
for (File jar : jars) {
|
||||
ReflectUtil.invoke(loader, method, new Object[] { jar.toURI().toURL() });
|
||||
ReflectUtil.invoke(loader, method, new Object[]{jar.toURI().toURL()});
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -82,11 +81,12 @@ public class JarClassLoader extends URLClassLoader {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public JarClassLoader() {
|
||||
this(new URL[] {});
|
||||
this(new URL[]{});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +106,7 @@ public class JarClassLoader extends URLClassLoader {
|
||||
* @return this
|
||||
*/
|
||||
public JarClassLoader addJar(File jarFileOrDir) {
|
||||
if(isJarFile(jarFileOrDir)) {
|
||||
if (isJarFile(jarFileOrDir)) {
|
||||
return addURL(jarFileOrDir);
|
||||
}
|
||||
final List<File> jars = loopJar(jarFileOrDir);
|
||||
@@ -126,6 +126,7 @@ public class JarClassLoader extends URLClassLoader {
|
||||
* 如果为目录,此目录用于搜索class文件,如果为文件,需为jar文件
|
||||
*
|
||||
* @param dir 目录
|
||||
* @return this
|
||||
* @since 4.4.2
|
||||
*/
|
||||
public JarClassLoader addURL(File dir) {
|
||||
@@ -134,6 +135,7 @@ public class JarClassLoader extends URLClassLoader {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 递归获得Jar文件
|
||||
*
|
||||
|
@@ -15,7 +15,6 @@ import cn.hutool.core.util.StrUtil;
|
||||
* <p>
|
||||
* 这些通用标识符具有不同的变体。此类的方法用于操作 Leach-Salz 变体,不过构造方法允许创建任何 UUID 变体(将在下面进行描述)。
|
||||
* <p>
|
||||
*
|
||||
* 变体 2 (Leach-Salz) UUID 的布局如下: long 型数据的最高有效位由以下无符号字段组成:
|
||||
*
|
||||
* <pre>
|
||||
@@ -24,7 +23,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
* 0x000000000000F000 version
|
||||
* 0x0000000000000FFF time_hi
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* long 型数据的最低有效位由以下无符号字段组成:
|
||||
*
|
||||
* <pre>
|
||||
@@ -48,16 +47,19 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* {@link SecureRandom} 的单例
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
private static class Holder {
|
||||
static final SecureRandom numberGenerator = RandomUtil.getSecureRandom();
|
||||
}
|
||||
|
||||
/** 此UUID的最高64有效位 */
|
||||
/**
|
||||
* 此UUID的最高64有效位
|
||||
*/
|
||||
private final long mostSigBits;
|
||||
|
||||
/** 此UUID的最低64有效位 */
|
||||
/**
|
||||
* 此UUID的最低64有效位
|
||||
*/
|
||||
private final long leastSigBits;
|
||||
|
||||
/**
|
||||
@@ -130,7 +132,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。
|
||||
*
|
||||
* @param name 用于构造 UUID 的字节数组。
|
||||
*
|
||||
* @return 根据指定数组生成的 {@code UUID}
|
||||
*/
|
||||
public static UUID nameUUIDFromBytes(byte[] name) {
|
||||
@@ -154,7 +155,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* @param name 指定 {@code UUID} 字符串
|
||||
* @return 具有指定值的 {@code UUID}
|
||||
* @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常
|
||||
*
|
||||
*/
|
||||
public static UUID fromString(String name) {
|
||||
String[] components = name.split("-");
|
||||
@@ -247,6 +247,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。<br>
|
||||
* 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。
|
||||
*
|
||||
* @return 时间戳值
|
||||
* @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。
|
||||
*/
|
||||
public long timestamp() throws UnsupportedOperationException {
|
||||
@@ -265,7 +266,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。
|
||||
*
|
||||
* @return 此 {@code UUID} 的时钟序列
|
||||
*
|
||||
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
|
||||
*/
|
||||
public int clockSequence() throws UnsupportedOperationException {
|
||||
@@ -283,7 +283,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。
|
||||
*
|
||||
* @return 此 {@code UUID} 的节点值
|
||||
*
|
||||
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
|
||||
*/
|
||||
public long node() throws UnsupportedOperationException {
|
||||
@@ -312,8 +311,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
* @return 此{@code UUID} 的字符串表现形式
|
||||
* @see #toString(boolean)
|
||||
*/
|
||||
@@ -341,8 +338,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
* @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串
|
||||
* @return 此{@code UUID} 的字符串表现形式
|
||||
*/
|
||||
@@ -390,7 +385,6 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。
|
||||
*
|
||||
* @param obj 要与之比较的对象
|
||||
*
|
||||
* @return 如果对象相同,则返回 {@code true};否则返回 {@code false}
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
@@ -410,9 +404,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
* 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。
|
||||
*
|
||||
* @param val 与此 UUID 比较的 UUID
|
||||
*
|
||||
* @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。
|
||||
*
|
||||
*/
|
||||
public int compareTo(UUID val) {
|
||||
// The ordering is intentionally set up so that the UUIDs
|
||||
@@ -425,6 +417,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 返回指定数字对应的hex值
|
||||
*
|
||||
|
@@ -15,46 +15,79 @@ import cn.hutool.core.util.StrUtil;
|
||||
* 字段验证器
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class Validator {
|
||||
|
||||
private Validator() {
|
||||
}
|
||||
|
||||
/** 英文字母 、数字和下划线 */
|
||||
/**
|
||||
* 英文字母 、数字和下划线
|
||||
*/
|
||||
public final static Pattern GENERAL = PatternPool.GENERAL;
|
||||
/** 数字 */
|
||||
/**
|
||||
* 数字
|
||||
*/
|
||||
public final static Pattern NUMBERS = PatternPool.NUMBERS;
|
||||
/** 分组 */
|
||||
/**
|
||||
* 分组
|
||||
*/
|
||||
public final static Pattern GROUP_VAR = PatternPool.GROUP_VAR;
|
||||
/** IP v4 */
|
||||
/**
|
||||
* IP v4
|
||||
*/
|
||||
public final static Pattern IPV4 = PatternPool.IPV4;
|
||||
/** IP v6 */
|
||||
/**
|
||||
* IP v6
|
||||
*/
|
||||
public final static Pattern IPV6 = PatternPool.IPV6;
|
||||
/** 货币 */
|
||||
/**
|
||||
* 货币
|
||||
*/
|
||||
public final static Pattern MONEY = PatternPool.MONEY;
|
||||
/** 邮件 */
|
||||
/**
|
||||
* 邮件
|
||||
*/
|
||||
public final static Pattern EMAIL = PatternPool.EMAIL;
|
||||
/** 移动电话 */
|
||||
/**
|
||||
* 移动电话
|
||||
*/
|
||||
public final static Pattern MOBILE = PatternPool.MOBILE;
|
||||
/** 身份证号码 */
|
||||
/**
|
||||
* 身份证号码
|
||||
*/
|
||||
public final static Pattern CITIZEN_ID = PatternPool.CITIZEN_ID;
|
||||
/** 邮编 */
|
||||
/**
|
||||
* 邮编
|
||||
*/
|
||||
public final static Pattern ZIP_CODE = PatternPool.ZIP_CODE;
|
||||
/** 生日 */
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
public final static Pattern BIRTHDAY = PatternPool.BIRTHDAY;
|
||||
/** URL */
|
||||
/**
|
||||
* URL
|
||||
*/
|
||||
public final static Pattern URL = PatternPool.URL;
|
||||
/** Http URL */
|
||||
/**
|
||||
* Http URL
|
||||
*/
|
||||
public final static Pattern URL_HTTP = PatternPool.URL_HTTP;
|
||||
/** 中文字、英文字母、数字和下划线 */
|
||||
/**
|
||||
* 中文字、英文字母、数字和下划线
|
||||
*/
|
||||
public final static Pattern GENERAL_WITH_CHINESE = PatternPool.GENERAL_WITH_CHINESE;
|
||||
/** UUID */
|
||||
/**
|
||||
* UUID
|
||||
*/
|
||||
public final static Pattern UUID = PatternPool.UUID;
|
||||
/** 不带横线的UUID */
|
||||
/**
|
||||
* 不带横线的UUID
|
||||
*/
|
||||
public final static Pattern UUID_SIMPLE = PatternPool.UUID_SIMPLE;
|
||||
/** 中国车牌号码 */
|
||||
/**
|
||||
* 中国车牌号码
|
||||
*/
|
||||
public final static Pattern PLATE_NUMBER = PatternPool.PLATE_NUMBER;
|
||||
|
||||
/**
|
||||
@@ -194,6 +227,7 @@ public class Validator {
|
||||
* 验证是否为空,非空时抛出异常<br>
|
||||
* 对于String类型判定是否为empty(null 或 "")<br>
|
||||
*
|
||||
* @param <T> 值类型
|
||||
* @param value 值
|
||||
* @param errorMsg 验证错误的信息
|
||||
* @return 验证后的值,验证通过返回此值,空值
|
||||
@@ -210,6 +244,7 @@ public class Validator {
|
||||
* 验证是否为非空,为空时抛出异常<br>
|
||||
* 对于String类型判定是否为empty(null 或 "")<br>
|
||||
*
|
||||
* @param <T> 值类型
|
||||
* @param value 值
|
||||
* @param errorMsg 验证错误的信息
|
||||
* @return 验证后的值,验证通过返回此值,非空值
|
||||
|
@@ -37,6 +37,7 @@ public class WeightRandom<T> implements Serializable {
|
||||
/**
|
||||
* 创建权重随机获取器
|
||||
*
|
||||
* @param <T> 权重随机获取的对象类型
|
||||
* @return {@link WeightRandom}
|
||||
*/
|
||||
public static <T> WeightRandom<T> create() {
|
||||
@@ -99,7 +100,7 @@ public class WeightRandom<T> implements Serializable {
|
||||
* @return this
|
||||
*/
|
||||
public WeightRandom<T> add(T obj, double weight) {
|
||||
return add(new WeightObj<T>(obj, weight));
|
||||
return add(new WeightObj<>(obj, weight));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,10 +227,7 @@ public class WeightRandom<T> implements Serializable {
|
||||
} else if (!this.obj.equals(other.obj)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(weight) != Double.doubleToLongBits(other.weight)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return Double.doubleToLongBits(weight) == Double.doubleToLongBits(other.weight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -119,7 +119,7 @@ public class MapProxy extends OptNullBasicTypeFromObjectGetter<Object> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
public Object invoke(Object proxy, Method method, Object[] args) {
|
||||
final Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (ArrayUtil.isEmpty(parameterTypes)) {
|
||||
final Class<?> returnType = method.getReturnType();
|
||||
@@ -167,6 +167,7 @@ public class MapProxy extends OptNullBasicTypeFromObjectGetter<Object> implement
|
||||
/**
|
||||
* 将Map代理为指定接口的动态代理对象
|
||||
*
|
||||
* @param <T> 代理的Bean类型
|
||||
* @param interfaceClass 接口
|
||||
* @return 代理对象
|
||||
* @since 4.5.2
|
||||
|
@@ -22,9 +22,13 @@ import cn.hutool.core.util.StrUtil;
|
||||
*/
|
||||
public class MapUtil {
|
||||
|
||||
/** 默认初始大小 */
|
||||
/**
|
||||
* 默认初始大小
|
||||
*/
|
||||
public static final int DEFAULT_INITIAL_CAPACITY = 16;
|
||||
/** 默认增长因子,当Map的size达到 容量*增长因子时,开始扩充Map */
|
||||
/**
|
||||
* 默认增长因子,当Map的size达到 容量*增长因子时,开始扩充Map
|
||||
*/
|
||||
public static final float DEFAULT_LOAD_FACTOR = 0.75f;
|
||||
|
||||
/**
|
||||
@@ -58,7 +62,7 @@ public class MapUtil {
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public static <K, V> Map<K, V> emptyIfNull(Map<K, V> set) {
|
||||
return (null == set) ? Collections.<K, V>emptyMap() : set;
|
||||
return (null == set) ? Collections.emptyMap() : set;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,11 +76,12 @@ public class MapUtil {
|
||||
* @return 非空(empty)的原Map或默认Map
|
||||
* @since 4.6.9
|
||||
*/
|
||||
public static <T extends Map<K, V>, K, V> T defaultIfEmpty(T map, T defaultMap){
|
||||
public static <T extends Map<K, V>, K, V> T defaultIfEmpty(T map, T defaultMap) {
|
||||
return isEmpty(map) ? defaultMap : map;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- new HashMap
|
||||
|
||||
/**
|
||||
* 新建一个HashMap
|
||||
*
|
||||
@@ -100,7 +105,7 @@ public class MapUtil {
|
||||
*/
|
||||
public static <K, V> HashMap<K, V> newHashMap(int size, boolean isOrder) {
|
||||
int initialCapacity = (int) (size / DEFAULT_LOAD_FACTOR) + 1;
|
||||
return isOrder ? new LinkedHashMap<K, V>(initialCapacity) : new HashMap<K, V>(initialCapacity);
|
||||
return isOrder ? new LinkedHashMap<>(initialCapacity) : new HashMap<>(initialCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +135,8 @@ public class MapUtil {
|
||||
/**
|
||||
* 新建TreeMap,Key有序的Map
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param comparator Key比较器
|
||||
* @return TreeMap
|
||||
* @since 3.2.3
|
||||
@@ -141,6 +148,8 @@ public class MapUtil {
|
||||
/**
|
||||
* 新建TreeMap,Key有序的Map
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param map Map
|
||||
* @param comparator Key比较器
|
||||
* @return TreeMap
|
||||
@@ -157,6 +166,9 @@ public class MapUtil {
|
||||
/**
|
||||
* 创建键不重复Map
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param size 初始容量
|
||||
* @return {@link IdentityHashMap}
|
||||
* @since 4.5.7
|
||||
*/
|
||||
@@ -197,7 +209,7 @@ public class MapUtil {
|
||||
* @return ConcurrentHashMap
|
||||
*/
|
||||
public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap(Map<K, V> map) {
|
||||
if(isEmpty(map)) {
|
||||
if (isEmpty(map)) {
|
||||
return new ConcurrentHashMap<>(DEFAULT_INITIAL_CAPACITY);
|
||||
}
|
||||
return new ConcurrentHashMap<>(map);
|
||||
@@ -222,6 +234,7 @@ public class MapUtil {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- value of
|
||||
|
||||
/**
|
||||
* 将单一键值对转换为Map
|
||||
*
|
||||
@@ -264,7 +277,7 @@ public class MapUtil {
|
||||
* <pre>
|
||||
* Map<Object, Object> colorMap = MapUtil.of(new String[][] { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } });
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 参考:commons-lang
|
||||
*
|
||||
* @param array 数组。元素类型为Map.Entry、数组、Iterable、Iterator
|
||||
@@ -326,7 +339,7 @@ public class MapUtil {
|
||||
* {a: 4}
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 结果是:
|
||||
*
|
||||
* <pre>
|
||||
@@ -380,7 +393,7 @@ public class MapUtil {
|
||||
* c: [1]
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 结果是:
|
||||
*
|
||||
* <pre>
|
||||
@@ -435,6 +448,8 @@ public class MapUtil {
|
||||
* 将已知Map转换为key为驼峰风格的Map<br>
|
||||
* 如果KEY为非String类型,保留原值
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param map 原Map
|
||||
* @return 驼峰风格Map
|
||||
* @since 3.3.1
|
||||
@@ -446,7 +461,7 @@ public class MapUtil {
|
||||
/**
|
||||
* 将键值对转换为二维数组,第一维是key,第二纬是value
|
||||
*
|
||||
* @param map Map<?, ?> map
|
||||
* @param map map
|
||||
* @return 数组
|
||||
* @since 4.1.9
|
||||
*/
|
||||
@@ -468,6 +483,7 @@ public class MapUtil {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- join
|
||||
|
||||
/**
|
||||
* 将map转成字符串
|
||||
*
|
||||
@@ -527,6 +543,7 @@ public class MapUtil {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- filter
|
||||
|
||||
/**
|
||||
* 过滤<br>
|
||||
* 过滤过程通过传入的Editor实现来返回需要的元素内容,这个Editor实现可以实现以下功能:
|
||||
@@ -685,10 +702,12 @@ public class MapUtil {
|
||||
/**
|
||||
* 排序已有Map,Key有序的Map,使用默认Key排序方式(字母顺序)
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param map Map
|
||||
* @return TreeMap
|
||||
* @since 4.0.1
|
||||
* @see #newTreeMap(Map, Comparator)
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public static <K, V> TreeMap<K, V> sort(Map<K, V> map) {
|
||||
return sort(map, null);
|
||||
@@ -697,11 +716,13 @@ public class MapUtil {
|
||||
/**
|
||||
* 排序已有Map,Key有序的Map
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param map Map
|
||||
* @param comparator Key比较器
|
||||
* @return TreeMap
|
||||
* @since 4.0.1
|
||||
* @see #newTreeMap(Map, Comparator)
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public static <K, V> TreeMap<K, V> sort(Map<K, V> map, Comparator<? super K> comparator) {
|
||||
TreeMap<K, V> result;
|
||||
@@ -734,6 +755,8 @@ public class MapUtil {
|
||||
* 创建Map包装类MapWrapper<br>
|
||||
* {@link MapWrapper}对Map做一次包装
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param map 被代理的Map
|
||||
* @return {@link MapWrapper}
|
||||
* @since 4.5.4
|
||||
@@ -743,6 +766,7 @@ public class MapUtil {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- builder
|
||||
|
||||
/**
|
||||
* 创建链接调用map
|
||||
*
|
||||
@@ -751,7 +775,7 @@ public class MapUtil {
|
||||
* @return map创建类
|
||||
*/
|
||||
public static <K, V> MapBuilder<K, V> builder() {
|
||||
return builder(new HashMap<K, V>());
|
||||
return builder(new HashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -941,6 +965,8 @@ public class MapUtil {
|
||||
* 实现方式为一处然后重新put,当旧的key不存在直接返回<br>
|
||||
* 当新的key存在,抛出{@link IllegalArgumentException} 异常
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param map Map
|
||||
* @param oldKey 原键
|
||||
* @param newKey 新键
|
||||
@@ -962,6 +988,8 @@ public class MapUtil {
|
||||
* 去除Map中值为{@code null}的键值对<br>
|
||||
* 注意:此方法在传入的Map上直接修改。
|
||||
*
|
||||
* @param <K> key的类型
|
||||
* @param <V> value的类型
|
||||
* @param map Map
|
||||
* @return map
|
||||
* @since 4.6.5
|
||||
@@ -973,9 +1001,9 @@ public class MapUtil {
|
||||
|
||||
final Iterator<Entry<K, V>> iter = map.entrySet().iterator();
|
||||
Entry<K, V> entry;
|
||||
while(iter.hasNext()) {
|
||||
while (iter.hasNext()) {
|
||||
entry = iter.next();
|
||||
if(null == entry.getValue()) {
|
||||
if (null == entry.getValue()) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ public class LocalPortGenerater implements Serializable{
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param beginPort
|
||||
* @param beginPort 起始端口号
|
||||
*/
|
||||
public LocalPortGenerater(int beginPort) {
|
||||
alternativePort = new AtomicInteger(beginPort);
|
||||
|
@@ -175,6 +175,7 @@ public class NetUtil {
|
||||
* 获取多个本地可用端口<br>
|
||||
* 来自org.springframework.util.SocketUtils
|
||||
*
|
||||
* @param numRequested 尝试次数
|
||||
* @param minPort 端口最小值(包含)
|
||||
* @param maxPort 端口最大值(包含)
|
||||
* @return 可用的端口
|
||||
@@ -311,7 +312,7 @@ public class NetUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CollectionUtil.addAll(new ArrayList<NetworkInterface>(), networkInterfaces);
|
||||
return CollectionUtil.addAll(new ArrayList<>(), networkInterfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -17,7 +17,7 @@ import cn.hutool.core.util.HexUtil;
|
||||
* 1.字符"a"-"z","A"-"Z","0"-"9",".","-","*",和"_" 都不会被编码;
|
||||
* 2.将空格转换为%20 ;
|
||||
* 3.将非文本内容转换成"%xy"的形式,xy是两位16进制的数值;
|
||||
* 4.在每个 name=value 对之间放置 & 符号。
|
||||
* 4.在每个 name=value 对之间放置 & 符号。
|
||||
* </pre>
|
||||
*
|
||||
* @author looly,
|
||||
@@ -34,7 +34,7 @@ public class URLEncoder implements Serializable{
|
||||
* <pre>
|
||||
* pchar = unreserved(不处理) / pct-encoded / sub-delims(子分隔符) / ":" / "@"
|
||||
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
||||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
||||
* </pre>
|
||||
*/
|
||||
public static final URLEncoder DEFAULT = createDefault();
|
||||
@@ -46,7 +46,7 @@ public class URLEncoder implements Serializable{
|
||||
* <pre>
|
||||
* 0x20 ' ' =》 '+'
|
||||
* 0x2A, 0x2D, 0x2E, 0x30 to 0x39, 0x41 to 0x5A, 0x5F, 0x61 to 0x7A as-is
|
||||
* '*', '-', '.', '0' to '9', 'A' to 'Z', '_', 'a' to 'z' Also '=' and '&' 不编码
|
||||
* '*', '-', '.', '0' to '9', 'A' to 'Z', '_', 'a' to 'z' Also '=' and '&' 不编码
|
||||
* 其它编码为 %nn 形式
|
||||
* </pre>
|
||||
*
|
||||
@@ -61,7 +61,7 @@ public class URLEncoder implements Serializable{
|
||||
* <pre>
|
||||
* pchar = unreserved(不处理) / pct-encoded / sub-delims(子分隔符) / ":" / "@"
|
||||
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
||||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
||||
* </pre>
|
||||
*
|
||||
* @return {@link URLEncoder}
|
||||
@@ -100,7 +100,7 @@ public class URLEncoder implements Serializable{
|
||||
* <pre>
|
||||
* 0x20 ' ' =》 '+'
|
||||
* 0x2A, 0x2D, 0x2E, 0x30 to 0x39, 0x41 to 0x5A, 0x5F, 0x61 to 0x7A as-is
|
||||
* '*', '-', '.', '0' to '9', 'A' to 'Z', '_', 'a' to 'z' Also '=' and '&' 不编码
|
||||
* '*', '-', '.', '0' to '9', 'A' to 'Z', '_', 'a' to 'z' Also '=' and '&' 不编码
|
||||
* 其它编码为 %nn 形式
|
||||
* </pre>
|
||||
*
|
||||
|
@@ -97,7 +97,7 @@ public class ClipboardUtil {
|
||||
/**
|
||||
* 从剪贴板的{@link Transferable}获取文本
|
||||
*
|
||||
* @param content
|
||||
* @param content {@link Transferable}
|
||||
* @return 文本
|
||||
* @since 4.5.6
|
||||
*/
|
||||
@@ -126,7 +126,7 @@ public class ClipboardUtil {
|
||||
/**
|
||||
* 从剪贴板的{@link Transferable}获取图片
|
||||
*
|
||||
* @param content
|
||||
* @param content {@link Transferable}
|
||||
* @return 图片
|
||||
* @since 4.5.6
|
||||
*/
|
||||
|
@@ -57,7 +57,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<>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class Simhash {
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照(frac, <simhash, content>)索引进行存储
|
||||
* 按照(frac, 《simhash, content》)索引进行存储
|
||||
*
|
||||
* @param simhash Simhash值
|
||||
*/
|
||||
@@ -146,7 +146,7 @@ public class Simhash {
|
||||
if (fracMap.containsKey(frac)) {
|
||||
fracMap.get(frac).add(simhash);
|
||||
} else {
|
||||
final List<Long> ls = new ArrayList<Long>();
|
||||
final List<Long> ls = new ArrayList<>();
|
||||
ls.add(simhash);
|
||||
fracMap.put(frac, ls);
|
||||
}
|
||||
@@ -184,7 +184,7 @@ public class Simhash {
|
||||
final int bitNum = this.bitNum;
|
||||
final int fracBitNum = this.fracBitNum;
|
||||
|
||||
final List<String> ls = new ArrayList<String>();
|
||||
final List<String> ls = new ArrayList<>();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < bitNum; i++) {
|
||||
sb.append(simhash >> i & 1);
|
||||
|
@@ -155,6 +155,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
/**
|
||||
* 追加对象,对象会被转换为字符串
|
||||
*
|
||||
* @param index 插入位置
|
||||
* @param obj 对象
|
||||
* @return this
|
||||
*/
|
||||
@@ -392,7 +393,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
* @param start 开始位置,负数按照0处理(包括)
|
||||
* @param end 结束位置,超出最大长度按照最大长度处理(不包括)
|
||||
* @return this
|
||||
* @throws StringIndexOutOfBoundsException 当start > end抛出此异常
|
||||
* @throws StringIndexOutOfBoundsException 当start > end抛出此异常
|
||||
*/
|
||||
public StrBuilder del(int start, int end) throws StringIndexOutOfBoundsException {
|
||||
if (start < 0) {
|
||||
|
@@ -13,6 +13,7 @@ import java.nio.charset.Charset;
|
||||
public class CsvUtil {
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------- Reader
|
||||
|
||||
/**
|
||||
* 获取CSV读取器
|
||||
*
|
||||
@@ -33,11 +34,13 @@ public class CsvUtil {
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------- Writer
|
||||
|
||||
/**
|
||||
* 获取CSV生成器(写出器),使用默认配置,覆盖已有文件(如果存在)
|
||||
*
|
||||
* @param filePath File CSV文件路径
|
||||
* @param charset 编码
|
||||
* @return {@link CsvWriter}
|
||||
*/
|
||||
public static CsvWriter getWriter(String filePath, Charset charset) {
|
||||
return new CsvWriter(filePath, charset);
|
||||
@@ -48,6 +51,7 @@ public class CsvUtil {
|
||||
*
|
||||
* @param file File CSV文件
|
||||
* @param charset 编码
|
||||
* @return {@link CsvWriter}
|
||||
*/
|
||||
public static CsvWriter getWriter(File file, Charset charset) {
|
||||
return new CsvWriter(file, charset);
|
||||
@@ -59,6 +63,7 @@ public class CsvUtil {
|
||||
* @param filePath File CSV文件路径
|
||||
* @param charset 编码
|
||||
* @param isAppend 是否追加
|
||||
* @return {@link CsvWriter}
|
||||
*/
|
||||
public static CsvWriter getWriter(String filePath, Charset charset, boolean isAppend) {
|
||||
return new CsvWriter(filePath, charset, isAppend);
|
||||
@@ -70,6 +75,7 @@ public class CsvUtil {
|
||||
* @param file File CSV文件
|
||||
* @param charset 编码
|
||||
* @param isAppend 是否追加
|
||||
* @return {@link CsvWriter}
|
||||
*/
|
||||
public static CsvWriter getWriter(File file, Charset charset, boolean isAppend) {
|
||||
return new CsvWriter(file, charset, isAppend);
|
||||
@@ -82,6 +88,7 @@ public class CsvUtil {
|
||||
* @param charset 编码
|
||||
* @param isAppend 是否追加
|
||||
* @param config 写出配置,null则使用默认配置
|
||||
* @return {@link CsvWriter}
|
||||
*/
|
||||
public static CsvWriter getWriter(File file, Charset charset, boolean isAppend, CsvWriteConfig config) {
|
||||
return new CsvWriter(file, charset, isAppend, config);
|
||||
|
@@ -9,7 +9,7 @@ import cn.hutool.core.date.TimeInterval;
|
||||
* ps:
|
||||
* //模拟1000个线程并发
|
||||
* ConcurrencyTester ct = new ConcurrencyTester(1000);
|
||||
* ct.test(() -> {
|
||||
* ct.test(() -> {
|
||||
* // 需要并发测试的业务代码
|
||||
* });
|
||||
* </pre>
|
||||
@@ -30,6 +30,7 @@ public class ConcurrencyTester {
|
||||
* 执行测试
|
||||
*
|
||||
* @param runnable 要测试的内容
|
||||
* @return this
|
||||
*/
|
||||
public ConcurrencyTester test(Runnable runnable) {
|
||||
timeInterval.start();
|
||||
|
@@ -16,7 +16,7 @@ import cn.hutool.core.exceptions.UtilException;
|
||||
* ps:
|
||||
* //模拟1000个线程并发
|
||||
* SyncFinisher sf = new SyncFinisher(1000);
|
||||
* concurrencyTestUtil.run(() -> {
|
||||
* concurrencyTestUtil.run(() -> {
|
||||
* // 需要并发测试的业务代码
|
||||
* });
|
||||
* </pre>
|
||||
@@ -46,7 +46,7 @@ public class SyncFinisher {
|
||||
this.beginLatch = new CountDownLatch(1);
|
||||
this.threadSize = threadSize;
|
||||
this.executorService = ThreadUtil.newExecutor(threadSize);
|
||||
this.workers = new LinkedHashSet<Worker>();
|
||||
this.workers = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -68,7 +68,7 @@ public class ThreadUtil {
|
||||
* 传入阻塞系数,线程池的大小计算公式为:CPU可用核心数 / (1 - 阻塞因子)<br>
|
||||
* Blocking Coefficient(阻塞系数) = 阻塞时间/(阻塞时间+使用CPU的时间)<br>
|
||||
* 计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近于1。
|
||||
*
|
||||
* <p>
|
||||
* see: http://blog.csdn.net/partner4java/article/details/9417663
|
||||
*
|
||||
* @param blockingCoefficient 阻塞系数,阻塞因子介于0~1之间的数,阻塞因子越大,线程池中的线程数越多。
|
||||
@@ -240,9 +240,9 @@ public class ThreadUtil {
|
||||
/**
|
||||
* 考虑{@link Thread#sleep(long)}方法有可能时间不足给定毫秒数,此方法保证sleep时间不小于给定的毫秒数
|
||||
*
|
||||
* @see ThreadUtil#sleep(Number)
|
||||
* @param millis 给定的sleep时间
|
||||
* @return 被中断返回false,否则true
|
||||
* @see ThreadUtil#sleep(Number)
|
||||
*/
|
||||
public static boolean safeSleep(Number millis) {
|
||||
long millisLong = millis.longValue();
|
||||
@@ -326,7 +326,7 @@ public class ThreadUtil {
|
||||
* @param thread 线程
|
||||
*/
|
||||
public static void waitForDie(Thread thread) {
|
||||
if(null == thread){
|
||||
if (null == thread) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -397,6 +397,7 @@ public class ThreadUtil {
|
||||
*
|
||||
* @param prefix 线程名前缀
|
||||
* @param isDaemon 是否守护线程
|
||||
* @return {@link ThreadFactory}
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static ThreadFactory newNamedThreadFactory(String prefix, boolean isDaemon) {
|
||||
@@ -409,6 +410,7 @@ public class ThreadUtil {
|
||||
* @param prefix 线程名前缀
|
||||
* @param threadGroup 线程组,可以为null
|
||||
* @param isDaemon 是否守护线程
|
||||
* @return {@link ThreadFactory}
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon) {
|
||||
@@ -422,6 +424,7 @@ public class ThreadUtil {
|
||||
* @param threadGroup 线程组,可以为null
|
||||
* @param isDaemon 是否守护线程
|
||||
* @param handler 未捕获异常处理
|
||||
* @return {@link ThreadFactory}
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon, UncaughtExceptionHandler handler) {
|
||||
|
@@ -829,6 +829,7 @@ public class ArrayUtil {
|
||||
/**
|
||||
* 去除{@code null} 元素
|
||||
*
|
||||
* @param <T> 数组元素类型
|
||||
* @param array 数组
|
||||
* @return 处理后的数组
|
||||
* @since 3.2.2
|
||||
@@ -846,6 +847,7 @@ public class ArrayUtil {
|
||||
/**
|
||||
* 去除{@code null}或者"" 元素
|
||||
*
|
||||
* @param <T> 数组元素类型
|
||||
* @param array 数组
|
||||
* @return 处理后的数组
|
||||
* @since 3.2.2
|
||||
@@ -862,6 +864,7 @@ public class ArrayUtil {
|
||||
/**
|
||||
* 去除{@code null}或者""或者空白字符串 元素
|
||||
*
|
||||
* @param <T> 数组元素类型
|
||||
* @param array 数组
|
||||
* @return 处理后的数组
|
||||
* @since 3.2.2
|
||||
@@ -1901,6 +1904,7 @@ public class ArrayUtil {
|
||||
/**
|
||||
* 获取子数组
|
||||
*
|
||||
* @param <T> 数组元素类型
|
||||
* @param array 数组
|
||||
* @param start 开始位置(包括)
|
||||
* @param end 结束位置(不包括)
|
||||
@@ -3886,6 +3890,7 @@ public class ArrayUtil {
|
||||
* 去重数组中的元素,去重后生成新的数组,原数组不变<br>
|
||||
* 此方法通过{@link LinkedHashSet} 去重
|
||||
*
|
||||
* @param <T> 数组元素类型
|
||||
* @param array 数组
|
||||
* @return 去重后的数组
|
||||
*/
|
||||
|
@@ -53,13 +53,13 @@ public class EnumUtil {
|
||||
/**
|
||||
* 字符串转枚举,调用{@link Enum#valueOf(Class, String)}
|
||||
*
|
||||
* @param <T> 枚举类型泛型
|
||||
* @param <E> 枚举类型泛型
|
||||
* @param enumClass 枚举类
|
||||
* @param value 值
|
||||
* @return 枚举值
|
||||
* @since 4.1.13
|
||||
*/
|
||||
public static <T extends Enum<T>> T fromString(Class<T> enumClass, String value) {
|
||||
public static <E extends Enum<E>> E fromString(Class<E> enumClass, String value) {
|
||||
return Enum.valueOf(enumClass, value);
|
||||
}
|
||||
|
||||
@@ -67,28 +67,28 @@ public class EnumUtil {
|
||||
* 字符串转枚举,调用{@link Enum#valueOf(Class, String)}<br>
|
||||
* 如果无枚举值,返回默认值
|
||||
*
|
||||
* @param <T> 枚举类型泛型
|
||||
* @param <E> 枚举类型泛型
|
||||
* @param enumClass 枚举类
|
||||
* @param value 值
|
||||
* @param defaultValue 无对应枚举值返回的默认值
|
||||
* @return 枚举值
|
||||
* @since 4.5.18
|
||||
*/
|
||||
public static <T extends Enum<T>> T fromString(Class<T> enumClass, String value, T defaultValue) {
|
||||
public static <E extends Enum<E>> E fromString(Class<E> enumClass, String value, E defaultValue) {
|
||||
return ObjectUtil.defaultIfNull(fromStringQuietly(enumClass, value), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转枚举,调用{@link Enum#valueOf(Class, String)},转换失败返回{@code null} 而非报错
|
||||
*
|
||||
* @param <T> 枚举类型泛型
|
||||
* @param <E> 枚举类型泛型
|
||||
* @param enumClass 枚举类
|
||||
* @param value 值
|
||||
* @return 枚举值
|
||||
* @since 4.5.18
|
||||
*/
|
||||
public static <T extends Enum<T>> T fromStringQuietly(Class<T> enumClass, String value) {
|
||||
if(null == enumClass || StrUtil.isBlank(value)) {
|
||||
public static <E extends Enum<E>> E fromStringQuietly(Class<E> enumClass, String value) {
|
||||
if (null == enumClass || StrUtil.isBlank(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -102,12 +102,13 @@ public class EnumUtil {
|
||||
/**
|
||||
* 模糊匹配转换为枚举,给定一个值,匹配枚举中定义的所有字段名(包括name属性),一旦匹配到返回这个枚举对象,否则返回null
|
||||
*
|
||||
* @param <E> 枚举类型
|
||||
* @param enumClass 枚举类
|
||||
* @param value 值
|
||||
* @return 匹配到的枚举对象,未匹配到返回null
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Enum<T>> T likeValueOf(Class<T> enumClass, Object value) {
|
||||
public static <E extends Enum<E>> E likeValueOf(Class<E> enumClass, Object value) {
|
||||
if (value instanceof CharSequence) {
|
||||
value = value.toString().trim();
|
||||
}
|
||||
@@ -123,7 +124,7 @@ public class EnumUtil {
|
||||
}
|
||||
for (Enum<?> enumObj : enums) {
|
||||
if (ObjectUtil.equal(value, ReflectUtil.getFieldValue(enumObj, field))) {
|
||||
return (T) enumObj;
|
||||
return (E) enumObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,6 +200,7 @@ public class EnumUtil {
|
||||
* 获取枚举字符串值和枚举对象的Map对应,使用LinkedHashMap保证有序<br>
|
||||
* 结果中键为枚举名,值为枚举对象
|
||||
*
|
||||
* @param <E> 枚举类型
|
||||
* @param enumClass 枚举类
|
||||
* @return 枚举字符串值和枚举对象的Map对应,使用LinkedHashMap保证有序
|
||||
* @since 4.0.2
|
||||
@@ -234,9 +236,9 @@ public class EnumUtil {
|
||||
/**
|
||||
* 判断某个值是存在枚举中
|
||||
*
|
||||
* @param <E> 枚举类型
|
||||
* @param enumClass 枚举类
|
||||
* @param val 需要查找的值
|
||||
* @param <E>
|
||||
* @return 是否存在
|
||||
*/
|
||||
public static <E extends Enum<E>> boolean contains(final Class<E> enumClass, String val) {
|
||||
@@ -246,9 +248,9 @@ public class EnumUtil {
|
||||
/**
|
||||
* 判断某个值是不存在枚举中
|
||||
*
|
||||
* @param <E> 枚举类型
|
||||
* @param enumClass 枚举类
|
||||
* @param val 需要查找的值
|
||||
* @param <E>
|
||||
* @return 是否不存在
|
||||
*/
|
||||
public static <E extends Enum<E>> boolean notContains(final Class<E> enumClass, String val) {
|
||||
|
@@ -467,6 +467,7 @@ public class RandomUtil {
|
||||
/**
|
||||
* 带有权重的随机生成器
|
||||
*
|
||||
* @param <T> 随机对象类型
|
||||
* @param weightObjs 带有权重的对象列表
|
||||
* @return {@link WeightRandom}
|
||||
* @since 4.0.3
|
||||
@@ -478,6 +479,7 @@ public class RandomUtil {
|
||||
/**
|
||||
* 带有权重的随机生成器
|
||||
*
|
||||
* @param <T> 随机对象类型
|
||||
* @param weightObjs 带有权重的对象列表
|
||||
* @return {@link WeightRandom}
|
||||
* @since 4.0.3
|
||||
|
@@ -830,6 +830,7 @@ public class ReflectUtil {
|
||||
*
|
||||
* @param <T> AccessibleObject的子类,比如Class、Method、Field等
|
||||
* @param accessibleObject 可设置访问权限的对象,比如Class、Method、Field等
|
||||
* @return 被设置可访问的对象
|
||||
* @since 4.6.8
|
||||
*/
|
||||
public static <T extends AccessibleObject> T setAccessible(T accessibleObject) {
|
||||
|
@@ -3495,11 +3495,13 @@ public class StrUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回字符串 searchStr 在字符串 str 中第 ordinal 次出现的位置。<br>
|
||||
* 如果 str=null 或 searchStr=null 或 ordinal<=0 则返回-1<br>
|
||||
* 返回字符串 searchStr 在字符串 str 中第 ordinal 次出现的位置。
|
||||
*
|
||||
* <p>
|
||||
* 如果 str=null 或 searchStr=null 或 ordinal≥0 则返回-1<br>
|
||||
* 此方法来自:Apache-Commons-Lang
|
||||
*
|
||||
* 栗子(*代表任意字符):
|
||||
* 例子(*代表任意字符):
|
||||
*
|
||||
* <pre>
|
||||
* StrUtil.ordinalIndexOf(null, *, *) = -1
|
||||
|
@@ -50,16 +50,20 @@ import cn.hutool.core.lang.Assert;
|
||||
* 工具类封装了XML文档的创建、读取、写出和部分XML操作
|
||||
*
|
||||
* @author xiaoleilu
|
||||
*
|
||||
*/
|
||||
public class XmlUtil {
|
||||
|
||||
/** 在XML中无效的字符 正则 */
|
||||
/**
|
||||
* 在XML中无效的字符 正则
|
||||
*/
|
||||
public final static String INVALID_REGEX = "[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]";
|
||||
/** XML格式化输出默认缩进量 */
|
||||
/**
|
||||
* XML格式化输出默认缩进量
|
||||
*/
|
||||
public final static int INDENT_DEFAULT = 2;
|
||||
|
||||
// -------------------------------------------------------------------------------------- Read
|
||||
|
||||
/**
|
||||
* 读取解析XML文件
|
||||
*
|
||||
@@ -207,6 +211,7 @@ public class XmlUtil {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------- Write
|
||||
|
||||
/**
|
||||
* 将XML文档转换为String<br>
|
||||
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8<br>
|
||||
@@ -363,6 +368,7 @@ public class XmlUtil {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------- Create
|
||||
|
||||
/**
|
||||
* 创建XML文档<br>
|
||||
* 创建的XML默认是utf8编码,修改编码的过程是在toStr和toFile方法里,即XML在转为文本的时候才定义编码
|
||||
@@ -407,6 +413,7 @@ public class XmlUtil {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------- Function
|
||||
|
||||
/**
|
||||
* 获得XML文档根节点
|
||||
*
|
||||
@@ -729,6 +736,7 @@ public class XmlUtil {
|
||||
* 将Map转换为XML格式的字符串
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param rootName 根节点名
|
||||
* @return XML格式的字符串
|
||||
* @since 4.0.8
|
||||
*/
|
||||
@@ -740,6 +748,7 @@ public class XmlUtil {
|
||||
* 将Map转换为XML
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param rootName 根节点名
|
||||
* @return XML
|
||||
* @since 4.0.9
|
||||
*/
|
||||
@@ -778,6 +787,7 @@ public class XmlUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 将Map转换为XML格式的字符串
|
||||
*
|
||||
|
@@ -53,6 +53,7 @@ public class BCUtil {
|
||||
*
|
||||
* @param encode 压缩公钥
|
||||
* @param curveName EC曲线名
|
||||
* @return 公钥
|
||||
* @since 4.4.4
|
||||
*/
|
||||
public static PublicKey decodeECPoint(String encode, String curveName) {
|
||||
@@ -65,6 +66,7 @@ public class BCUtil {
|
||||
*
|
||||
* @param encodeByte 压缩公钥
|
||||
* @param curveName EC曲线名,例如{@link KeyUtil#SM2_DEFAULT_CURVE}
|
||||
* @return 公钥
|
||||
* @since 4.4.4
|
||||
*/
|
||||
public static PublicKey decodeECPoint(byte[] encodeByte, String curveName) {
|
||||
@@ -108,7 +110,7 @@ public class BCUtil {
|
||||
*/
|
||||
public static PublicKey readPublicKey(InputStream pemStream) {
|
||||
final Certificate certificate = KeyUtil.readX509Certificate(pemStream);
|
||||
if(null == certificate) {
|
||||
if (null == certificate) {
|
||||
return null;
|
||||
}
|
||||
return certificate.getPublicKey();
|
||||
|
@@ -588,6 +588,7 @@ public class KeyUtil {
|
||||
/**
|
||||
* 获取主体算法名,例如RSA/ECB/PKCS1Padding的主体算法是RSA
|
||||
*
|
||||
* @param algorithm XXXwithXXX算法
|
||||
* @return 主体算法名
|
||||
* @since 4.5.2
|
||||
*/
|
||||
@@ -823,6 +824,7 @@ public class KeyUtil {
|
||||
*
|
||||
* @param encode 压缩公钥
|
||||
* @param curveName EC曲线名
|
||||
* @return 公钥
|
||||
* @since 4.4.4
|
||||
*/
|
||||
public static PublicKey decodeECPoint(String encode, String curveName) {
|
||||
@@ -835,6 +837,7 @@ public class KeyUtil {
|
||||
*
|
||||
* @param encodeByte 压缩公钥
|
||||
* @param curveName EC曲线名
|
||||
* @return 公钥
|
||||
* @since 4.4.4
|
||||
*/
|
||||
public static PublicKey decodeECPoint(byte[] encodeByte, String curveName) {
|
||||
|
@@ -50,7 +50,6 @@ import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||
* 3、摘要加密(digest),例如:MD5、SHA-1、SHA-256、HMAC等<br>
|
||||
*
|
||||
* @author xiaoleilu, Gsealy
|
||||
*
|
||||
*/
|
||||
public final class SecureUtil {
|
||||
|
||||
@@ -490,6 +489,7 @@ public final class SecureUtil {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------- 摘要算法
|
||||
|
||||
/**
|
||||
* MD5加密<br>
|
||||
* 例:
|
||||
@@ -810,6 +810,7 @@ public final class SecureUtil {
|
||||
* 私钥和公钥同时为空时生成一对新的私钥和公钥<br>
|
||||
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证
|
||||
*
|
||||
* @param algorithm 算法枚举
|
||||
* @param privateKey 私钥
|
||||
* @param publicKey 公钥
|
||||
* @return {@link Sign}
|
||||
@@ -927,6 +928,7 @@ public final class SecureUtil {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------- UUID
|
||||
|
||||
/**
|
||||
* 简化的UUID,去掉了横线
|
||||
*
|
||||
@@ -972,6 +974,7 @@ public final class SecureUtil {
|
||||
* 创建{@link Cipher}
|
||||
*
|
||||
* @param algorithm 算法
|
||||
* @return {@link Cipher}
|
||||
* @since 4.5.2
|
||||
*/
|
||||
public static Cipher createCipher(String algorithm) {
|
||||
@@ -991,6 +994,7 @@ public final class SecureUtil {
|
||||
* 创建{@link MessageDigest}
|
||||
*
|
||||
* @param algorithm 算法
|
||||
* @return {@link MessageDigest}
|
||||
* @since 4.5.2
|
||||
*/
|
||||
public static MessageDigest createMessageDigest(String algorithm) {
|
||||
@@ -1010,6 +1014,7 @@ public final class SecureUtil {
|
||||
* 创建{@link Mac}
|
||||
*
|
||||
* @param algorithm 算法
|
||||
* @return {@link Mac}
|
||||
* @since 4.5.13
|
||||
*/
|
||||
public static Mac createMac(String algorithm) {
|
||||
|
@@ -150,6 +150,7 @@ public abstract class AbstractAsymmetricCrypto<T extends AbstractAsymmetricCrypt
|
||||
* 编码为Base64字符串
|
||||
*
|
||||
* @param data 被加密的字符串
|
||||
* @param charset 编码
|
||||
* @param keyType 私钥或公钥 {@link KeyType}
|
||||
* @return Base64字符串
|
||||
* @since 4.0.1
|
||||
|
@@ -12,7 +12,7 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
* 使用方法如下:
|
||||
* <p>
|
||||
* <code>
|
||||
* String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br />
|
||||
* String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
|
||||
* </code>
|
||||
* <p>
|
||||
* 使用checkpw方法检查被加密的字符串是否与原始字符串匹配:
|
||||
@@ -24,8 +24,8 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
* gensalt方法提供了可选参数 (log_rounds) 来定义加盐多少,也决定了加密的复杂度:
|
||||
* <p>
|
||||
* <code>
|
||||
* String strong_salt = BCrypt.gensalt(10)<br />
|
||||
* String stronger_salt = BCrypt.gensalt(12)<br />
|
||||
* String strong_salt = BCrypt.gensalt(10);
|
||||
* String stronger_salt = BCrypt.gensalt(12);
|
||||
* </code>
|
||||
*
|
||||
* @author Damien Miller
|
||||
@@ -192,7 +192,7 @@ public class BCrypt {
|
||||
* @throws IllegalArgumentException if maxolen is invalid
|
||||
*/
|
||||
private static byte[] decodeBase64(String s, int maxolen) throws IllegalArgumentException {
|
||||
StringBuffer rs = new StringBuffer();
|
||||
final StringBuilder rs = new StringBuilder();
|
||||
int off = 0, slen = s.length(), olen = 0;
|
||||
byte[] ret;
|
||||
byte c1, c2, c3, c4, o;
|
||||
|
@@ -12,11 +12,11 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
* 摘要算法工具类
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class DigestUtil {
|
||||
|
||||
// ------------------------------------------------------------------------------------------- MD5
|
||||
|
||||
/**
|
||||
* 计算32位MD5摘要值
|
||||
*
|
||||
@@ -132,6 +132,7 @@ public class DigestUtil {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- MD5 16
|
||||
|
||||
/**
|
||||
* 计算16位MD5摘要值,并转为16进制字符串
|
||||
*
|
||||
@@ -200,6 +201,7 @@ public class DigestUtil {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- SHA-1
|
||||
|
||||
/**
|
||||
* 计算SHA-1摘要值
|
||||
*
|
||||
@@ -303,6 +305,7 @@ public class DigestUtil {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- SHA-256
|
||||
|
||||
/**
|
||||
* 计算SHA-256摘要值
|
||||
*
|
||||
@@ -416,6 +419,7 @@ public class DigestUtil {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- Hmac
|
||||
|
||||
/**
|
||||
* 创建HMac对象,调用digest方法可获得hmac值
|
||||
*
|
||||
@@ -477,6 +481,7 @@ public class DigestUtil {
|
||||
* 验证密码是否与Bcrypt加密后的密文匹配
|
||||
*
|
||||
* @param password 明文密码
|
||||
* @param hashed hash值(加密后的值)
|
||||
* @return 是否匹配
|
||||
* @since 4.1.1
|
||||
*/
|
||||
|
@@ -29,17 +29,19 @@ import cn.hutool.db.sql.Wrapper;
|
||||
* 提供抽象方法getConnection和closeConnection,用于自定义数据库连接的打开和关闭
|
||||
*
|
||||
* @author Luxiaolei
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractDb implements Serializable{
|
||||
public abstract class AbstractDb implements Serializable {
|
||||
private static final long serialVersionUID = 3858951941916349062L;
|
||||
|
||||
protected DataSource ds;
|
||||
/** 是否支持事务 */
|
||||
/**
|
||||
* 是否支持事务
|
||||
*/
|
||||
protected Boolean isSupportTransaction = null;
|
||||
protected SqlConnRunner runner;
|
||||
|
||||
// ------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
@@ -85,7 +87,6 @@ public abstract class AbstractDb implements Serializable{
|
||||
* 查询
|
||||
*
|
||||
* @param <T> 结果集需要处理的对象类型
|
||||
*
|
||||
* @param sql 查询语句
|
||||
* @param beanClass 元素Bean类型
|
||||
* @param params 参数
|
||||
@@ -228,6 +229,7 @@ public abstract class AbstractDb implements Serializable{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------- CRUD start
|
||||
|
||||
/**
|
||||
* 插入数据
|
||||
*
|
||||
@@ -368,6 +370,7 @@ public abstract class AbstractDb implements Serializable{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------- Get start
|
||||
|
||||
/**
|
||||
* 根据某个字段(最好是唯一字段)查询单个记录<br>
|
||||
* 当有多条返回时,只显示查询到的第一条
|
||||
@@ -486,6 +489,7 @@ public abstract class AbstractDb implements Serializable{
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param where 条件实体类(包含表名)
|
||||
* @param beanClass Bean类
|
||||
* @return 数据对象列表
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 3.2.2
|
||||
@@ -767,6 +771,7 @@ public abstract class AbstractDb implements Serializable{
|
||||
// ---------------------------------------------------------------------------- CRUD end
|
||||
|
||||
// ---------------------------------------------------------------------------- Getters and Setters start
|
||||
|
||||
/**
|
||||
* 获取{@link SqlConnRunner}
|
||||
*
|
||||
@@ -821,6 +826,7 @@ public abstract class AbstractDb implements Serializable{
|
||||
// ---------------------------------------------------------------------------- Getters and Setters end
|
||||
|
||||
// ---------------------------------------------------------------------------- protected method start
|
||||
|
||||
/**
|
||||
* 检查数据库是否支持事务,此项检查同一个数据源只检查一次,如果不支持抛出DbRuntimeException异常
|
||||
*
|
||||
|
@@ -123,8 +123,6 @@ public class Session extends AbstractDb implements Closeable {
|
||||
public void commit() throws SQLException {
|
||||
try {
|
||||
getConnection().commit();
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} finally {
|
||||
try {
|
||||
getConnection().setAutoCommit(true); // 事务结束,恢复自动提交
|
||||
@@ -142,8 +140,6 @@ public class Session extends AbstractDb implements Closeable {
|
||||
public void rollback() throws SQLException {
|
||||
try {
|
||||
getConnection().rollback();
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} finally {
|
||||
try {
|
||||
getConnection().setAutoCommit(true); // 事务结束,恢复自动提交
|
||||
@@ -180,8 +176,6 @@ public class Session extends AbstractDb implements Closeable {
|
||||
public void rollback(Savepoint savepoint) throws SQLException {
|
||||
try {
|
||||
getConnection().rollback(savepoint);
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} finally {
|
||||
try {
|
||||
getConnection().setAutoCommit(true); // 事务结束,恢复自动提交
|
||||
@@ -195,9 +189,8 @@ public class Session extends AbstractDb implements Closeable {
|
||||
* 静默回滚到某个保存点,保存点的设置请使用setSavepoint方法
|
||||
*
|
||||
* @param savepoint 保存点
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public void quietRollback(Savepoint savepoint) throws SQLException {
|
||||
public void quietRollback(Savepoint savepoint) {
|
||||
try {
|
||||
getConnection().rollback(savepoint);
|
||||
} catch (Exception e) {
|
||||
@@ -255,7 +248,7 @@ public class Session extends AbstractDb implements Closeable {
|
||||
* 在事务中执行操作,通过实现{@link VoidFunc0}接口的call方法执行多条SQL语句从而完成事务
|
||||
*
|
||||
* @param func 函数抽象,在函数中执行多个SQL操作,多个操作会被合并为同一事务
|
||||
* @throws SQLException
|
||||
* @throws SQLException SQL异常
|
||||
* @since 3.2.3
|
||||
*/
|
||||
public void tx(VoidFunc1<Session> func) throws SQLException {
|
||||
|
@@ -28,10 +28,10 @@ import java.util.List;
|
||||
* SQL执行类<br>
|
||||
* 此执行类只接受方言参数,不需要数据源,只有在执行方法时需要数据库连接对象<br>
|
||||
* 此对象存在的意义在于,可以由使用者自定义数据库连接对象,并执行多个方法,方便事务的统一控制或减少连接对象的创建关闭
|
||||
* @author Luxiaolei
|
||||
*
|
||||
* @author Luxiaolei
|
||||
*/
|
||||
public class SqlConnRunner{
|
||||
public class SqlConnRunner {
|
||||
private Dialect dialect;
|
||||
|
||||
/**
|
||||
@@ -65,8 +65,10 @@ public class SqlConnRunner{
|
||||
}
|
||||
|
||||
//------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param dialect 方言
|
||||
*/
|
||||
public SqlConnRunner(Dialect dialect) {
|
||||
@@ -75,6 +77,7 @@ public class SqlConnRunner{
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param driverClassName 驱动类名,,用于识别方言
|
||||
*/
|
||||
public SqlConnRunner(String driverClassName) {
|
||||
@@ -83,9 +86,11 @@ public class SqlConnRunner{
|
||||
//------------------------------------------------------- Constructor end
|
||||
|
||||
//---------------------------------------------------------------------------- CRUD start
|
||||
|
||||
/**
|
||||
* 插入数据<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param record 记录
|
||||
* @return 插入行数
|
||||
@@ -93,7 +98,7 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public int insert(Connection conn, Entity record) throws SQLException {
|
||||
checkConn(conn);
|
||||
if(CollectionUtil.isEmpty(record)){
|
||||
if (CollectionUtil.isEmpty(record)) {
|
||||
throw new SQLException("Empty entity provided!");
|
||||
}
|
||||
PreparedStatement ps = null;
|
||||
@@ -117,9 +122,9 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public int insertOrUpdate(Connection conn, Entity record, String... keys) throws SQLException {
|
||||
final Entity where = record.filter(keys);
|
||||
if(MapUtil.isNotEmpty(where) && count(conn, where) > 0) {
|
||||
if (MapUtil.isNotEmpty(where) && count(conn, where) > 0) {
|
||||
return update(conn, record, where);
|
||||
}else {
|
||||
} else {
|
||||
return insert(conn, record);
|
||||
}
|
||||
}
|
||||
@@ -151,13 +156,13 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public int[] insert(Connection conn, Entity... records) throws SQLException {
|
||||
checkConn(conn);
|
||||
if(ArrayUtil.isEmpty(records)){
|
||||
if (ArrayUtil.isEmpty(records)) {
|
||||
return new int[]{0};
|
||||
}
|
||||
|
||||
//单条单独处理
|
||||
if(1 == records.length) {
|
||||
return new int[] { insert(conn, records[0])};
|
||||
if (1 == records.length) {
|
||||
return new int[]{insert(conn, records[0])};
|
||||
}
|
||||
|
||||
PreparedStatement ps = null;
|
||||
@@ -172,6 +177,7 @@ public class SqlConnRunner{
|
||||
/**
|
||||
* 插入数据<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param record 记录
|
||||
* @return 主键列表
|
||||
@@ -179,7 +185,7 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public List<Object> insertForGeneratedKeys(Connection conn, Entity record) throws SQLException {
|
||||
checkConn(conn);
|
||||
if(CollectionUtil.isEmpty(record)){
|
||||
if (CollectionUtil.isEmpty(record)) {
|
||||
throw new SQLException("Empty entity provided!");
|
||||
}
|
||||
|
||||
@@ -196,6 +202,7 @@ public class SqlConnRunner{
|
||||
/**
|
||||
* 插入数据<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param record 记录
|
||||
* @return 自增主键
|
||||
@@ -203,7 +210,7 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public Long insertForGeneratedKey(Connection conn, Entity record) throws SQLException {
|
||||
checkConn(conn);
|
||||
if(CollectionUtil.isEmpty(record)){
|
||||
if (CollectionUtil.isEmpty(record)) {
|
||||
throw new SQLException("Empty entity provided!");
|
||||
}
|
||||
|
||||
@@ -220,6 +227,7 @@ public class SqlConnRunner{
|
||||
/**
|
||||
* 删除数据<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param where 条件
|
||||
* @return 影响行数
|
||||
@@ -227,7 +235,7 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public int del(Connection conn, Entity where) throws SQLException {
|
||||
checkConn(conn);
|
||||
if(CollectionUtil.isEmpty(where)){
|
||||
if (CollectionUtil.isEmpty(where)) {
|
||||
//不允许做全表删除
|
||||
throw new SQLException("Empty entity provided!");
|
||||
}
|
||||
@@ -245,6 +253,7 @@ public class SqlConnRunner{
|
||||
/**
|
||||
* 更新数据<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param record 记录
|
||||
* @param where 条件
|
||||
@@ -253,17 +262,17 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public int update(Connection conn, Entity record, Entity where) throws SQLException {
|
||||
checkConn(conn);
|
||||
if(CollectionUtil.isEmpty(record)){
|
||||
if (CollectionUtil.isEmpty(record)) {
|
||||
throw new SQLException("Empty entity provided!");
|
||||
}
|
||||
if(CollectionUtil.isEmpty(where)){
|
||||
if (CollectionUtil.isEmpty(where)) {
|
||||
//不允许做全表更新
|
||||
throw new SQLException("Empty where provided!");
|
||||
}
|
||||
|
||||
//表名可以从被更新记录的Entity中获得,也可以从Where中获得
|
||||
String tableName = record.getTableName();
|
||||
if(StrUtil.isBlank(tableName)){
|
||||
if (StrUtil.isBlank(tableName)) {
|
||||
tableName = where.getTableName();
|
||||
record.setTableName(tableName);
|
||||
}
|
||||
@@ -345,7 +354,7 @@ public class SqlConnRunner{
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 3.2.1
|
||||
*/
|
||||
public List<Entity> find(Connection conn, Entity where) throws SQLException{
|
||||
public List<Entity> find(Connection conn, Entity where) throws SQLException {
|
||||
return find(conn, where.getFieldNames(), where, EntityListHandler.create());
|
||||
}
|
||||
|
||||
@@ -357,7 +366,7 @@ public class SqlConnRunner{
|
||||
* @return 数据对象列表
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public List<Entity> findAll(Connection conn, Entity where) throws SQLException{
|
||||
public List<Entity> findAll(Connection conn, Entity where) throws SQLException {
|
||||
return find(conn, where, EntityListHandler.create());
|
||||
}
|
||||
|
||||
@@ -369,7 +378,7 @@ public class SqlConnRunner{
|
||||
* @return 数据对象列表
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public List<Entity> findAll(Connection conn, String tableName) throws SQLException{
|
||||
public List<Entity> findAll(Connection conn, String tableName) throws SQLException {
|
||||
return findAll(conn, Entity.create(tableName));
|
||||
}
|
||||
|
||||
@@ -383,7 +392,7 @@ public class SqlConnRunner{
|
||||
* @return 数据对象列表
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public List<Entity> findBy(Connection conn, String tableName, String field, Object value) throws SQLException{
|
||||
public List<Entity> findBy(Connection conn, String tableName, String field, Object value) throws SQLException {
|
||||
return findAll(conn, Entity.create(tableName).set(field, value));
|
||||
}
|
||||
|
||||
@@ -398,7 +407,7 @@ public class SqlConnRunner{
|
||||
* @return 数据对象列表
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public List<Entity> findLike(Connection conn, String tableName, String field, String value, LikeType likeType) throws SQLException{
|
||||
public List<Entity> findLike(Connection conn, String tableName, String field, String value, LikeType likeType) throws SQLException {
|
||||
return findAll(conn, Entity.create(tableName).set(field, SqlUtil.buildLikeValue(value, likeType, true)));
|
||||
}
|
||||
|
||||
@@ -412,12 +421,13 @@ public class SqlConnRunner{
|
||||
* @return 数据对象列表
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public List<Entity> findIn(Connection conn, String tableName, String field, Object... values) throws SQLException{
|
||||
public List<Entity> findIn(Connection conn, String tableName, String field, Object... values) throws SQLException {
|
||||
return findAll(conn, Entity.create(tableName).set(field, values));
|
||||
}
|
||||
|
||||
/**
|
||||
* 结果的条目数
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param where 查询条件
|
||||
* @return 复合条件的结果数
|
||||
@@ -469,7 +479,7 @@ public class SqlConnRunner{
|
||||
*/
|
||||
public <T> T page(Connection conn, Collection<String> fields, Entity where, Page page, RsHandler<T> rsh) throws SQLException {
|
||||
checkConn(conn);
|
||||
if(null == page){
|
||||
if (null == page) {
|
||||
return this.find(conn, fields, where, rsh);
|
||||
}
|
||||
|
||||
@@ -514,7 +524,7 @@ public class SqlConnRunner{
|
||||
checkConn(conn);
|
||||
|
||||
//查询全部
|
||||
if(null == page){
|
||||
if (null == page) {
|
||||
List<Entity> entityList = this.find(conn, fields, where, new EntityListHandler());
|
||||
final PageResult<Entity> pageResult = new PageResult<>(0, entityList.size(), entityList.size());
|
||||
pageResult.addAll(entityList);
|
||||
@@ -542,15 +552,19 @@ public class SqlConnRunner{
|
||||
//---------------------------------------------------------------------------- CRUD end
|
||||
|
||||
//---------------------------------------------------------------------------- Getters and Setters end
|
||||
|
||||
/**
|
||||
* @return SQL方言
|
||||
*/
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置SQL方言
|
||||
*
|
||||
* @param dialect 方言
|
||||
* @return this
|
||||
*/
|
||||
public SqlConnRunner setDialect(Dialect dialect) {
|
||||
this.dialect = dialect;
|
||||
@@ -559,6 +573,7 @@ public class SqlConnRunner{
|
||||
|
||||
/**
|
||||
* 设置包装器,包装器用于对表名、字段名进行符号包装(例如双引号),防止关键字与这些表名或字段冲突
|
||||
*
|
||||
* @param wrapperChar 包装字符,字符会在SQL生成时位于表名和字段名两边,null时表示取消包装
|
||||
* @return this
|
||||
* @since 4.0.0
|
||||
@@ -569,6 +584,7 @@ public class SqlConnRunner{
|
||||
|
||||
/**
|
||||
* 设置包装器,包装器用于对表名、字段名进行符号包装(例如双引号),防止关键字与这些表名或字段冲突
|
||||
*
|
||||
* @param wrapper 包装器,null表示取消包装
|
||||
* @return this
|
||||
* @since 4.0.0
|
||||
@@ -580,8 +596,8 @@ public class SqlConnRunner{
|
||||
//---------------------------------------------------------------------------- Getters and Setters end
|
||||
|
||||
//---------------------------------------------------------------------------- Private method start
|
||||
private void checkConn(Connection conn){
|
||||
if(null == conn){
|
||||
private void checkConn(Connection conn) {
|
||||
if (null == conn) {
|
||||
throw new NullPointerException("Connection object is null!");
|
||||
}
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@ public enum ThreadLocalConnection {
|
||||
*
|
||||
* @param ds 数据源
|
||||
* @return Connection
|
||||
* @throws SQLException
|
||||
* @throws SQLException SQL异常
|
||||
*/
|
||||
public Connection get(DataSource ds) throws SQLException {
|
||||
Connection conn = connMap.get(ds);
|
||||
|
@@ -140,7 +140,7 @@ public abstract class DSFactory implements Closeable, Serializable{
|
||||
/**
|
||||
* 创建数据源实现工厂<br>
|
||||
* 此方法通过“试错”方式查找引入项目的连接池库,按照优先级寻找,一旦寻找到则创建对应的数据源工厂<br>
|
||||
* 连接池优先级:Hikari > Druid > Tomcat > Dbcp > C3p0 > Hutool Pooled
|
||||
* 连接池优先级:Hikari > Druid > Tomcat > Dbcp > C3p0 > Hutool Pooled
|
||||
*
|
||||
* @return 日志实现类
|
||||
*/
|
||||
@@ -153,7 +153,7 @@ public abstract class DSFactory implements Closeable, Serializable{
|
||||
/**
|
||||
* 创建数据源实现工厂<br>
|
||||
* 此方法通过“试错”方式查找引入项目的连接池库,按照优先级寻找,一旦寻找到则创建对应的数据源工厂<br>
|
||||
* 连接池优先级:Hikari > Druid > Tomcat > Dbcp > C3p0 > Hutool Pooled
|
||||
* 连接池优先级:Hikari > Druid > Tomcat > Dbcp > C3p0 > Hutool Pooled
|
||||
*
|
||||
* @return 日志实现类
|
||||
* @since 4.1.3
|
||||
|
@@ -31,6 +31,7 @@ public class DataSourceWrapper implements DataSource, Closeable, Cloneable {
|
||||
*
|
||||
* @param ds 原始的DataSource
|
||||
* @param driver 数据库驱动类名
|
||||
* @return {@link DataSourceWrapper}
|
||||
*/
|
||||
public static DataSourceWrapper wrap(DataSource ds, String driver) {
|
||||
return new DataSourceWrapper(ds, driver);
|
||||
|
@@ -30,6 +30,7 @@ public class HandleHelper {
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param columnCount 列数
|
||||
* @param meta ResultSetMetaData
|
||||
* @param rs 数据集
|
||||
@@ -45,6 +46,7 @@ public class HandleHelper {
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param columnCount 列数
|
||||
* @param meta ResultSetMetaData
|
||||
* @param rs 数据集
|
||||
@@ -84,8 +86,8 @@ public class HandleHelper {
|
||||
final Map<String, PropDesc> propMap = BeanUtil.getBeanDesc(beanClass).getPropMap(true);
|
||||
String columnLabel;
|
||||
PropDesc pd;
|
||||
Method setter = null;
|
||||
Object value = null;
|
||||
Method setter;
|
||||
Object value;
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
columnLabel = meta.getColumnLabel(i);
|
||||
pd = propMap.get(columnLabel);
|
||||
|
@@ -30,6 +30,7 @@ public enum SqlLog {
|
||||
* @param isShowSql 是否显示SQL
|
||||
* @param isFormatSql 是否格式化显示的SQL
|
||||
* @param isShowParams 是否打印参数
|
||||
* @param level 日志级别
|
||||
*/
|
||||
public void init(boolean isShowSql, boolean isFormatSql, boolean isShowParams, Level level) {
|
||||
this.showSql = isShowSql;
|
||||
|
@@ -89,7 +89,7 @@ public class SqlUtil {
|
||||
* 2、LikeType.EndWith: value%
|
||||
* 3、LikeType.Contains: %value%
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* 如果withLikeKeyword为true,则结果为:
|
||||
*
|
||||
* <pre>
|
||||
@@ -100,6 +100,7 @@ public class SqlUtil {
|
||||
*
|
||||
* @param value 被查找值
|
||||
* @param likeType LIKE值类型 {@link LikeType}
|
||||
* @param withLikeKeyword 是否包含LIKE关键字
|
||||
* @return 拼接后的like值
|
||||
*/
|
||||
public static String buildLikeValue(String value, LikeType likeType, boolean withLikeKeyword) {
|
||||
|
@@ -42,30 +42,42 @@ import cn.hutool.setting.dialect.Props;
|
||||
* </pre>
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class Setting extends AbsSetting implements Map<String, String> {
|
||||
private static final long serialVersionUID = 3618305164959883393L;
|
||||
|
||||
/** 默认字符集 */
|
||||
/**
|
||||
* 默认字符集
|
||||
*/
|
||||
public final static Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8;
|
||||
/** 默认配置文件扩展名 */
|
||||
/**
|
||||
* 默认配置文件扩展名
|
||||
*/
|
||||
public final static String EXT_NAME = "setting";
|
||||
|
||||
/** 附带分组的键值对存储 */
|
||||
/**
|
||||
* 附带分组的键值对存储
|
||||
*/
|
||||
private final GroupedMap groupedMap = new GroupedMap();
|
||||
|
||||
/** 本设置对象的字符集 */
|
||||
/**
|
||||
* 本设置对象的字符集
|
||||
*/
|
||||
protected Charset charset;
|
||||
/** 是否使用变量 */
|
||||
/**
|
||||
* 是否使用变量
|
||||
*/
|
||||
protected boolean isUseVariable;
|
||||
/** 设定文件的URL */
|
||||
/**
|
||||
* 设定文件的URL
|
||||
*/
|
||||
protected URL settingUrl;
|
||||
|
||||
private SettingLoader settingLoader;
|
||||
private WatchMonitor watchMonitor;
|
||||
|
||||
// ------------------------------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 空构造
|
||||
*/
|
||||
@@ -305,6 +317,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------- Functions
|
||||
|
||||
/**
|
||||
* 持久化当前设置,会覆盖掉之前的设置<br>
|
||||
* 持久化不会保留之前的分组
|
||||
@@ -359,6 +372,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
* 正则只能有一个group表示变量本身,剩余为字符 例如 \$\{(name)\}表示${name}变量名为name的一个变量表示
|
||||
*
|
||||
* @param regex 正则
|
||||
* @return this
|
||||
*/
|
||||
public Setting setVarRegex(String regex) {
|
||||
if (null == this.settingLoader) {
|
||||
@@ -381,6 +395,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
}
|
||||
|
||||
// ------------------------------------------------- Map interface with group
|
||||
|
||||
/**
|
||||
* 某个分组对应的键值对是否为空
|
||||
*
|
||||
|
@@ -485,6 +485,7 @@ public final class Props extends Properties implements BasicTypeGetter<String>,
|
||||
* ['person']['friends'][5]['name']
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param beanClass Bean类
|
||||
* @return Bean对象
|
||||
* @since 4.6.3
|
||||
@@ -505,6 +506,7 @@ public final class Props extends Properties implements BasicTypeGetter<String>,
|
||||
* ['person']['friends'][5]['name']
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param beanClass Bean类
|
||||
* @param prefix 公共前缀,不指定前缀传null,当指定前缀后非此前缀的属性被忽略
|
||||
* @return Bean对象
|
||||
@@ -527,6 +529,7 @@ public final class Props extends Properties implements BasicTypeGetter<String>,
|
||||
* ['person']['friends'][5]['name']
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param bean Bean对象
|
||||
* @param prefix 公共前缀,不指定前缀传null,当指定前缀后非此前缀的属性被忽略
|
||||
* @return Bean对象
|
||||
|
Reference in New Issue
Block a user