This commit is contained in:
Looly 2020-04-11 10:38:07 +08:00
parent 47be0f4f79
commit 73fd3b849f
21 changed files with 128 additions and 122 deletions

View File

@ -21,6 +21,7 @@
* 【core 】 添加BiMap
* 【all 】 cn.hutool.extra.servlet.multipart包迁移到cn.hutool.core.net下
* 【core 】 XmlUtil.mapToXml方法支持集合解析issue#820@Github
* 【json 】 解析Object中对是否为bean单独判断而不是直接解析
### Bug修复
* 【extra 】 修复SpringUtil使用devtools重启报错问题

View File

@ -1,13 +1,13 @@
package cn.hutool.bloomfilter;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.BitSet;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.HashUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.BitSet;
/**
* BloomFilter实现方式2此方式使用BitSet存储<br>
* Hash算法的使用使用固定顺序只需指定个数即可
@ -17,10 +17,10 @@ import cn.hutool.core.util.HashUtil;
public class BitSetBloomFilter implements BloomFilter{
private static final long serialVersionUID = 1L;
private BitSet bitSet;
private int bitSetSize;
private int addedElements;
private int hashFunctionNumber;
private final BitSet bitSet;
private final int bitSetSize;
private final int addedElements;
private final int hashFunctionNumber;
/**
* 构造一个布隆过滤器过滤器的容量为c * n 个bit.

View File

@ -42,6 +42,23 @@ import java.util.Map;
*/
public class BeanUtil {
/**
* 判断是否为可读的Bean对象判定方法是
*
* <pre>
* 1是否存在只有无参数的getXXX方法或者isXXX方法
* 2是否存在public类型的字段
* </pre>
*
* @param clazz 待测试类
* @return 是否为可读的Bean对象
* @see #hasGetter(Class)
* @see #hasPublicField(Class)
*/
public static boolean isReadableBean(Class<?> clazz) {
return hasGetter(clazz) || hasPublicField(clazz);
}
/**
* 判断是否为Bean对象判定方法是
*
@ -53,6 +70,7 @@ public class BeanUtil {
* @param clazz 待测试类
* @return 是否为Bean对象
* @see #hasSetter(Class)
* @see #hasPublicField(Class)
*/
public static boolean isBean(Class<?> clazz) {
return hasSetter(clazz) || hasPublicField(clazz);

View File

@ -351,6 +351,24 @@ public class CollUtil {
return IterUtil.join(iterable.iterator(), conjunction);
}
/**
* conjunction 为分隔符将集合转换为字符串
*
* @param <T> 集合元素类型
* @param iterable {@link Iterable}
* @param conjunction 分隔符
* @param prefix 每个元素添加的前缀null表示不添加
* @param suffix 每个元素添加的后缀null表示不添加
* @return 连接后的字符串
* @since 5.3.0
*/
public static <T> String join(Iterable<T> iterable, CharSequence conjunction, String prefix, String suffix) {
if (null == iterable) {
return null;
}
return IterUtil.join(iterable.iterator(), conjunction, prefix, suffix);
}
/**
* conjunction 为分隔符将集合转换为字符串<br>
* 如果集合元素为数组{@link Iterable}{@link Iterator}则递归组合其为字符串

View File

@ -302,7 +302,9 @@ public class IterUtil {
* @param suffix 每个元素添加的后缀null表示不添加
* @return 连接后的字符串
* @since 4.0.10
* @deprecated 如果对象同时实现Iterable和Iterator接口会产生歧义请使用CollUtil.join
*/
@Deprecated
public static <T> String join(Iterable<T> iterable, CharSequence conjunction, String prefix, String suffix) {
if (null == iterable) {
return null;

View File

@ -19,16 +19,16 @@ public class ChineseDate {
private static final Date baseDate = DateUtil.parseDate("1900-01-31");
//农历年
private int year;
private final int year;
//农历月
private int month;
private final int month;
//农历日
private int day;
private final int day;
//是否闰年
private boolean leap;
private String[] chineseNumber = {"", "", "", "", "", "", "", "", "", "", "十一", "十二"};
private String[] chineseNumberName = {"", "", "", "", "", "", "", "", "", "", "十一", ""};
private long[] lunarInfo = new long[]{0x04bd8, 0x04ae0, 0x0a570,
private final String[] chineseNumber = {"", "", "", "", "", "", "", "", "", "", "十一", "十二"};
private final String[] chineseNumberName = {"", "", "", "", "", "", "", "", "", "", "十一", ""};
private final long[] lunarInfo = new long[]{0x04bd8, 0x04ae0, 0x0a570,
0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0,
0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50,
@ -51,7 +51,7 @@ public class ChineseDate {
0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2,
0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0};
//农历节日 *表示放假日
private String[] lFtv = new String[]{
private final String[] lFtv = new String[]{
"0101 春节", "0102 大年初二", "0103 大年初三", "0104 大年初四",
"0105 大年初五", "0106 大年初六", "0107 大年初七", "0105 路神生日",
"0115 元宵节", "0202 龙抬头", "0219 观世音圣诞", "0404 寒食节",

View File

@ -1,11 +1,11 @@
package cn.hutool.core.io;
import cn.hutool.core.util.CharsetUtil;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import cn.hutool.core.util.CharsetUtil;
/**
* 基于快速缓冲FastByteBuffer的OutputStream随着数据的增长自动扩充缓冲区
* <p>
@ -34,7 +34,6 @@ public class FastByteArrayOutputStream extends OutputStream {
buffer = new FastByteBuffer(size);
}
@SuppressWarnings("NullableProblems")
@Override
public void write(byte[] b, int off, int len) {
buffer.append(b, off, len);

View File

@ -2402,7 +2402,7 @@ public class ArrayUtil {
if (ArrayUtil.isArray(item)) {
sb.append(join(ArrayUtil.wrap(item), conjunction, prefix, suffix));
} else if (item instanceof Iterable<?>) {
sb.append(IterUtil.join((Iterable<?>) item, conjunction, prefix, suffix));
sb.append(CollUtil.join((Iterable<?>) item, conjunction, prefix, suffix));
} else if (item instanceof Iterator<?>) {
sb.append(IterUtil.join((Iterator<?>) item, conjunction, prefix, suffix));
} else {

View File

@ -938,7 +938,6 @@ public class ZipUtil {
addDir(subPath, out);
}
// 压缩目录下的子文件或目录
//noinspection ConstantConditions
for (File childFile : files) {
zip(childFile, srcRootDir, out, filter);
}

View File

@ -1,5 +1,7 @@
package cn.hutool.core.clone;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.junit.Assert;
import org.junit.Test;
@ -17,7 +19,10 @@ public class CloneTest {
Cat cat = new Cat();
Cat cat2 = cat.clone();
Assert.assertEquals(cat, cat2);
}
@Test
public void cloneTest2(){
//继承CloneSupport类
Dog dog = new Dog();
Dog dog2 = dog.clone();
@ -30,7 +35,8 @@ public class CloneTest {
* @author Looly
*
*/
private static class Cat implements Cloneable<Cat>{
@Data
static class Cat implements Cloneable<Cat>{
private String name = "miaomiao";
private int age = 2;
@ -42,35 +48,6 @@ public class CloneTest {
throw new CloneRuntimeException(e);
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Cat other = (Cat) obj;
if (age != other.age) {
return false;
}
if (name == null) {
return other.name == null;
} else return name.equals(other.name);
}
}
/**
@ -78,37 +55,10 @@ public class CloneTest {
* @author Looly
*
*/
private static class Dog extends CloneSupport<Dog>{
@EqualsAndHashCode(callSuper = false)
@Data
static class Dog extends CloneSupport<Dog>{
private String name = "wangwang";
private int age = 3;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Dog other = (Dog) obj;
if (age != other.age) {
return false;
}
if (name == null) {
return other.name == null;
} else return name.equals(other.name);
}
}
}

View File

@ -179,6 +179,7 @@ public class CollUtilTest {
map.put("c", "3");
final String[] result = new String[1];
//noinspection deprecation
CollUtil.forEach(map, (key, value, index) -> {
if (key.equals("a")) {
result[0] = value;

View File

@ -16,25 +16,25 @@ public class IterUtilTest {
@Test
public void fieldValueMapTest() {
ArrayList<Car> carList = CollUtil.newArrayList(new Car("123", "大众"), new Car("345", "奔驰"), new Car("567", "路虎"));
Map<String, Car> carNameMap = IterUtil.fieldValueMap(carList, "carNumber");
Map<String, Car> carNameMap = IterUtil.fieldValueMap(carList.iterator(), "carNumber");
Assert.assertEquals("大众", carNameMap.get("123").getCarName());
Assert.assertEquals("奔驰", carNameMap.get("345").getCarName());
Assert.assertEquals("路虎", carNameMap.get("567").getCarName());
}
@Test
public void joinTest() {
ArrayList<String> list = CollUtil.newArrayList("1", "2", "3", "4");
String join = IterUtil.join(list, ":");
String join = IterUtil.join(list.iterator(), ":");
Assert.assertEquals("1:2:3:4", join);
ArrayList<Integer> list1 = CollUtil.newArrayList(1, 2, 3, 4);
String join1 = IterUtil.join(list1, ":");
String join1 = IterUtil.join(list1.iterator(), ":");
Assert.assertEquals("1:2:3:4", join1);
ArrayList<String> list2 = CollUtil.newArrayList("1", "2", "3", "4");
String join2 = IterUtil.join(list2, ":", "\"", "\"");
String join2 = IterUtil.join(list2.iterator(), ":", "\"", "\"");
Assert.assertEquals("\"1\":\"2\":\"3\":\"4\"", join2);
}

View File

@ -3,16 +3,14 @@ package cn.hutool.core.convert;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.convert.NumberWordFormater;
public class NumberWordFormatTest {
@Test
public void formatTest() {
String format = NumberWordFormater.format(100.23);
String format = NumberWordFormatter.format(100.23);
Assert.assertEquals("ONE HUNDRED AND CENTS TWENTY THREE ONLY", format);
String format2 = NumberWordFormater.format("2100.00");
String format2 = NumberWordFormatter.format("2100.00");
Assert.assertEquals("TWO THOUSAND ONE HUNDRED AND CENTS ONLY", format2);
}
}

View File

@ -1,11 +1,5 @@
package cn.hutool.db.ds;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.resource.NoResourceException;
import cn.hutool.core.lang.Assert;
@ -15,6 +9,11 @@ import cn.hutool.db.DbUtil;
import cn.hutool.db.dialect.DriverUtil;
import cn.hutool.setting.Setting;
import javax.sql.DataSource;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 抽象数据源工厂<br>
* 此工厂抽象类用于实现数据源的缓存当用户多次调用{@link #getDataSource(String)} 工厂只需创建一次即可<br>
@ -32,9 +31,9 @@ public abstract class AbstractDSFactory extends DSFactory {
private static final String DEFAULT_DB_SETTING_PATH2 = "db.setting";
/** 数据库连接配置文件 */
private Setting setting;
private final Setting setting;
/** 数据源池 */
private Map<String, DataSourceWrapper> dsMap;
private final Map<String, DataSourceWrapper> dsMap;
/**
* 构造

View File

@ -144,7 +144,7 @@ public class MetaUtil {
}
}
}
return columnNames.toArray(new String[columnNames.size()]);
return columnNames.toArray(new String[0]);
} catch (Exception e) {
throw new DbRuntimeException("Get columns error!", e);
} finally {
@ -172,7 +172,6 @@ public class MetaUtil {
* @param tableName 表名
* @return Table对象
*/
@SuppressWarnings("resource")
public static Table getTableMeta(DataSource ds, String tableName) {
final Table table = Table.create(tableName);
Connection conn = null;

View File

@ -1,7 +1,7 @@
package cn.hutool.extra.template;
import java.io.IOException;
import cn.hutool.core.lang.Dict;
import cn.hutool.extra.template.engine.beetl.BeetlUtil;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
@ -9,8 +9,7 @@ import org.beetl.core.resource.StringTemplateResourceLoader;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.lang.Dict;
import cn.hutool.extra.template.engine.beetl.BeetlUtil;
import java.io.IOException;
/**
* BeetlUtil单元测试
@ -18,6 +17,7 @@ import cn.hutool.extra.template.engine.beetl.BeetlUtil;
* @author looly
*
*/
@SuppressWarnings("deprecation")
public class BeetlUtilTest {
@Test

View File

@ -14,13 +14,14 @@ import org.junit.Test;
* @author looly
*
*/
@SuppressWarnings("ConstantConditions")
public class RestTest {
@Test
public void contentTypeTest() {
HttpRequest request = HttpRequest.post("http://localhost:8090/rest/restTest/")//
.body(JSONUtil.createObj().put("aaa", "aaaValue").put("键2", "值2").toString());
.body(JSONUtil.createObj()
.set("aaa", "aaaValue")
.set("键2", "值2").toString());
Assert.assertEquals("application/json;charset=UTF-8", request.header("Content-Type"));
}
@ -28,7 +29,9 @@ public class RestTest {
@Ignore
public void postTest() {
HttpRequest request = HttpRequest.post("http://localhost:8090/rest/restTest/")//
.body(JSONUtil.createObj().put("aaa", "aaaValue").put("键2", "值2").toString());
.body(JSONUtil.createObj()
.set("aaa", "aaaValue")
.set("键2", "值2").toString());
Console.log(request.execute().body());
}
@ -36,7 +39,8 @@ public class RestTest {
@Ignore
public void postTest2() {
String result = HttpUtil.post("http://localhost:8090/rest/restTest/", JSONUtil.createObj()//
.put("aaa", "aaaValue").put("键2", "值2").toString());
.set("aaa", "aaaValue")
.set("键2", "值2").toString());
Console.log(result);
}
@ -44,7 +48,9 @@ public class RestTest {
@Ignore
public void postTest3() {
HttpRequest request = HttpRequest.post("http://211.162.39.204:8181/jeesite-simple/a/open/bizGwbnService/test")//
.body(JSONUtil.createObj().put("aaa", "aaaValue").put("键2", "值2").toString());
.body(JSONUtil.createObj()
.set("aaa", "aaaValue")
.set("键2", "值2").toString());
Console.log(request.execute().body());
}
}

View File

@ -3,6 +3,7 @@ package cn.hutool.json;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.collection.ArrayIter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@ -41,7 +42,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
/** 持有原始数据的List */
private final List<Object> rawList;
/** 配置项 */
private JSONConfig config;
private final JSONConfig config;
// -------------------------------------------------------------------------------------------------------------------- Constructor start
/**
@ -365,14 +366,13 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
return rawList.contains(o);
}
@SuppressWarnings("NullableProblems")
@Override
public Object[] toArray() {
return rawList.toArray();
}
@Override
@SuppressWarnings({"unchecked", "NullableProblems"})
@SuppressWarnings({"unchecked"})
public <T> T[] toArray(T[] a) {
return (T[]) JSONConverter.toArray(this, a.getClass().getComponentType());
}
@ -600,7 +600,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
init((JSONTokener) source);
} else {
Iterator<?> iter;
if (source.getClass().isArray()) {// 数组
if (ArrayUtil.isArray(source)) {// 数组
iter = new ArrayIter<>(source);
} else if (source instanceof Iterator<?>) {// Iterator
iter = ((Iterator<?>) source);

View File

@ -46,7 +46,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/** JSON的KV持有Map */
private final Map<String, Object> rawHashMap;
/** 配置项 */
private JSONConfig config;
private final JSONConfig config;
// -------------------------------------------------------------------------------------------------------------------- Constructor start
/**
@ -677,9 +677,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
} else if (source instanceof JSONTokener) {
// JSONTokener
init((JSONTokener) source);
} else if (source instanceof Number) {
// ignore Number
} else {
} else if(BeanUtil.isReadableBean(source.getClass())){
// 普通Bean
this.populateMap(source);
}

View File

@ -11,7 +11,7 @@ public class CustomSerializeTest {
@Test
public void serializeTest() {
JSONUtil.putSerializer(CustomBean.class, (JSONObjectSerializer<CustomBean>) (json, bean) -> json.put("customName", bean.name));
JSONUtil.putSerializer(CustomBean.class, (JSONObjectSerializer<CustomBean>) (json, bean) -> json.set("customName", bean.name));
CustomBean customBean = new CustomBean();
customBean.name = "testName";

View File

@ -25,6 +25,24 @@ public class JSONUtilTest {
Console.log(jsonArray);
}
/**
* 数字解析为JSONArray报错
*/
@Test(expected = JSONException.class)
public void parseNumberTest(){
JSONArray json = JSONUtil.parseArray(123L);
Console.log(json);
}
/**
* 数字解析为JSONObject忽略
*/
@Test
public void parseNumberTest2(){
JSONObject json = JSONUtil.parseObj(123L);
Assert.assertEquals(new JSONObject(), json);
}
@Test
public void toJsonStrTest() {
UserA a1 = new UserA();
@ -67,9 +85,9 @@ public class JSONUtilTest {
public void toJsonStrTest3() {
// 验证某个字段为JSON字符串时转义是否规范
JSONObject object = new JSONObject(true);
object.put("name", "123123");
object.put("value", "\\");
object.put("value2", "</");
object.set("name", "123123");
object.set("value", "\\");
object.set("value2", "</");
HashMap<String, String> map = MapUtil.newHashMap();
map.put("user", object.toString());