This commit is contained in:
Looly
2022-02-13 22:51:58 +08:00
parent 0189de2dad
commit 0344982767
9 changed files with 172 additions and 8 deletions

View File

@@ -1,6 +1,9 @@
package cn.hutool.json;
import cn.hutool.core.comparator.CompareUtil;
import java.io.Serializable;
import java.util.Comparator;
/**
* JSON配置项
@@ -15,6 +18,10 @@ public class JSONConfig implements Serializable {
* 是否有序顺序按照加入顺序排序只针对JSONObject有效
*/
private boolean order;
/**
* 键排序规则,{@code null}表示不排序,不排序情况下,如果{@link #order}为{@code true}按照加入顺序排序否则按照hash排序
*/
private Comparator<String> keyComparator;
/**
* 是否忽略转换过程中的异常
*/
@@ -70,6 +77,40 @@ public class JSONConfig implements Serializable {
return this;
}
/**
* 获取键排序规则<br>
* 键排序规则,{@code null}表示不排序,不排序情况下,如果{@link #order}为{@code true}按照加入顺序排序否则按照hash排序
*
* @return 键排序规则
* @since 5.7.21
*/
public Comparator<String> getKeyComparator() {
return this.keyComparator;
}
/**
* 设置自然排序,即按照字母顺序排序
*
* @return this
* @since 5.7.21
*/
public JSONConfig setNatureKeyComparator() {
return setKeyComparator(CompareUtil.naturalComparator());
}
/**
* 设置键排序规则<br>
* 键排序规则,{@code null}表示不排序,不排序情况下,如果{@link #order}为{@code true}按照加入顺序排序否则按照hash排序
*
* @param keyComparator 键排序规则
* @return this
* @since 5.7.21
*/
public JSONConfig setKeyComparator(Comparator<String> keyComparator) {
this.keyComparator = keyComparator;
return this;
}
/**
* 是否忽略转换过程中的异常
*

View File

@@ -10,6 +10,7 @@ import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.mutable.MutablePair;
import cn.hutool.core.map.CaseInsensitiveLinkedMap;
import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.map.CaseInsensitiveTreeMap;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -25,10 +26,12 @@ import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeMap;
/**
* JSON对象<br>
@@ -121,9 +124,21 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
config = JSONConfig.create();
}
if (config.isIgnoreCase()) {
this.rawHashMap = config.isOrder() ? new CaseInsensitiveLinkedMap<>(capacity) : new CaseInsensitiveMap<>(capacity);
final Comparator<String> keyComparator = config.getKeyComparator();
if(null != keyComparator){
// 比较器存在情况下isOrder无效
this.rawHashMap = new CaseInsensitiveTreeMap<>(keyComparator);
}else{
this.rawHashMap = config.isOrder() ? new CaseInsensitiveLinkedMap<>(capacity) : new CaseInsensitiveMap<>(capacity);
}
} else {
this.rawHashMap = MapUtil.newHashMap(capacity, config.isOrder());
final Comparator<String> keyComparator = config.getKeyComparator();
if(null != keyComparator){
// 比较器存在情况下isOrder无效
this.rawHashMap = new TreeMap<>(keyComparator);
}else{
this.rawHashMap = MapUtil.newHashMap(capacity, config.isOrder());
}
}
this.config = config;
}
@@ -178,7 +193,8 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
public JSONObject(Object source, boolean ignoreNullValue, boolean isOrder) {
this(source, JSONConfig.create().setOrder(isOrder)//
.setIgnoreCase((source instanceof CaseInsensitiveMap))//
.setIgnoreNullValue(ignoreNullValue));
.setIgnoreNullValue(ignoreNullValue)
);
}
/**

View File

@@ -0,0 +1,18 @@
package cn.hutool.json;
import org.junit.Assert;
import org.junit.Test;
/**
* https://gitee.com/dromara/hutool/issues/I4RBZ4
*/
public class IssueI4RBZ4Test {
@Test
public void sortTest(){
String jsonStr = "{\"id\":\"123\",\"array\":[1,2,3],\"outNum\":356,\"body\":{\"ava1\":\"20220108\",\"use\":1,\"ava2\":\"20230108\"},\"name\":\"John\"}";
final JSONObject jsonObject = JSONUtil.parseObj(jsonStr, JSONConfig.create().setNatureKeyComparator());
Assert.assertEquals("{\"array\":[1,2,3],\"body\":{\"ava1\":\"20220108\",\"ava2\":\"20230108\",\"use\":1},\"id\":\"123\",\"name\":\"John\",\"outNum\":356}", jsonObject.toString());
}
}

View File

@@ -1,18 +1,19 @@
package cn.hutool.json;
import cn.hutool.core.lang.Console;
import lombok.Data;
import lombok.experimental.Accessors;
import org.junit.Assert;
import org.junit.Test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class issues1881Test {
public class Issues1881Test {
@Accessors(chain = true)
@Data
public class ThingsHolderContactVO implements Serializable {
static class ThingsHolderContactVO implements Serializable {
private static final long serialVersionUID = -8727337936070932370L;
private Long id;
@@ -30,6 +31,6 @@ public class issues1881Test {
holderContactVOList.add(new ThingsHolderContactVO().setId(1L).setName("1"));
holderContactVOList.add(new ThingsHolderContactVO().setId(2L).setName("2"));
Console.log(JSONUtil.parseArray(holderContactVOList));
Assert.assertEquals("[{\"name\":\"1\",\"id\":1},{\"name\":\"2\",\"id\":2}]", JSONUtil.parseArray(holderContactVOList).toString());
}
}

View File

@@ -2,6 +2,7 @@ package cn.hutool.json;
import cn.hutool.core.lang.Console;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
/**
@@ -33,6 +34,7 @@ public class JSONStrFormatterTest {
}
@Test
@Ignore
public void formatTest4(){
String jsonStr = "{\"employees\":[{\"firstName\":\"Bill\",\"lastName\":\"Gates\"},{\"firstName\":\"George\",\"lastName\":\"Bush\"},{\"firstName\":\"Thomas\",\"lastName\":\"Carter\"}]}";
Console.log(JSONUtil.formatJsonStr(jsonStr));

View File

@@ -36,7 +36,7 @@ public class JSONUtilTest {
@Test(expected = JSONException.class)
public void parseNumberTest() {
JSONArray json = JSONUtil.parseArray(123L);
Console.log(json);
Assert.assertNotNull(json);
}
/**