diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9285dd1e4..b4a3a1a9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,11 +8,14 @@
### 新特性
* 【core 】 解决NumberUtil导致的ambiguous问题(issue#630@Github)
* 【core 】 BeanUtil.isEmpty()忽略字段支持,增加isNotEmpty(issue#629@Github)
-* 【extra 】 邮件发送后获取message-id(issue#I15FKR@Gitee)
+* 【extra】 邮件发送后获取message-id(issue#I15FKR@Gitee)
+* 【core 】 CaseInsensitiveMap/CamelCaseMap增加toString(issue#636@Github)
+* 【core 】 XmlUtil多节点改进(issue#I15I0R@Gitee)
### Bug修复
* 【extra】 修复SFTP.upload上传失败的问题
* 【db】 修复findLike匹配错误问题
+* 【core 】 修复scale方法透明无效问题(issue#I15L5S@Gitee)
-------------------------------------------------------------------------------------------------------------
diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java
index f5a9ef759..c13a2b4d2 100644
--- a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java
+++ b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java
@@ -4,6 +4,8 @@ import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
+import java.time.Instant;
+import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -444,7 +446,35 @@ public class Convert {
public static Date toDate(Object value, Date defaultValue) {
return convertQuietly(Date.class, value, defaultValue);
}
-
+
+ /**
+ * LocalDateTime
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ * @since 5.0.7
+ */
+ public static Date toLocalDateTime(Object value, Date defaultValue) {
+ return convertQuietly(LocalDateTime.class, value, defaultValue);
+ }
+
+ /**
+ * Instant
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ * @since 5.0.7
+ */
+ public static Date toInstant(Object value, Date defaultValue) {
+ return convertQuietly(Instant.class, value, defaultValue);
+ }
+
/**
* 转换为Date
* 如果给定的值为空,或者转换失败,返回null
diff --git a/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromObjectGetter.java b/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromObjectGetter.java
index a693ca8c8..3317ffb51 100644
--- a/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromObjectGetter.java
+++ b/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromObjectGetter.java
@@ -10,21 +10,20 @@ import cn.hutool.core.convert.Convert;
* 基本类型的getter接口抽象实现,所有类型的值获取都是通过将getObj获得的值转换而来
* 用户只需实现getObj方法即可,其他类型将会从Object结果中转换
* 在不提供默认值的情况下, 如果值不存在或获取错误,返回null
+ *
* @author Looly
*/
-public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTypeGetter{
+public interface OptNullBasicTypeFromObjectGetter extends OptNullBasicTypeGetter{
- @Override
- public String getStr(K key, String defaultValue) {
+ default String getStr(K key, String defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
}
return Convert.toStr(obj, defaultValue);
}
-
- @Override
- public Integer getInt(K key, Integer defaultValue) {
+
+ default Integer getInt(K key, Integer defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -32,8 +31,7 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toInt(obj, defaultValue);
}
- @Override
- public Short getShort(K key, Short defaultValue) {
+ default Short getShort(K key, Short defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -41,8 +39,7 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toShort(obj, defaultValue);
}
- @Override
- public Boolean getBool(K key, Boolean defaultValue) {
+ default Boolean getBool(K key, Boolean defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -50,8 +47,7 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toBool(obj, defaultValue);
}
- @Override
- public Long getLong(K key, Long defaultValue) {
+ default Long getLong(K key, Long defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -59,17 +55,15 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toLong(obj, defaultValue);
}
- @Override
- public Character getChar(K key, Character defaultValue) {
+ default Character getChar(K key, Character defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
}
return Convert.toChar(obj, defaultValue);
}
-
- @Override
- public Float getFloat(K key, Float defaultValue) {
+
+ default Float getFloat(K key, Float defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -77,8 +71,7 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toFloat(obj, defaultValue);
}
- @Override
- public Double getDouble(K key, Double defaultValue) {
+ default Double getDouble(K key, Double defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -86,8 +79,7 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toDouble(obj, defaultValue);
}
- @Override
- public Byte getByte(K key, Byte defaultValue) {
+ default Byte getByte(K key, Byte defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -95,8 +87,7 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toByte(obj, defaultValue);
}
- @Override
- public BigDecimal getBigDecimal(K key, BigDecimal defaultValue) {
+ default BigDecimal getBigDecimal(K key, BigDecimal defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
@@ -104,26 +95,23 @@ public abstract class OptNullBasicTypeFromObjectGetter extends OptNullBasicTy
return Convert.toBigDecimal(obj, defaultValue);
}
- @Override
- public BigInteger getBigInteger(K key, BigInteger defaultValue) {
+ default BigInteger getBigInteger(K key, BigInteger defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
}
return Convert.toBigInteger(obj, defaultValue);
}
-
- @Override
- public > E getEnum(Class clazz, K key, E defaultValue) {
+
+ default > E getEnum(Class clazz, K key, E defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
}
return Convert.toEnum(clazz, obj, defaultValue);
}
-
- @Override
- public Date getDate(K key, Date defaultValue) {
+
+ default Date getDate(K key, Date defaultValue) {
final Object obj = getObj(key);
if(null == obj) {
return defaultValue;
diff --git a/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromStringGetter.java b/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromStringGetter.java
index 13e6eecd4..c0562ec24 100644
--- a/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromStringGetter.java
+++ b/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeFromStringGetter.java
@@ -12,70 +12,57 @@ import cn.hutool.core.convert.Convert;
*
* @author Looly
*/
-public abstract class OptNullBasicTypeFromStringGetter extends OptNullBasicTypeGetter {
+public interface OptNullBasicTypeFromStringGetter extends OptNullBasicTypeGetter {
- @Override
- public Object getObj(K key, Object defaultValue) {
+ default Object getObj(K key, Object defaultValue) {
return getStr(key, null == defaultValue ? null : defaultValue.toString());
}
- @Override
- public Integer getInt(K key, Integer defaultValue) {
+ default Integer getInt(K key, Integer defaultValue) {
return Convert.toInt(getStr(key), defaultValue);
}
- @Override
- public Short getShort(K key, Short defaultValue) {
+ default Short getShort(K key, Short defaultValue) {
return Convert.toShort(getStr(key), defaultValue);
}
- @Override
- public Boolean getBool(K key, Boolean defaultValue) {
+ default Boolean getBool(K key, Boolean defaultValue) {
return Convert.toBool(getStr(key), defaultValue);
}
- @Override
- public Long getLong(K key, Long defaultValue) {
+ default Long getLong(K key, Long defaultValue) {
return Convert.toLong(getStr(key), defaultValue);
}
- @Override
- public Character getChar(K key, Character defaultValue) {
+ default Character getChar(K key, Character defaultValue) {
return Convert.toChar(getStr(key), defaultValue);
}
- @Override
- public Float getFloat(K key, Float defaultValue) {
+ default Float getFloat(K key, Float defaultValue) {
return Convert.toFloat(getStr(key), defaultValue);
}
- @Override
- public Double getDouble(K key, Double defaultValue) {
+ default Double getDouble(K key, Double defaultValue) {
return Convert.toDouble(getStr(key), defaultValue);
}
- @Override
- public Byte getByte(K key, Byte defaultValue) {
+ default Byte getByte(K key, Byte defaultValue) {
return Convert.toByte(getStr(key), defaultValue);
}
- @Override
- public BigDecimal getBigDecimal(K key, BigDecimal defaultValue) {
+ default BigDecimal getBigDecimal(K key, BigDecimal defaultValue) {
return Convert.toBigDecimal(getStr(key), defaultValue);
}
- @Override
- public BigInteger getBigInteger(K key, BigInteger defaultValue) {
+ default BigInteger getBigInteger(K key, BigInteger defaultValue) {
return Convert.toBigInteger(getStr(key), defaultValue);
}
- @Override
- public > E getEnum(Class clazz, K key, E defaultValue) {
+ default > E getEnum(Class clazz, K key, E defaultValue) {
return Convert.toEnum(clazz, getStr(key), defaultValue);
}
- @Override
- public Date getDate(K key, Date defaultValue) {
+ default Date getDate(K key, Date defaultValue) {
return Convert.toDate(getStr(key), defaultValue);
}
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeGetter.java b/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeGetter.java
index 45b40f6a6..df992aa34 100644
--- a/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeGetter.java
+++ b/hutool-core/src/main/java/cn/hutool/core/getter/OptNullBasicTypeGetter.java
@@ -8,13 +8,12 @@ import java.util.Date;
* 基本类型的getter接口抽象实现
* 提供一个统一的接口定义返回不同类型的值(基本类型)
* 在不提供默认值的情况下, 如果值不存在或获取错误,返回null
- * 用户只需实现{@code com.xiaoleilu.hutool.getter.OptBasicTypeGetter}接口即可
+ * 用户只需实现{@link OptBasicTypeGetter}接口即可
* @author Looly
*/
-public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, OptBasicTypeGetter{
+public interface OptNullBasicTypeGetter extends BasicTypeGetter, OptBasicTypeGetter{
- @Override
- public Object getObj(K key) {
+ default Object getObj(K key) {
return getObj(key, null);
}
@@ -25,8 +24,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public String getStr(K key){
+ default String getStr(K key){
return this.getStr(key, null);
}
@@ -37,8 +35,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Integer getInt(K key) {
+ default Integer getInt(K key) {
return this.getInt(key, null);
}
@@ -49,8 +46,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Short getShort(K key){
+ default Short getShort(K key){
return this.getShort(key, null);
}
@@ -61,8 +57,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Boolean getBool(K key){
+ default Boolean getBool(K key){
return this.getBool(key, null);
}
@@ -73,8 +68,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Long getLong(K key){
+ default Long getLong(K key){
return this.getLong(key, null);
}
@@ -85,8 +79,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Character getChar(K key){
+ default Character getChar(K key){
return this.getChar(key, null);
}
@@ -97,8 +90,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Float getFloat(K key){
+ default Float getFloat(K key){
return this.getFloat(key, null);
}
@@ -109,11 +101,10 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Double getDouble(K key){
+ default Double getDouble(K key){
return this.getDouble(key, null);
}
-
+
/**
* 获取byte型属性值
* 无值或获取错误返回null
@@ -121,8 +112,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Byte getByte(K key){
+ default Byte getByte(K key){
return this.getByte(key, null);
}
@@ -133,8 +123,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public BigDecimal getBigDecimal(K key){
+ default BigDecimal getBigDecimal(K key){
return this.getBigDecimal(key, null);
}
@@ -145,8 +134,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public BigInteger getBigInteger(K key){
+ default BigInteger getBigInteger(K key){
return this.getBigInteger(key, null);
}
@@ -158,8 +146,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public > E getEnum(Class clazz, K key) {
+ default > E getEnum(Class clazz, K key) {
return this.getEnum(clazz, key, null);
}
@@ -170,8 +157,7 @@ public abstract class OptNullBasicTypeGetter implements BasicTypeGetter, O
* @param key 属性名
* @return 属性值
*/
- @Override
- public Date getDate(K key) {
+ default Date getDate(K key) {
return this.getDate(key, null);
}
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/img/Img.java b/hutool-core/src/main/java/cn/hutool/core/img/Img.java
index eefd84636..9058c533f 100644
--- a/hutool-core/src/main/java/cn/hutool/core/img/Img.java
+++ b/hutool-core/src/main/java/cn/hutool/core/img/Img.java
@@ -53,7 +53,7 @@ public class Img implements Serializable {
/**
* 目标图片文件格式,用于写出
*/
- private String targetImageType = ImgUtil.IMAGE_TYPE_JPG;
+ private String targetImageType;
/**
* 计算x,y坐标的时候是否从中心做为原始坐标开始计算
*/
@@ -140,7 +140,22 @@ public class Img implements Serializable {
* @param srcImage 来源图片
*/
public Img(BufferedImage srcImage) {
+ this(srcImage, null);
+ }
+
+ /**
+ * 构造
+ *
+ * @param srcImage 来源图片
+ * @param targetImageType 目标图片类型
+ * @since 5.0.7
+ */
+ public Img(BufferedImage srcImage, String targetImageType) {
this.srcImage = srcImage;
+ if(null == targetImageType){
+ targetImageType = ImgUtil.IMAGE_TYPE_JPG;
+ }
+ this.targetImageType = targetImageType;
}
/**
@@ -294,15 +309,14 @@ public class Img implements Serializable {
srcHeight = srcImage.getHeight(null);
srcWidth = srcImage.getWidth(null);
- if (null == fixedColor) {// 补白
- fixedColor = Color.WHITE;
- }
final BufferedImage image = new BufferedImage(width, height, getTypeInt());
Graphics2D g = image.createGraphics();
// 设置背景
- g.setBackground(fixedColor);
- g.clearRect(0, 0, width, height);
+ if(null != fixedColor){
+ g.setBackground(fixedColor);
+ g.clearRect(0, 0, width, height);
+ }
// 在中间贴图
g.drawImage(srcImage, (width - srcWidth) / 2, (height - srcHeight) / 2, srcWidth, srcHeight, fixedColor, null);
@@ -586,6 +600,7 @@ public class Img implements Serializable {
}
if (targetFile.exists()) {
+ //noinspection ResultOfMethodCallIgnored
targetFile.delete();
}
@@ -624,6 +639,7 @@ public class Img implements Serializable {
* @see BufferedImage#TYPE_INT_RGB
*/
private int getTypeInt() {
+ //noinspection SwitchStatementWithTooFewBranches
switch (this.targetImageType) {
case ImgUtil.IMAGE_TYPE_PNG:
return BufferedImage.TYPE_INT_ARGB;
@@ -678,6 +694,7 @@ public class Img implements Serializable {
if (degree >= 90) {
if (degree / 90 % 2 == 1) {
int temp = height;
+ //noinspection SuspiciousNameCombination
height = width;
width = temp;
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java b/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java
index 58980cc27..492ab2cc0 100644
--- a/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java
@@ -171,17 +171,20 @@ public class ImgUtil {
/**
* 缩放图像(按高度和宽度缩放)
- * 缩放后默认为jpeg格式
+ * 缩放后默认格式与源图片相同,无法识别原图片默认JPG
*
* @param srcImageFile 源图像文件地址
* @param destImageFile 缩放后的图像地址
* @param width 缩放后的宽度
* @param height 缩放后的高度
- * @param fixedColor 比例不对时补充的颜色,不补充为null
+ * @param fixedColor 补充的颜色,不补充为null
* @throws IORuntimeException IO异常
*/
public static void scale(File srcImageFile, File destImageFile, int width, int height, Color fixedColor) throws IORuntimeException {
- write(scale(read(srcImageFile), width, height, fixedColor), destImageFile);
+ Img.from(srcImageFile)//
+ .setTargetImageType(FileUtil.extName(destImageFile))//
+ .scale(width, height, fixedColor)//
+ .write(destImageFile);
}
/**
@@ -397,12 +400,12 @@ public class ImgUtil {
if (srcWidth % destWidth == 0) {
cols = srcWidth / destWidth;
} else {
- cols = (int) Math.floor(srcWidth / destWidth) + 1;
+ cols = (int) Math.floor((double)srcWidth / destWidth) + 1;
}
if (srcHeight % destHeight == 0) {
rows = srcHeight / destHeight;
} else {
- rows = (int) Math.floor(srcHeight / destHeight) + 1;
+ rows = (int) Math.floor((double)srcHeight / destHeight) + 1;
}
// 循环建立切片
Image tag;
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java
index 47f0e00b3..a9b77f6c3 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseLinkedMap.java
@@ -60,7 +60,7 @@ public class CamelCaseLinkedMap extends CamelCaseMap {
* @param loadFactor 加载因子
*/
public CamelCaseLinkedMap(int initialCapacity, float loadFactor) {
- super(new HashMap(initialCapacity, loadFactor));
+ super(new HashMap<>(initialCapacity, loadFactor));
}
// ------------------------------------------------------------------------- Constructor end
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java
index 8dc8d4faf..0da049ec0 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CamelCaseMap.java
@@ -62,7 +62,7 @@ public class CamelCaseMap extends CustomKeyMap {
* @param loadFactor 加载因子
*/
public CamelCaseMap(int initialCapacity, float loadFactor) {
- super(new HashMap(initialCapacity, loadFactor));
+ super(new HashMap<>(initialCapacity, loadFactor));
}
// ------------------------------------------------------------------------- Constructor end
@@ -74,7 +74,7 @@ public class CamelCaseMap extends CustomKeyMap {
*/
@Override
protected Object customKey(Object key) {
- if (null != key && key instanceof CharSequence) {
+ if (key instanceof CharSequence) {
key = StrUtil.toCamelCase(key.toString());
}
return key;
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java
index 8bc486ee2..5fe5d503a 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/CaseInsensitiveLinkedMap.java
@@ -61,7 +61,7 @@ public class CaseInsensitiveLinkedMap extends CaseInsensitiveMap {
* @param loadFactor 加载因子
*/
public CaseInsensitiveLinkedMap(int initialCapacity, float loadFactor) {
- super(new LinkedHashMap(initialCapacity, loadFactor));
+ super(new LinkedHashMap<>(initialCapacity, loadFactor));
}
// ------------------------------------------------------------------------- Constructor end
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/MapProxy.java b/hutool-core/src/main/java/cn/hutool/core/map/MapProxy.java
index 7865e2ad1..2d9875605 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/MapProxy.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/MapProxy.java
@@ -21,7 +21,7 @@ import cn.hutool.core.util.StrUtil;
* @author looly
* @since 3.2.0
*/
-public class MapProxy extends OptNullBasicTypeFromObjectGetter