diff --git a/CHANGELOG.md b/CHANGELOG.md index b3ae47dc0..69f7084dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.4.5 (2020-10-16) +# 5.4.5 (2020-10-17) ### 新特性 * 【core 】 ConsoleTable代码优化(pr#190@Gitee) @@ -20,6 +20,8 @@ * 【core 】 优化针对list的split方法(pr#194@Gitee) * 【poi 】 ExcelWriter增加setRowStyle方法 * 【core 】 Assert增加函数接口(pr#1166@Github) +* 【core 】 新增AtomicIntegerArray、AtomicLongArray转换 +* 【extra 】 PinyinUtil新增Bopomofo4j支持 ### Bug修复 * 【core 】 解决农历判断节日未判断大小月导致的问题(issue#I1XHSF@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java index 3fa034c86..fe1c55143 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java @@ -3,6 +3,8 @@ package cn.hutool.core.convert; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.convert.impl.ArrayConverter; import cn.hutool.core.convert.impl.AtomicBooleanConverter; +import cn.hutool.core.convert.impl.AtomicIntegerArrayConverter; +import cn.hutool.core.convert.impl.AtomicLongArrayConverter; import cn.hutool.core.convert.impl.AtomicReferenceConverter; import cn.hutool.core.convert.impl.BeanConverter; import cn.hutool.core.convert.impl.BooleanConverter; @@ -69,7 +71,9 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerArray; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongArray; import java.util.concurrent.atomic.AtomicReference; /** @@ -423,6 +427,10 @@ public class ConverterRegistry implements Serializable { defaultConverterMap.put(SoftReference.class, new ReferenceConverter(SoftReference.class));// since 3.0.8 defaultConverterMap.put(AtomicReference.class, new AtomicReferenceConverter());// since 3.0.8 + //AtomicXXXArray,since 5.4.5 + defaultConverterMap.put(AtomicIntegerArray.class, new AtomicIntegerArrayConverter()); + defaultConverterMap.put(AtomicLongArray.class, new AtomicLongArrayConverter()); + // 其它类型 defaultConverterMap.put(Class.class, new ClassConverter()); defaultConverterMap.put(TimeZone.class, new TimeZoneConverter()); diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicIntegerArrayConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicIntegerArrayConverter.java new file mode 100644 index 000000000..81b9b6c7e --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicIntegerArrayConverter.java @@ -0,0 +1,22 @@ +package cn.hutool.core.convert.impl; + +import cn.hutool.core.convert.AbstractConverter; +import cn.hutool.core.convert.Convert; + +import java.util.concurrent.atomic.AtomicIntegerArray; + +/** + * {@link AtomicIntegerArray}转换器 + * + * @author Looly + * @since 5.4.5 + */ +public class AtomicIntegerArrayConverter extends AbstractConverter { + private static final long serialVersionUID = 1L; + + @Override + protected AtomicIntegerArray convertInternal(Object value) { + return new AtomicIntegerArray(Convert.convert(int[].class, value)); + } + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicLongArrayConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicLongArrayConverter.java new file mode 100644 index 000000000..1b0d170fc --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicLongArrayConverter.java @@ -0,0 +1,22 @@ +package cn.hutool.core.convert.impl; + +import cn.hutool.core.convert.AbstractConverter; +import cn.hutool.core.convert.Convert; + +import java.util.concurrent.atomic.AtomicLongArray; + +/** + * {@link AtomicLongArray}转换器 + * + * @author Looly + * @since 5.4.5 + */ +public class AtomicLongArrayConverter extends AbstractConverter { + private static final long serialVersionUID = 1L; + + @Override + protected AtomicLongArray convertInternal(Object value) { + return new AtomicLongArray(Convert.convert(long[].class, value)); + } + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/NumberConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/NumberConverter.java index 3054e76a8..1f366f4ad 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/NumberConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/NumberConverter.java @@ -13,6 +13,8 @@ import java.util.Calendar; import java.util.Date; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.DoubleAdder; +import java.util.concurrent.atomic.LongAdder; /** * 数字转换器
@@ -64,7 +66,6 @@ public class NumberConverter extends AbstractConverter { } final String valueStr = convertToStr(value); return StrUtil.isBlank(valueStr) ? null : Byte.valueOf(valueStr); - } else if (Short.class == targetType) { if (value instanceof Number) { return ((Number) value).shortValue(); @@ -73,7 +74,6 @@ public class NumberConverter extends AbstractConverter { } final String valueStr = convertToStr(value); return StrUtil.isBlank(valueStr) ? null : Short.valueOf(valueStr); - } else if (Integer.class == targetType) { if (value instanceof Number) { return ((Number) value).intValue(); @@ -88,7 +88,6 @@ public class NumberConverter extends AbstractConverter { } final String valueStr = convertToStr(value); return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseInt(valueStr); - } else if (AtomicInteger.class == targetType) { final Number number = convertInternal(value, Integer.class); if (null != number) { @@ -96,7 +95,6 @@ public class NumberConverter extends AbstractConverter { intValue.set(number.intValue()); return intValue; } - return null; } else if (Long.class == targetType) { if (value instanceof Number) { return ((Number) value).longValue(); @@ -111,7 +109,6 @@ public class NumberConverter extends AbstractConverter { } final String valueStr = convertToStr(value); return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseLong(valueStr); - } else if (AtomicLong.class == targetType) { final Number number = convertInternal(value, Long.class); if (null != number) { @@ -119,7 +116,14 @@ public class NumberConverter extends AbstractConverter { longValue.set(number.longValue()); return longValue; } - return null; + }else if (LongAdder.class == targetType) { + //jdk8 新增 + final Number number = convertInternal(value, Long.class); + if (null != number) { + final LongAdder longValue = new LongAdder(); + longValue.add(number.longValue()); + return longValue; + } } else if (Float.class == targetType) { if (value instanceof Number) { return ((Number) value).floatValue(); @@ -137,13 +141,18 @@ public class NumberConverter extends AbstractConverter { } final String valueStr = convertToStr(value); return StrUtil.isBlank(valueStr) ? null : Double.valueOf(valueStr); - + }else if (DoubleAdder.class == targetType) { + //jdk8 新增 + final Number number = convertInternal(value, Long.class); + if (null != number) { + final DoubleAdder doubleAdder = new DoubleAdder(); + doubleAdder.add(number.doubleValue()); + return doubleAdder; + } } else if (BigDecimal.class == targetType) { return toBigDecimal(value); - } else if (BigInteger.class == targetType) { return toBigInteger(value); - } else if (Number.class == targetType) { if (value instanceof Number) { return (Number) value; @@ -166,22 +175,14 @@ public class NumberConverter extends AbstractConverter { * @return 结果 */ private BigDecimal toBigDecimal(Object value) { - if (value instanceof Long) { - return new BigDecimal((Long) value); - } else if (value instanceof Integer) { - return new BigDecimal((Integer) value); - } else if (value instanceof BigInteger) { - return new BigDecimal((BigInteger) value); + if (value instanceof Number) { + return NumberUtil.toBigDecimal((Number) value); } else if (value instanceof Boolean) { return new BigDecimal((boolean) value ? 1 : 0); } //对于Double类型,先要转换为String,避免精度问题 - final String valueStr = convertToStr(value); - if (StrUtil.isBlank(valueStr)) { - return null; - } - return new BigDecimal(valueStr); + return NumberUtil.toBigDecimal(convertToStr(value)); } /** @@ -198,11 +199,8 @@ public class NumberConverter extends AbstractConverter { } else if (value instanceof Boolean) { return BigInteger.valueOf((boolean) value ? 1 : 0); } - final String valueStr = convertToStr(value); - if (StrUtil.isBlank(valueStr)) { - return null; - } - return new BigInteger(valueStr); + + return NumberUtil.toBigInteger(convertToStr(value)); } @Override diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java index f1a49e749..91f2ac830 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java @@ -1,18 +1,77 @@ package cn.hutool.core.convert.impl; import cn.hutool.core.convert.AbstractConverter; +import cn.hutool.core.convert.ConvertException; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.XmlUtil; + +import java.io.InputStream; +import java.io.Reader; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.SQLException; +import java.util.TimeZone; /** - * 字符串转换器 - * @author Looly + * 字符串转换器,提供各种对象转换为字符串的逻辑封装 * + * @author Looly */ -public class StringConverter extends AbstractConverter{ +public class StringConverter extends AbstractConverter { private static final long serialVersionUID = 1L; @Override protected String convertInternal(Object value) { + if (value instanceof TimeZone) { + return ((TimeZone) value).getID(); + } else if (value instanceof org.w3c.dom.Node) { + return XmlUtil.toStr((org.w3c.dom.Node) value); + } else if (value instanceof Clob) { + return clobToStr((Clob) value); + } else if (value instanceof Blob) { + return blobToStr((Blob) value); + } + + // 其它情况 return convertToStr(value); } + /** + * Clob字段值转字符串 + * + * @param clob {@link Clob} + * @return 字符串 + * @since 5.4.5 + */ + private static String clobToStr(Clob clob) { + Reader reader = null; + try { + reader = clob.getCharacterStream(); + return IoUtil.read(reader); + } catch (SQLException e) { + throw new ConvertException(e); + } finally { + IoUtil.close(reader); + } + } + + /** + * Blob字段值转字符串 + * + * @param blob {@link Blob} + * @return 字符串 + * @since 5.4.5 + */ + private static String blobToStr(Blob blob) { + InputStream in = null; + try { + in = blob.getBinaryStream(); + return IoUtil.read(in, CharsetUtil.CHARSET_UTF_8); + } catch (SQLException e) { + throw new ConvertException(e); + } finally { + IoUtil.close(in); + } + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index 737f7347d..9c8395087 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -2005,6 +2005,17 @@ public class NumberUtil { if (null == number) { return BigDecimal.ZERO; } + + if(number instanceof BigDecimal){ + return (BigDecimal) number; + } else if (number instanceof Long) { + return new BigDecimal((Long) number); + } else if (number instanceof Integer) { + return new BigDecimal((Integer) number); + } else if (number instanceof BigInteger) { + return new BigDecimal((BigInteger) number); + } + return toBigDecimal(number.toString()); } @@ -2019,6 +2030,38 @@ public class NumberUtil { return (null == number) ? BigDecimal.ZERO : new BigDecimal(number); } + /** + * 数字转{@link BigInteger} + * + * @param number 数字 + * @return {@link BigInteger} + * @since 5.4.5 + */ + public static BigInteger toBigInteger(Number number) { + if (null == number) { + return BigInteger.ZERO; + } + + if(number instanceof BigInteger){ + return (BigInteger) number; + } else if (number instanceof Long) { + return BigInteger.valueOf((Long) number); + } + + return toBigInteger(number.longValue()); + } + + /** + * 数字转{@link BigInteger} + * + * @param number 数字 + * @return {@link BigInteger} + * @since 5.4.5 + */ + public static BigInteger toBigInteger(String number) { + return (null == number) ? BigInteger.ZERO : new BigInteger(number); + } + /** * 是否空白符
* 空白符包括空格、制表符、全角空格和不间断空格
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java index e7162eb4f..eb0e34ea8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java @@ -345,6 +345,19 @@ public class XmlUtil { // -------------------------------------------------------------------------------------- Write + /** + * 将XML文档转换为String
+ * 字符编码使用XML文档中的编码,获取不到则使用UTF-8
+ * 默认非格式化输出,若想格式化请使用{@link #format(Document)} + * + * @param doc XML文档 + * @return XML字符串 + * @since 5.4.5 + */ + public static String toStr(Node doc) { + return toStr(doc, false); + } + /** * 将XML文档转换为String
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8
@@ -354,7 +367,20 @@ public class XmlUtil { * @return XML字符串 */ public static String toStr(Document doc) { - return toStr(doc, false); + return toStr((Node)doc); + } + + /** + * 将XML文档转换为String
+ * 字符编码使用XML文档中的编码,获取不到则使用UTF-8 + * + * @param doc XML文档 + * @param isPretty 是否格式化输出 + * @return XML字符串 + * @since 5.4.5 + */ + public static String toStr(Node doc, boolean isPretty) { + return toStr(doc, CharsetUtil.UTF_8, isPretty); } /** @@ -367,7 +393,21 @@ public class XmlUtil { * @since 3.0.9 */ public static String toStr(Document doc, boolean isPretty) { - return toStr(doc, CharsetUtil.UTF_8, isPretty); + return toStr((Node)doc, isPretty); + } + + /** + * 将XML文档转换为String
+ * 字符编码使用XML文档中的编码,获取不到则使用UTF-8 + * + * @param doc XML文档 + * @param charset 编码 + * @param isPretty 是否格式化输出 + * @return XML字符串 + * @since 5.4.5 + */ + public static String toStr(Node doc, String charset, boolean isPretty) { + return toStr(doc, charset, isPretty, false); } /** @@ -381,7 +421,7 @@ public class XmlUtil { * @since 3.0.9 */ public static String toStr(Document doc, String charset, boolean isPretty) { - return toStr(doc, charset, isPretty, false); + return toStr((Node)doc, charset, isPretty); } /** @@ -395,7 +435,7 @@ public class XmlUtil { * @return XML字符串 * @since 5.1.2 */ - public static String toStr(Document doc, String charset, boolean isPretty, boolean omitXmlDeclaration) { + public static String toStr(Node doc, String charset, boolean isPretty, boolean omitXmlDeclaration) { final StringWriter writer = StrUtil.getWriter(); try { write(doc, writer, charset, isPretty ? INDENT_DEFAULT : 0, omitXmlDeclaration); diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java index 52d063af0..43d5bd5f6 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java @@ -9,6 +9,8 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.atomic.AtomicIntegerArray; +import java.util.concurrent.atomic.AtomicLongArray; /** * 类型转换工具单元测试 @@ -222,6 +224,20 @@ public class ConvertTest { Assert.assertEquals("5.1.1", product.getVersion()); } + @Test + public void toAtomicIntegerArrayTest(){ + String str = "1,2"; + final AtomicIntegerArray atomicIntegerArray = Convert.convert(AtomicIntegerArray.class, str); + Assert.assertEquals("[1, 2]", atomicIntegerArray.toString()); + } + + @Test + public void toAtomicLongArrayTest(){ + String str = "1,2"; + final AtomicLongArray atomicLongArray = Convert.convert(AtomicLongArray.class, str); + Assert.assertEquals("[1, 2]", atomicLongArray.toString()); + } + @Data @AllArgsConstructor public static class Product implements Serializable { diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/StringConvertTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/StringConvertTest.java new file mode 100644 index 000000000..aeed15190 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/convert/StringConvertTest.java @@ -0,0 +1,15 @@ +package cn.hutool.core.convert; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.TimeZone; + +public class StringConvertTest { + + @Test + public void timezoneToStrTest(){ + final String s = Convert.toStr(TimeZone.getTimeZone("Asia/Shanghai")); + Assert.assertEquals("Asia/Shanghai", s); + } +} diff --git a/hutool-extra/bopomofo4j-temp/bopomofo4j-c6e41074-5302-42b6-9bdf-8742cb416a62.jar b/hutool-extra/bopomofo4j-temp/bopomofo4j-c6e41074-5302-42b6-9bdf-8742cb416a62.jar new file mode 100644 index 000000000..6ae573b55 Binary files /dev/null and b/hutool-extra/bopomofo4j-temp/bopomofo4j-c6e41074-5302-42b6-9bdf-8742cb416a62.jar differ diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index f91f5ac87..6d46f081e 100644 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -233,6 +233,12 @@ 1.1.8 true + + com.rnkrsoft.bopomofo4j + bopomofo4j + 1.0.0 + true + cglib cglib diff --git a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/Bopomofo4jEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/Bopomofo4jEngine.java new file mode 100644 index 000000000..09409cab8 --- /dev/null +++ b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/Bopomofo4jEngine.java @@ -0,0 +1,43 @@ +package cn.hutool.extra.pinyin.engine.bopomofo4j; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.pinyin.PinyinEngine; +import com.rnkrsoft.bopomofo4j.Bopomofo4j; +import com.rnkrsoft.bopomofo4j.ToneType; + +/** + * 封装了Bopomofo4j的引擎。 + * + *

+ * Bopomofo4j封装,项目:https://gitee.com/rnkrsoft/Bopomofo4j。 + *

+ * + *

+ * 引入: + *

+ * <dependency>
+ *     <groupId>com.rnkrsoft.bopomofo4j</groupId>
+ *     <artifactId>bopomofo4j</artifactId>
+ *     <version>1.0.0</version>
+ * </dependency>
+ * 
+ * + * @author looly + * @since 5.4.5 + */ +public class Bopomofo4jEngine implements PinyinEngine { + + public Bopomofo4jEngine(){ + Bopomofo4j.local(); + } + + @Override + public String getPinyin(char c) { + return Bopomofo4j.pinyin(String.valueOf(c), ToneType.WITHOUT_TONE, false, false, StrUtil.EMPTY); + } + + @Override + public String getPinyin(String str, String separator) { + return Bopomofo4j.pinyin(str, ToneType.WITHOUT_TONE, false, false, separator); + } +} diff --git a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/package-info.java new file mode 100644 index 000000000..8e56f1b49 --- /dev/null +++ b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/package-info.java @@ -0,0 +1,20 @@ +/** + * 封装了Bopomofo4j的引擎。 + * + *

+ * Bopomofo4j封装,项目:https://gitee.com/rnkrsoft/Bopomofo4j。 + *

+ * + *

+ * 引入: + *

+ * <dependency>
+ *     <groupId>com.rnkrsoft.bopomofo4j</groupId>
+ *     <artifactId>bopomofo4j</artifactId>
+ *     <version>1.0.0</version>
+ * </dependency>
+ * 
+ * + * @author looly + */ +package cn.hutool.extra.pinyin.engine.bopomofo4j; \ No newline at end of file diff --git a/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine index 5526a0a33..c91f32dd3 100644 --- a/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine +++ b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine @@ -1,3 +1,4 @@ cn.hutool.extra.pinyin.engine.tinypinyin.TinyPinyinEngine cn.hutool.extra.pinyin.engine.jpinyin.JPinyinEngine -cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine \ No newline at end of file +cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine +cn.hutool.extra.pinyin.engine.bopomofo4j.Bopomofo4jEngine \ No newline at end of file diff --git a/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java b/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java index 751fa53ee..a39c8c1db 100644 --- a/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java +++ b/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java @@ -1,5 +1,6 @@ package cn.hutool.extra.pinyin; +import cn.hutool.extra.pinyin.engine.bopomofo4j.Bopomofo4jEngine; import cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine; import org.junit.Assert; import org.junit.Test; @@ -19,6 +20,13 @@ public class PinyinUtilTest { Assert.assertEquals("ni hao h", pinyin); } + @Test + public void getPinyinByBopomofo4jTest() { + final Bopomofo4jEngine engine = new Bopomofo4jEngine(); + final String pinyin = engine.getPinyin("你好h", " "); + Assert.assertEquals("ni haoh", pinyin); + } + @Test public void getPinyinUpperCaseTest(){ final String pinyin = PinyinUtil.getPinyin("你好怡", " "); @@ -37,4 +45,11 @@ public class PinyinUtilTest { final String result = engine.getFirstLetter("林海", ""); Assert.assertEquals("lh", result); } + + @Test + public void getFirstLetterByBopomofo4jTest(){ + final Bopomofo4jEngine engine = new Bopomofo4jEngine(); + final String result = engine.getFirstLetter("林海", ""); + Assert.assertEquals("lh", result); + } } diff --git a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java index c47ac3df6..98e9c3264 100644 --- a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java @@ -2,6 +2,7 @@ package cn.hutool.json; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.TemporalAccessorUtil; import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; @@ -239,6 +240,9 @@ final class InternalJSONUtil { */ private static String formatDate(Object dateObj, String format) { if (StrUtil.isNotBlank(format)) { + if(dateObj instanceof TemporalAccessor){ + return TemporalAccessorUtil.format((TemporalAccessor) dateObj, format); + } //用户定义了日期格式 return JSONUtil.quote(DateUtil.format(Convert.toDate(dateObj), format)); } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java index 0f0117c8a..3c6c15363 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -351,6 +351,18 @@ public class JSONObject implements JSON, JSONGetter, Map @Override @Deprecated public JSONObject put(String key, Object value) throws JSONException { + return set(key, value); + } + + /** + * 设置键值对到JSONObject中,在忽略null模式下,如果值为null,将此键移除 + * + * @param key 键 + * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. + * @return this. + * @throws JSONException 值是无穷数字抛出此异常 + */ + public JSONObject set(String key, Object value) throws JSONException { if (null == key) { return this; } @@ -366,19 +378,6 @@ public class JSONObject implements JSON, JSONGetter, Map return this; } - /** - * 设置键值对到JSONObject中,在忽略null模式下,如果值为null,将此键移除 - * - * @param key 键 - * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. - * @return this. - * @throws JSONException 值是无穷数字抛出此异常 - */ - public JSONObject set(String key, Object value) throws JSONException { - put(key, value); - return this; - } - /** * 一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略 * @@ -392,7 +391,7 @@ public class JSONObject implements JSON, JSONGetter, Map if (rawHashMap.containsKey(key)) { throw new JSONException("Duplicate key \"{}\"", key); } - this.put(key, value); + this.set(key, value); } return this; } @@ -407,7 +406,7 @@ public class JSONObject implements JSON, JSONGetter, Map */ public JSONObject putOpt(String key, Object value) throws JSONException { if (key != null && value != null) { - this.put(key, value); + this.set(key, value); } return this; } @@ -415,7 +414,7 @@ public class JSONObject implements JSON, JSONGetter, Map @Override public void putAll(Map m) { for (Entry entry : m.entrySet()) { - this.put(entry.getKey(), entry.getValue()); + this.set(entry.getKey(), entry.getValue()); } } @@ -432,7 +431,7 @@ public class JSONObject implements JSON, JSONGetter, Map InternalJSONUtil.testValidity(value); Object object = this.getObj(key); if (object == null) { - this.put(key, value instanceof JSONArray ? new JSONArray(this.config).set(value) : value); + this.set(key, value instanceof JSONArray ? new JSONArray(this.config).set(value) : value); } else if (object instanceof JSONArray) { ((JSONArray) object).set(value); } else { @@ -472,19 +471,19 @@ public class JSONObject implements JSON, JSONGetter, Map public JSONObject increment(String key) throws JSONException { Object value = this.getObj(key); if (value == null) { - this.put(key, 1); + this.set(key, 1); } else if (value instanceof BigInteger) { - this.put(key, ((BigInteger) value).add(BigInteger.ONE)); + this.set(key, ((BigInteger) value).add(BigInteger.ONE)); } else if (value instanceof BigDecimal) { - this.put(key, ((BigDecimal) value).add(BigDecimal.ONE)); + this.set(key, ((BigDecimal) value).add(BigDecimal.ONE)); } else if (value instanceof Integer) { - this.put(key, (Integer) value + 1); + this.set(key, (Integer) value + 1); } else if (value instanceof Long) { - this.put(key, (Long) value + 1); + this.set(key, (Long) value + 1); } else if (value instanceof Double) { - this.put(key, (Double) value + 1); + this.set(key, (Double) value + 1); } else if (value instanceof Float) { - this.put(key, (Float) value + 1); + this.set(key, (Float) value + 1); } else { throw new JSONException("Unable to increment [" + JSONUtil.quote(key) + "]."); } @@ -652,8 +651,11 @@ public class JSONObject implements JSON, JSONGetter, Map } else if (source instanceof Map) { // Map for (final Entry e : ((Map) source).entrySet()) { - this.put(Convert.toStr(e.getKey()), e.getValue()); + this.set(Convert.toStr(e.getKey()), e.getValue()); } + }else if (source instanceof Map.Entry) { + final Map.Entry entry = (Map.Entry) source; + this.set(Convert.toStr(entry.getKey()), entry.getValue()); } else if (source instanceof CharSequence) { // 可能为JSON字符串 init((CharSequence) source); diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java index cc5583dad..9f7e8422a 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java @@ -9,6 +9,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.lang.Console; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.test.bean.JSONBean; import cn.hutool.json.test.bean.ResultDto; @@ -27,9 +28,13 @@ import org.junit.Ignore; import org.junit.Test; import java.math.BigDecimal; +import java.sql.Timestamp; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; /** * JSONObject单元测试 @@ -425,6 +430,14 @@ public class JSONObjectTest { Assert.assertEquals("{\"date\":[\"2020-06-05 11:16:11\"],\"bbb\":[\"222\"],\"aaa\":[\"123\"]}", json.toString()); } + @Test + public void getTimestampTest(){ + String timeStr = "1970-01-01 00:00:00"; + final JSONObject jsonObject = JSONUtil.createObj().set("time", timeStr); + final Timestamp time = jsonObject.get("time", Timestamp.class); + Assert.assertEquals("1970-01-01 00:00:00.0", time.toString()); + } + public enum TestEnum { TYPE_A, TYPE_B } @@ -497,4 +510,14 @@ public class JSONObjectTest { return this.fieldToIgnore; } } + + @Test + public void setEntryTest(){ + final HashMap of = MapUtil.of("test", "testValue"); + final Set> entries = of.entrySet(); + final Map.Entry next = entries.iterator().next(); + + final JSONObject jsonObject = JSONUtil.parseObj(next); + Console.log(jsonObject); + } }