mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
Merge remote-tracking branch 'origin/v5-dev' into v5-dev
This commit is contained in:
commit
aa263733e0
19
CHANGELOG.md
19
CHANGELOG.md
@ -3,14 +3,31 @@
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
# 5.6.1 (2021-03-14)
|
# 5.6.2 (2021-03-18)
|
||||||
|
|
||||||
|
### 新特性
|
||||||
|
### Bug修复
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# 5.6.1 (2021-03-18)
|
||||||
|
|
||||||
### 新特性
|
### 新特性
|
||||||
* 【crypto 】 SecureUtil去除final修饰符(issue#1474@Github)
|
* 【crypto 】 SecureUtil去除final修饰符(issue#1474@Github)
|
||||||
* 【core 】 IoUtil增加lineIter方法
|
* 【core 】 IoUtil增加lineIter方法
|
||||||
|
* 【core 】 新增函数式懒加载加载器(pr#275@Gitee)
|
||||||
|
* 【http 】 UserAgentUtil增加miniProgram判断(issue#1475@Github)
|
||||||
|
* 【db 】 增加Ignite数据库驱动识别
|
||||||
|
* 【core 】 DateUtil.parse支持带毫秒的UTC时间
|
||||||
|
* 【core 】 IdcardUtil.Idcard增加toString(pr#1487@Github)
|
||||||
|
* 【core 】 ChineseDate增加getGregorianXXX方法(issue#1481@Github)
|
||||||
|
|
||||||
### Bug修复
|
### Bug修复
|
||||||
* 【core 】 修复IoUtil.readBytes的FileInputStream中isClose参数失效问题(issue#I3B7UD@Gitee)
|
* 【core 】 修复IoUtil.readBytes的FileInputStream中isClose参数失效问题(issue#I3B7UD@Gitee)
|
||||||
|
* 【core 】 修复DataUnit中KB不大写的问题
|
||||||
|
* 【json 】 修复JSONUtil.getByPath类型错误问题(issue#I3BSDF@Gitee)
|
||||||
|
* 【core 】 修复BeanUtil.toBean提供null未返回null的问题(issue#I3BQPV@Gitee)
|
||||||
|
* 【core 】 修复ModifierUtil#modifiersToInt中逻辑判断问题(issue#1486@Github)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
14
README-EN.md
14
README-EN.md
@ -125,19 +125,19 @@ Each module can be introduced individually, or all modules can be introduced by
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
<version>5.6.1</version>
|
<version>5.6.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Gradle
|
### Gradle
|
||||||
```
|
```
|
||||||
compile 'cn.hutool:hutool-all:5.6.1'
|
compile 'cn.hutool:hutool-all:5.6.2'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
- [Maven1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.1/)
|
- [Maven1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.2/)
|
||||||
- [Maven2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.6.1/)
|
- [Maven2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.6.2/)
|
||||||
|
|
||||||
> note:
|
> note:
|
||||||
> Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available.
|
> Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available.
|
||||||
@ -199,6 +199,10 @@ If you think Hutool is good, you can donate to buy tshe author a pack of chili~,
|
|||||||
|
|
||||||
## WeChat Official Account
|
## WeChat Official Account
|
||||||
|
|
||||||
Welcome to the official account of Hutool cooperation.
|
#### Welcome to the official account of Hutool cooperation.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Welcome to organization Dromara
|
||||||
|
|
||||||
|

|
12
README.md
12
README.md
@ -123,20 +123,20 @@ Hutool的存在就是为了减少代码搜索成本,避免网络上参差不
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
<version>5.6.1</version>
|
<version>5.6.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Gradle
|
### Gradle
|
||||||
```
|
```
|
||||||
compile 'cn.hutool:hutool-all:5.6.1'
|
compile 'cn.hutool:hutool-all:5.6.2'
|
||||||
```
|
```
|
||||||
|
|
||||||
### 非Maven项目
|
### 非Maven项目
|
||||||
|
|
||||||
点击以下任一链接,下载`hutool-all-X.X.X.jar`即可:
|
点击以下任一链接,下载`hutool-all-X.X.X.jar`即可:
|
||||||
|
|
||||||
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.1/)
|
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.2/)
|
||||||
|
|
||||||
> 注意
|
> 注意
|
||||||
> Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。
|
> Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。
|
||||||
@ -207,6 +207,10 @@ Hutool欢迎任何人为Hutool添砖加瓦,贡献代码,不过维护者是
|
|||||||
|
|
||||||
## 公众号
|
## 公众号
|
||||||
|
|
||||||
欢迎关注Hutool合作的公众号。
|
#### 欢迎关注Hutool合作的公众号
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Dromara开源组织公众号
|
||||||
|
|
||||||
|

|
@ -1 +1 @@
|
|||||||
5.6.1
|
5.6.2
|
||||||
|
@ -1 +1 @@
|
|||||||
var version = '5.6.1'
|
var version = '5.6.2'
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-aop</artifactId>
|
<artifactId>hutool-aop</artifactId>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-bloomFilter</artifactId>
|
<artifactId>hutool-bloomFilter</artifactId>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-bom</artifactId>
|
<artifactId>hutool-bom</artifactId>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-cache</artifactId>
|
<artifactId>hutool-cache</artifactId>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-captcha</artifactId>
|
<artifactId>hutool-captcha</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-core</artifactId>
|
<artifactId>hutool-core</artifactId>
|
||||||
|
@ -544,6 +544,9 @@ public class BeanUtil {
|
|||||||
* @since 5.2.4
|
* @since 5.2.4
|
||||||
*/
|
*/
|
||||||
public static <T> T toBean(Object source, Class<T> clazz, CopyOptions options) {
|
public static <T> T toBean(Object source, Class<T> clazz, CopyOptions options) {
|
||||||
|
if(null == source){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final T target = ReflectUtil.newInstanceIfPossible(clazz);
|
final T target = ReflectUtil.newInstanceIfPossible(clazz);
|
||||||
copyProperties(source, target, options);
|
copyProperties(source, target, options);
|
||||||
return target;
|
return target;
|
||||||
@ -559,6 +562,9 @@ public class BeanUtil {
|
|||||||
* @return Bean
|
* @return Bean
|
||||||
*/
|
*/
|
||||||
public static <T> T toBean(Class<T> beanClass, ValueProvider<String> valueProvider, CopyOptions copyOptions) {
|
public static <T> T toBean(Class<T> beanClass, ValueProvider<String> valueProvider, CopyOptions copyOptions) {
|
||||||
|
if (null == beanClass || null == valueProvider) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return fillBean(ReflectUtil.newInstanceIfPossible(beanClass), valueProvider, copyOptions);
|
return fillBean(ReflectUtil.newInstanceIfPossible(beanClass), valueProvider, copyOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,6 +606,9 @@ public class BeanUtil {
|
|||||||
* @return Map
|
* @return Map
|
||||||
*/
|
*/
|
||||||
public static Map<String, Object> beanToMap(Object bean, boolean isToUnderlineCase, boolean ignoreNullValue) {
|
public static Map<String, Object> beanToMap(Object bean, boolean isToUnderlineCase, boolean ignoreNullValue) {
|
||||||
|
if (null == bean) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return beanToMap(bean, new LinkedHashMap<>(), isToUnderlineCase, ignoreNullValue);
|
return beanToMap(bean, new LinkedHashMap<>(), isToUnderlineCase, ignoreNullValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +623,7 @@ public class BeanUtil {
|
|||||||
* @since 3.2.3
|
* @since 3.2.3
|
||||||
*/
|
*/
|
||||||
public static Map<String, Object> beanToMap(Object bean, Map<String, Object> targetMap, final boolean isToUnderlineCase, boolean ignoreNullValue) {
|
public static Map<String, Object> beanToMap(Object bean, Map<String, Object> targetMap, final boolean isToUnderlineCase, boolean ignoreNullValue) {
|
||||||
if (bean == null) {
|
if (null == bean) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,7 +648,7 @@ public class BeanUtil {
|
|||||||
* @since 4.0.5
|
* @since 4.0.5
|
||||||
*/
|
*/
|
||||||
public static Map<String, Object> beanToMap(Object bean, Map<String, Object> targetMap, boolean ignoreNullValue, Editor<String> keyEditor) {
|
public static Map<String, Object> beanToMap(Object bean, Map<String, Object> targetMap, boolean ignoreNullValue, Editor<String> keyEditor) {
|
||||||
if (bean == null) {
|
if (null == bean) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import cn.hutool.core.date.chinese.LunarFestival;
|
|||||||
import cn.hutool.core.date.chinese.LunarInfo;
|
import cn.hutool.core.date.chinese.LunarInfo;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
@ -151,6 +152,16 @@ public class ChineseDate {
|
|||||||
return this.year;
|
return this.year;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公历的年
|
||||||
|
*
|
||||||
|
* @return 公历年
|
||||||
|
* @since 5.6.1
|
||||||
|
*/
|
||||||
|
public int getGregorianYear(){
|
||||||
|
return this.gyear;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取农历的月,从1开始计数
|
* 获取农历的月,从1开始计数
|
||||||
*
|
*
|
||||||
@ -161,6 +172,26 @@ public class ChineseDate {
|
|||||||
return this.month;
|
return this.month;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公历的月,从1开始计数
|
||||||
|
*
|
||||||
|
* @return 公历月
|
||||||
|
* @since 5.6.1
|
||||||
|
*/
|
||||||
|
public int getGregorianMonthBase1(){
|
||||||
|
return this.gmonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公历的月,从0开始计数
|
||||||
|
*
|
||||||
|
* @return 公历月
|
||||||
|
* @since 5.6.1
|
||||||
|
*/
|
||||||
|
public int getGregorianMonth(){
|
||||||
|
return this.gmonth -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前农历月份是否为闰月
|
* 当前农历月份是否为闰月
|
||||||
*
|
*
|
||||||
@ -200,6 +231,16 @@ public class ChineseDate {
|
|||||||
return this.day;
|
return this.day;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公历的日
|
||||||
|
*
|
||||||
|
* @return 公历日
|
||||||
|
* @since 5.6.1
|
||||||
|
*/
|
||||||
|
public int getGregorianDay(){
|
||||||
|
return this.gday;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得农历日
|
* 获得农历日
|
||||||
*
|
*
|
||||||
@ -223,6 +264,28 @@ public class ChineseDate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公历的Date
|
||||||
|
*
|
||||||
|
* @return 公历Date
|
||||||
|
* @since 5.6.1
|
||||||
|
*/
|
||||||
|
public Date getGregorianDate(){
|
||||||
|
return DateUtil.date(getGregorianCalendar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公历的Calendar
|
||||||
|
*
|
||||||
|
* @return 公历Calendar
|
||||||
|
* @since 5.6.1
|
||||||
|
*/
|
||||||
|
public Calendar getGregorianCalendar(){
|
||||||
|
final Calendar calendar = CalendarUtil.calendar();
|
||||||
|
//noinspection MagicConstant
|
||||||
|
calendar.set(this.gyear, getGregorianMonth(), this.gday, 0, 0, 0);
|
||||||
|
return calendar;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得节日
|
* 获得节日
|
||||||
|
@ -200,6 +200,15 @@ public class DatePattern {
|
|||||||
*/
|
*/
|
||||||
public static final FastDateFormat UTC_SIMPLE_FORMAT = FastDateFormat.getInstance(UTC_SIMPLE_PATTERN, TimeZone.getTimeZone("UTC"));
|
public static final FastDateFormat UTC_SIMPLE_FORMAT = FastDateFormat.getInstance(UTC_SIMPLE_PATTERN, TimeZone.getTimeZone("UTC"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UTC时间:yyyy-MM-dd'T'HH:mm:ss.SSS
|
||||||
|
*/
|
||||||
|
public static final String UTC_SIMPLE_MS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS";
|
||||||
|
/**
|
||||||
|
* UTC时间{@link FastDateFormat}:yyyy-MM-dd'T'HH:mm:ss.SSS
|
||||||
|
*/
|
||||||
|
public static final FastDateFormat UTC_SIMPLE_MS_FORMAT = FastDateFormat.getInstance(UTC_SIMPLE_MS_PATTERN, TimeZone.getTimeZone("UTC"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UTC时间:yyyy-MM-dd'T'HH:mm:ss'Z'
|
* UTC时间:yyyy-MM-dd'T'HH:mm:ss'Z'
|
||||||
*/
|
*/
|
||||||
|
@ -836,6 +836,9 @@ public class DateUtil extends CalendarUtil {
|
|||||||
} else if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 2) {
|
} else if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 2) {
|
||||||
// 格式类似:2018-09-13T05:34:31
|
// 格式类似:2018-09-13T05:34:31
|
||||||
return parse(utcString, DatePattern.UTC_SIMPLE_FORMAT);
|
return parse(utcString, DatePattern.UTC_SIMPLE_FORMAT);
|
||||||
|
} else if (StrUtil.contains(utcString, CharUtil.DOT)){
|
||||||
|
// 可能为: 2021-03-17T06:31:33.99
|
||||||
|
return parse(utcString, DatePattern.UTC_SIMPLE_MS_FORMAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 没有更多匹配的时间格式
|
// 没有更多匹配的时间格式
|
||||||
|
@ -44,7 +44,7 @@ public enum DataUnit {
|
|||||||
*/
|
*/
|
||||||
TERABYTES("TB", DataSize.ofTerabytes(1));
|
TERABYTES("TB", DataSize.ofTerabytes(1));
|
||||||
|
|
||||||
public static final String[] UNIT_NAMES = new String[]{"B", "kB", "MB", "GB", "TB", "PB", "EB"};
|
public static final String[] UNIT_NAMES = new String[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"};
|
||||||
|
|
||||||
private final String suffix;
|
private final String suffix;
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public enum DataUnit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过后缀返回对应的 {@link DataUnit}
|
* 通过后缀返回对应的 DataUnit
|
||||||
*
|
*
|
||||||
* @param suffix 单位后缀
|
* @param suffix 单位后缀
|
||||||
* @return 匹配到的{@link DataUnit}
|
* @return 匹配到的{@link DataUnit}
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package cn.hutool.core.lang.loader;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 函数式懒加载加载器<br>
|
||||||
|
* 传入用于生成对象的函数,在对象需要使用时调用生成对象,然后抛弃此生成对象的函数。<br>
|
||||||
|
* 此加载器常用于对象比较庞大而不一定被使用的情况,用于减少启动时资源占用问题<br>
|
||||||
|
* 继承自{@link LazyLoader},如何实现多线程安全,由LazyLoader完成。
|
||||||
|
*
|
||||||
|
* @param <T> 被加载对象类型
|
||||||
|
* @author Mr.Po
|
||||||
|
* @see cn.hutool.core.lang.loader.LazyLoader
|
||||||
|
* @since 5.6.1
|
||||||
|
*/
|
||||||
|
public class LazyFunLoader<T> extends LazyLoader<T> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于生成对象的函数
|
||||||
|
*/
|
||||||
|
private Supplier<T> supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param supplier 用于生成对象的函数
|
||||||
|
*/
|
||||||
|
public LazyFunLoader(Supplier<T> supplier) {
|
||||||
|
Assert.notNull(supplier);
|
||||||
|
this.supplier = supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected T init() {
|
||||||
|
T t = this.supplier.get();
|
||||||
|
this.supplier = null;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已经初始化
|
||||||
|
*
|
||||||
|
* @return 是/否
|
||||||
|
*/
|
||||||
|
public boolean isInitialize() {
|
||||||
|
return this.supplier == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果已经初始化,就执行传入函数
|
||||||
|
*
|
||||||
|
* @param consumer 待执行函数
|
||||||
|
*/
|
||||||
|
public void ifInitialized(Consumer<T> consumer) {
|
||||||
|
Assert.notNull(consumer);
|
||||||
|
|
||||||
|
// 已经初始化
|
||||||
|
if (this.isInitialize()) {
|
||||||
|
consumer.accept(this.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -753,8 +753,8 @@ public class Money implements Serializable, Comparable<Money> {
|
|||||||
|
|
||||||
long total = 0;
|
long total = 0;
|
||||||
|
|
||||||
for (int i = 0; i < ratios.length; i++) {
|
for (long element : ratios) {
|
||||||
total += ratios[i];
|
total += element;
|
||||||
}
|
}
|
||||||
|
|
||||||
long remainder = cent;
|
long remainder = cent;
|
||||||
|
@ -719,5 +719,15 @@ public class IdcardUtil {
|
|||||||
public Integer getGender() {
|
public Integer getGender() {
|
||||||
return this.gender;
|
return this.gender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Idcard{" +
|
||||||
|
"provinceCode='" + provinceCode + '\'' +
|
||||||
|
", cityCode='" + cityCode + '\'' +
|
||||||
|
", birthDate=" + birthDate +
|
||||||
|
", gender=" + gender +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ public class ModifierUtil {
|
|||||||
private static int modifiersToInt(ModifierType... modifierTypes) {
|
private static int modifiersToInt(ModifierType... modifierTypes) {
|
||||||
int modifier = modifierTypes[0].getValue();
|
int modifier = modifierTypes[0].getValue();
|
||||||
for(int i = 1; i < modifierTypes.length; i++) {
|
for(int i = 1; i < modifierTypes.length; i++) {
|
||||||
modifier &= modifierTypes[i].getValue();
|
modifier |= modifierTypes[i].getValue();
|
||||||
}
|
}
|
||||||
return modifier;
|
return modifier;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ public class ChineseDateTest {
|
|||||||
@Test
|
@Test
|
||||||
public void chineseDateTest() {
|
public void chineseDateTest() {
|
||||||
ChineseDate date = new ChineseDate(DateUtil.parseDate("2020-01-25"));
|
ChineseDate date = new ChineseDate(DateUtil.parseDate("2020-01-25"));
|
||||||
|
Assert.assertEquals("2020-01-25 00:00:00", date.getGregorianDate().toString());
|
||||||
Assert.assertEquals(2020, date.getChineseYear());
|
Assert.assertEquals(2020, date.getChineseYear());
|
||||||
|
|
||||||
Assert.assertEquals(1, date.getMonth());
|
Assert.assertEquals(1, date.getMonth());
|
||||||
@ -50,6 +51,7 @@ public class ChineseDateTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getChineseMonthTest(){
|
public void getChineseMonthTest(){
|
||||||
ChineseDate chineseDate = new ChineseDate(2020,6,15);
|
ChineseDate chineseDate = new ChineseDate(2020,6,15);
|
||||||
|
Assert.assertEquals("2020-08-04 00:00:00", chineseDate.getGregorianDate().toString());
|
||||||
Assert.assertEquals("六月", chineseDate.getChineseMonth());
|
Assert.assertEquals("六月", chineseDate.getChineseMonth());
|
||||||
|
|
||||||
chineseDate = new ChineseDate(2020,4,15);
|
chineseDate = new ChineseDate(2020,4,15);
|
||||||
|
@ -550,6 +550,13 @@ public class DateUtilTest {
|
|||||||
assert dt != null;
|
assert dt != null;
|
||||||
dateStr = dt.toString(simpleDateFormat);
|
dateStr = dt.toString(simpleDateFormat);
|
||||||
Assert.assertEquals("2018-09-13 13:34:39.999", dateStr);
|
Assert.assertEquals("2018-09-13 13:34:39.999", dateStr);
|
||||||
|
|
||||||
|
// 使用UTC时区
|
||||||
|
dateStr1 = "2018-09-13T13:34:39.99";
|
||||||
|
dt = DateUtil.parse(dateStr1);
|
||||||
|
assert dt != null;
|
||||||
|
dateStr = dt.toString();
|
||||||
|
Assert.assertEquals("2018-09-13 13:34:39", dateStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -6,10 +6,6 @@ import org.junit.Ignore;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件类型判断单元测试
|
* 文件类型判断单元测试
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package cn.hutool.core.lang.loader;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class LazyFunLoaderTest {
|
||||||
|
|
||||||
|
static class BigObject {
|
||||||
|
|
||||||
|
private boolean isDestroy = false;
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
this.isDestroy = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
LazyFunLoader<BigObject> loader = new LazyFunLoader<>(BigObject::new);
|
||||||
|
|
||||||
|
Assert.assertNotNull(loader.get());
|
||||||
|
Assert.assertTrue(loader.isInitialize());
|
||||||
|
|
||||||
|
// 对于某些对象,在程序关闭时,需要进行销毁操作
|
||||||
|
loader.ifInitialized(BigObject::destroy);
|
||||||
|
|
||||||
|
Assert.assertTrue(loader.get().isDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
LazyFunLoader<BigObject> loader = new LazyFunLoader<>(BigObject::new);
|
||||||
|
|
||||||
|
// 若从未使用,则可以避免不必要的初始化
|
||||||
|
loader.ifInitialized(it -> {
|
||||||
|
|
||||||
|
Assert.fail();
|
||||||
|
it.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.assertFalse(loader.isInitialize());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package cn.hutool.core.util;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class ModifierUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasModifierTest() throws NoSuchMethodException {
|
||||||
|
Method method = ModifierUtilTest.class.getDeclaredMethod("ddd");
|
||||||
|
Assert.assertTrue(ModifierUtil.hasModifier(method, ModifierUtil.ModifierType.PRIVATE));
|
||||||
|
Assert.assertTrue(ModifierUtil.hasModifier(method,
|
||||||
|
ModifierUtil.ModifierType.PRIVATE,
|
||||||
|
ModifierUtil.ModifierType.STATIC)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private static void ddd() {
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-cron</artifactId>
|
<artifactId>hutool-cron</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-crypto</artifactId>
|
<artifactId>hutool-crypto</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-db</artifactId>
|
<artifactId>hutool-db</artifactId>
|
||||||
|
@ -52,6 +52,10 @@ public class DialectFactory {
|
|||||||
public static final String DRIVER_DM7 = "dm.jdbc.driver.DmDriver";
|
public static final String DRIVER_DM7 = "dm.jdbc.driver.DmDriver";
|
||||||
/** JDBC 驱动 人大金仓 */
|
/** JDBC 驱动 人大金仓 */
|
||||||
public static final String DRIVER_KINGBASE8 = "com.kingbase8.Driver";
|
public static final String DRIVER_KINGBASE8 = "com.kingbase8.Driver";
|
||||||
|
/** JDBC 驱动 Ignite thin */
|
||||||
|
public static final String DRIVER_IGNITE_THIN = "org.apache.ignite.IgniteJdbcThinDriver";
|
||||||
|
/** JDBC 驱动 ClickHouse */
|
||||||
|
public static final String DRIVER_CLICK_HOUSE = "ru.yandex.clickhouse.ClickHouseDriver";
|
||||||
|
|
||||||
private static final Map<DataSource, Dialect> DIALECT_POOL = new ConcurrentHashMap<>();
|
private static final Map<DataSource, Dialect> DIALECT_POOL = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@ -138,6 +142,12 @@ public class DialectFactory {
|
|||||||
} else if (nameContainsProductInfo.contains("kingbase8")) {
|
} else if (nameContainsProductInfo.contains("kingbase8")) {
|
||||||
// 人大金仓8
|
// 人大金仓8
|
||||||
driver = DRIVER_KINGBASE8;
|
driver = DRIVER_KINGBASE8;
|
||||||
|
} else if (nameContainsProductInfo.contains("ignite")) {
|
||||||
|
// Ignite thin
|
||||||
|
driver = DRIVER_IGNITE_THIN;
|
||||||
|
} else if (nameContainsProductInfo.contains("clickhouse")) {
|
||||||
|
// ClickHouse
|
||||||
|
driver = DRIVER_CLICK_HOUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return driver;
|
return driver;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-dfa</artifactId>
|
<artifactId>hutool-dfa</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-extra</artifactId>
|
<artifactId>hutool-extra</artifactId>
|
||||||
|
@ -39,6 +39,12 @@ public class PinyinUtilTest {
|
|||||||
Assert.assertEquals("h, s, d, y, g", result);
|
Assert.assertEquals("h, s, d, y, g", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getFirstLetterTest2(){
|
||||||
|
final String result = PinyinUtil.getFirstLetter("崞阳", ", ");
|
||||||
|
Assert.assertEquals("g, y", result);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getFirstLetterByPinyin4jTest(){
|
public void getFirstLetterByPinyin4jTest(){
|
||||||
final Pinyin4jEngine engine = new Pinyin4jEngine();
|
final Pinyin4jEngine engine = new Pinyin4jEngine();
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-http</artifactId>
|
<artifactId>hutool-http</artifactId>
|
||||||
|
@ -50,6 +50,8 @@ public class Browser extends UserAgentInfo {
|
|||||||
new Browser("wxwork", "wxwork", "wxwork\\/([\\d\\w\\.\\-]+)"),
|
new Browser("wxwork", "wxwork", "wxwork\\/([\\d\\w\\.\\-]+)"),
|
||||||
// 微信
|
// 微信
|
||||||
new Browser("MicroMessenger", "MicroMessenger", "MicroMessenger\\/([\\d\\w\\.\\-]+)"),
|
new Browser("MicroMessenger", "MicroMessenger", "MicroMessenger\\/([\\d\\w\\.\\-]+)"),
|
||||||
|
// 微信小程序
|
||||||
|
new Browser("miniProgram", "miniProgram", "miniProgram\\/([\\d\\w\\.\\-]+)"),
|
||||||
// 钉钉
|
// 钉钉
|
||||||
new Browser("DingTalk", "DingTalk", "AliApp\\(DingTalk\\/([\\d\\w\\.\\-]+)\\)")
|
new Browser("DingTalk", "DingTalk", "AliApp\\(DingTalk\\/([\\d\\w\\.\\-]+)\\)")
|
||||||
);
|
);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-json</artifactId>
|
<artifactId>hutool-json</artifactId>
|
||||||
|
@ -543,7 +543,7 @@ public class JSONUtil {
|
|||||||
* @see JSON#getByPath(String)
|
* @see JSON#getByPath(String)
|
||||||
*/
|
*/
|
||||||
public static Object getByPath(JSON json, String expression) {
|
public static Object getByPath(JSON json, String expression) {
|
||||||
return (null == json || StrUtil.isBlank(expression)) ? null : json.getByPath(expression);
|
return getByPath(json, expression, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -572,7 +572,15 @@ public class JSONUtil {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T getByPath(JSON json, String expression, T defaultValue) {
|
public static <T> T getByPath(JSON json, String expression, T defaultValue) {
|
||||||
return (T) ObjectUtil.defaultIfNull(getByPath(json, expression), defaultValue);
|
if((null == json || StrUtil.isBlank(expression))){
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(null != defaultValue){
|
||||||
|
final Class<T> type = (Class<T>) defaultValue.getClass();
|
||||||
|
return ObjectUtil.defaultIfNull(json.getByPath(expression, type), defaultValue);
|
||||||
|
}
|
||||||
|
return (T) json.getByPath(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
27
hutool-json/src/test/java/cn/hutool/json/IssueI3BS4S.java
Normal file
27
hutool-json/src/test/java/cn/hutool/json/IssueI3BS4S.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package cn.hutool.json;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试带毫秒的日期转换
|
||||||
|
*/
|
||||||
|
public class IssueI3BS4S {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toBeanTest(){
|
||||||
|
String jsonStr = "{date: '2021-03-17T06:31:33.99'}";
|
||||||
|
final Bean1 bean1 = new Bean1();
|
||||||
|
BeanUtil.copyProperties(JSONUtil.parseObj(jsonStr), bean1);
|
||||||
|
Assert.assertEquals("2021-03-17T06:31:33.099", bean1.getDate().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean1{
|
||||||
|
private LocalDateTime date;
|
||||||
|
}
|
||||||
|
}
|
@ -19,4 +19,12 @@ public class JSONPathTest {
|
|||||||
value = JSONUtil.parseArray(json).getByPath("[1].name");
|
value = JSONUtil.parseArray(json).getByPath("[1].name");
|
||||||
Assert.assertEquals("mingzi", value);
|
Assert.assertEquals("mingzi", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getByPathTest2(){
|
||||||
|
String str = "{'accountId':111}";
|
||||||
|
JSON json = JSONUtil.parse(str);
|
||||||
|
Long accountId = JSONUtil.getByPath(json, "$.accountId", 0L);
|
||||||
|
Assert.assertEquals(111L, accountId.longValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-log</artifactId>
|
<artifactId>hutool-log</artifactId>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-poi</artifactId>
|
<artifactId>hutool-poi</artifactId>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-script</artifactId>
|
<artifactId>hutool-script</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-setting</artifactId>
|
<artifactId>hutool-setting</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-socket</artifactId>
|
<artifactId>hutool-socket</artifactId>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hutool-system</artifactId>
|
<artifactId>hutool-system</artifactId>
|
||||||
|
2
pom.xml
2
pom.xml
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-parent</artifactId>
|
<artifactId>hutool-parent</artifactId>
|
||||||
<version>5.6.1-SNAPSHOT</version>
|
<version>5.6.2-SNAPSHOT</version>
|
||||||
<name>hutool</name>
|
<name>hutool</name>
|
||||||
<description>Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。</description>
|
<description>Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。</description>
|
||||||
<url>https://github.com/looly/hutool</url>
|
<url>https://github.com/looly/hutool</url>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user