This commit is contained in:
Looly
2021-10-30 02:23:28 +08:00
parent 735325e870
commit 2d1fc30c27
9 changed files with 150 additions and 54 deletions

View File

@@ -3,7 +3,7 @@
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.7.16 (2021-10-29) # 5.7.16 (2021-10-30)
### 🐣新特性 ### 🐣新特性
* 【core 】 增加DateTime.toLocalDateTime * 【core 】 增加DateTime.toLocalDateTime
@@ -16,6 +16,7 @@
* 【core 】 TemporalUtil增加toChronoUnit、toTimeUnit方法issue#I4FGDH@Gitee * 【core 】 TemporalUtil增加toChronoUnit、toTimeUnit方法issue#I4FGDH@Gitee
* 【core 】 StopWatch增加prettyPrint重载issue#1910@Github * 【core 】 StopWatch增加prettyPrint重载issue#1910@Github
* 【core 】 修改RegexPool中Ipv4正则 * 【core 】 修改RegexPool中Ipv4正则
* 【json 】 Filter改为MutablePair以便编辑键值对issue#1921@Github
### 🐞Bug修复 ### 🐞Bug修复
* 【core 】 修复UrlBuilder.addPath歧义问题issue#1912@Github * 【core 】 修复UrlBuilder.addPath歧义问题issue#1912@Github

View File

@@ -16,17 +16,17 @@ import java.util.Objects;
public class Pair<K, V> extends CloneSupport<Pair<K, V>> implements Serializable { public class Pair<K, V> extends CloneSupport<Pair<K, V>> implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final K key; protected K key;
private final V value; protected V value;
/** /**
* 构建{@link Pair}对象 * 构建{@code Pair}对象
* *
* @param <K> 键类型 * @param <K> 键类型
* @param <V> 值类型 * @param <V> 值类型
* @param key 键 * @param key 键
* @param value 值 * @param value 值
* @return {@link Pair} * @return {@code Pair}
* @since 5.4.3 * @since 5.4.3
*/ */
public static <K, V> Pair<K, V> of(K key, V value) { public static <K, V> Pair<K, V> of(K key, V value) {

View File

@@ -3,7 +3,7 @@ package cn.hutool.core.lang.mutable;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
/** /**
* 可变 <code>double</code> 类型 * 可变 {@code double} 类型
* *
* @see Double * @see Double
* @since 3.0.1 * @since 3.0.1
@@ -150,12 +150,12 @@ public class MutableDouble extends Number implements Comparable<MutableDouble>,
* 相等需同时满足如下条件: * 相等需同时满足如下条件:
* <ol> * <ol>
* <li>非空</li> * <li>非空</li>
* <li>类型为 {@link MutableDouble}</li> * <li>类型为 {@code MutableDouble}</li>
* <li>值相等</li> * <li>值相等</li>
* </ol> * </ol>
* *
* @param obj 比对的对象 * @param obj 比对的对象
* @return 相同返回<code>true</code>,否则 <code>false</code> * @return 相同返回<code>true</code>,否则 {@code false}
*/ */
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
@@ -175,7 +175,7 @@ public class MutableDouble extends Number implements Comparable<MutableDouble>,
/** /**
* 比较 * 比较
* *
* @param other 其它 {@link MutableDouble} 对象 * @param other 其它 {@code MutableDouble} 对象
* @return x==y返回0x&lt;y返回-1x&gt;y返回1 * @return x==y返回0x&lt;y返回-1x&gt;y返回1
*/ */
@Override @Override

View File

@@ -0,0 +1,57 @@
package cn.hutool.core.lang.mutable;
import cn.hutool.core.lang.Pair;
/**
* 可变{@link Pair}实现,可以修改键和值
*
* @param <K> 键类型
* @param <V> 值类型
* @since 5.7.16
*/
public class MutablePair<K, V> extends Pair<K, V> implements Mutable<Pair<K, V>>{
private static final long serialVersionUID = 1L;
/**
* 构造
*
* @param key 键
* @param value 值
*/
public MutablePair(K key, V value) {
super(key, value);
}
/**
* 设置键
*
* @param key 新键
* @return this
*/
public MutablePair<K, V> setKey(K key) {
this.key = key;
return this;
}
/**
* 设置值
*
* @param value 新值
* @return this
*/
public MutablePair<K, V> setValue(V value) {
this.value = value;
return this;
}
@Override
public Pair<K, V> get() {
return this;
}
@Override
public void set(Pair<K, V> pair) {
this.key = pair.getKey();
this.value = pair.getValue();
}
}

View File

@@ -22,7 +22,6 @@ import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
@@ -118,7 +117,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
public static <T> boolean hasNull(T... array) { public static <T> boolean hasNull(T... array) {
if (isNotEmpty(array)) { if (isNotEmpty(array)) {
for (T element : array) { for (T element : array) {
if (null == element) { if (ObjectUtil.isNull(element)) {
return true; return true;
} }
} }
@@ -150,7 +149,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T firstNonNull(T... array) { public static <T> T firstNonNull(T... array) {
return firstMatch(Objects::nonNull, array); return firstMatch(ObjectUtil::isNotNull, array);
} }
/** /**

View File

@@ -292,7 +292,7 @@ public class ObjectUtil {
* @since 3.0.7 * @since 3.0.7
*/ */
public static <T> T defaultIfNull(final T object, final T defaultValue) { public static <T> T defaultIfNull(final T object, final T defaultValue) {
return (null != object) ? object : defaultValue; return isNull(object) ? defaultValue : object;
} }
@@ -300,14 +300,14 @@ public class ObjectUtil {
* 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值 * 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值
* *
* @param source Object 类型对象 * @param source Object 类型对象
* @param handle 自定义的处理方法 * @param handle 非空时自定义的处理方法
* @param defaultValue 默认为空的返回值 * @param defaultValue 默认为空的返回值
* @param <T> 被检查对象为{@code null}返回默认值否则返回自定义handle处理后的返回值 * @param <T> 被检查对象为{@code null}返回默认值否则返回自定义handle处理后的返回值
* @return 处理后的返回值 * @return 处理后的返回值
* @since 5.4.6 * @since 5.4.6
*/ */
public static <T> T defaultIfNull(Object source, Supplier<? extends T> handle, final T defaultValue) { public static <T> T defaultIfNull(Object source, Supplier<? extends T> handle, final T defaultValue) {
if (Objects.nonNull(source)) { if (isNotNull(source)) {
return handle.get(); return handle.get();
} }
return defaultValue; return defaultValue;

View File

@@ -4,7 +4,7 @@ import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.collection.ArrayIter; import cn.hutool.core.collection.ArrayIter;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Filter; import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.Pair; import cn.hutool.core.lang.mutable.MutablePair;
import cn.hutool.core.text.StrJoiner; import cn.hutool.core.text.StrJoiner;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
@@ -537,11 +537,11 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* 支持过滤器,即选择哪些字段或值不写出 * 支持过滤器,即选择哪些字段或值不写出
* *
* @param indentFactor 每层缩进空格数 * @param indentFactor 每层缩进空格数
* @param filter 键值对过滤器 * @param filter 过滤器可以修改值keyindex无法修改
* @return JSON字符串 * @return JSON字符串
* @since 5.7.15 * @since 5.7.15
*/ */
public String toJSONString(int indentFactor, Filter<Pair<Integer, Object>> filter){ public String toJSONString(int indentFactor, Filter<MutablePair<Integer, Object>> filter) {
final StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) { synchronized (sw.getBuffer()) {
return this.write(sw, indentFactor, 0, filter).toString(); return this.write(sw, indentFactor, 0, filter).toString();
@@ -560,18 +560,19 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @param writer writer * @param writer writer
* @param indentFactor 缩进因子,定义每一级别增加的缩进量 * @param indentFactor 缩进因子,定义每一级别增加的缩进量
* @param indent 本级别缩进量 * @param indent 本级别缩进量
* @param filter 过滤器 * @param filter 过滤器可以修改值keyindex无法修改
* @return Writer * @return Writer
* @throws JSONException JSON相关异常 * @throws JSONException JSON相关异常
* @since 5.7.15 * @since 5.7.15
*/ */
public Writer write(Writer writer, int indentFactor, int indent, Filter<Pair<Integer, Object>> filter) throws JSONException { public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Integer, Object>> filter) throws JSONException {
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config) final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
.beginArray(); .beginArray();
CollUtil.forEach(this, (value, index) -> { CollUtil.forEach(this, (value, index) -> {
if (null == filter || filter.accept(new Pair<>(index, value))) { final MutablePair<Integer, Object> pair = new MutablePair<>(index, value);
jsonWriter.writeValue(value); if (null == filter || filter.accept(pair)) {
jsonWriter.writeValue(pair.getValue());
} }
}); });
jsonWriter.end(); jsonWriter.end();
@@ -580,6 +581,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
} }
// ------------------------------------------------------------------------------------------------- Private method start // ------------------------------------------------------------------------------------------------- Private method start
/** /**
* 初始化 * 初始化
* *

View File

@@ -7,7 +7,7 @@ import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Filter; import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.Pair; import cn.hutool.core.lang.mutable.MutablePair;
import cn.hutool.core.map.CaseInsensitiveLinkedMap; import cn.hutool.core.map.CaseInsensitiveLinkedMap;
import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
@@ -560,11 +560,11 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* 支持过滤器,即选择哪些字段或值不写出 * 支持过滤器,即选择哪些字段或值不写出
* *
* @param indentFactor 每层缩进空格数 * @param indentFactor 每层缩进空格数
* @param filter 键值对过滤器 * @param filter 过滤器,同时可以修改编辑键和值
* @return JSON字符串 * @return JSON字符串
* @since 5.7.15 * @since 5.7.15
*/ */
public String toJSONString(int indentFactor, Filter<Pair<String, Object>> filter){ public String toJSONString(int indentFactor, Filter<MutablePair<String, Object>> filter) {
final StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) { synchronized (sw.getBuffer()) {
return this.write(sw, indentFactor, 0, filter).toString(); return this.write(sw, indentFactor, 0, filter).toString();
@@ -583,17 +583,18 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* @param writer writer * @param writer writer
* @param indentFactor 缩进因子,定义每一级别增加的缩进量 * @param indentFactor 缩进因子,定义每一级别增加的缩进量
* @param indent 本级别缩进量 * @param indent 本级别缩进量
* @param filter 过滤器 * @param filter 过滤器,同时可以修改编辑键和值
* @return Writer * @return Writer
* @throws JSONException JSON相关异常 * @throws JSONException JSON相关异常
* @since 5.7.15 * @since 5.7.15
*/ */
public Writer write(Writer writer, int indentFactor, int indent, Filter<Pair<String, Object>> filter) throws JSONException { public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<String, Object>> filter) throws JSONException {
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config) final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
.beginObj(); .beginObj();
this.forEach((key, value) -> { this.forEach((key, value) -> {
if (null == filter || filter.accept(new Pair<>(key, value))) { final MutablePair<String, Object> pair = new MutablePair<>(key, value);
jsonWriter.writeField(key, value); if (null == filter || filter.accept(pair)) {
jsonWriter.writeField(pair.getKey(), pair.getValue());
} }
}); });
jsonWriter.end(); jsonWriter.end();

View File

@@ -10,6 +10,7 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.test.bean.JSONBean; import cn.hutool.json.test.bean.JSONBean;
import cn.hutool.json.test.bean.ResultDto; import cn.hutool.json.test.bean.ResultDto;
@@ -537,9 +538,11 @@ public class JSONObjectTest {
public static class SameNameBean { public static class SameNameBean {
private final String username = "123"; private final String username = "123";
private final String userName = "abc"; private final String userName = "abc";
public String getUsername() { public String getUsername() {
return username; return username;
} }
@PropIgnore @PropIgnore
private final String fieldToIgnore = "sfdsdads"; private final String fieldToIgnore = "sfdsdads";
@@ -633,4 +636,37 @@ public class JSONObjectTest {
final String s = json1.toJSONString(0, (pair) -> false == pair.getKey().equals("b")); final String s = json1.toJSONString(0, (pair) -> false == pair.getKey().equals("b"));
Assert.assertEquals("{\"a\":\"value1\",\"c\":\"value3\",\"d\":true}", s); Assert.assertEquals("{\"a\":\"value1\",\"c\":\"value3\",\"d\":true}", s);
} }
@Test
public void editTest() {
JSONObject json1 = JSONUtil.createObj(JSONConfig.create().setOrder(true))
.set("a", "value1")
.set("b", "value2")
.set("c", "value3")
.set("d", true);
final String s = json1.toJSONString(0, (pair) -> {
if ("b".equals(pair.getKey())) {
// 修改值为新值
pair.setValue(pair.getValue() + "_edit");
return true;
}
// 除了"b",其他都去掉
return false;
});
Assert.assertEquals("{\"b\":\"value2_edit\"}", s);
}
@Test
public void nullToEmptyTest() {
JSONObject json1 = JSONUtil.createObj(JSONConfig.create().setOrder(true).setIgnoreNullValue(false))
.set("a", null)
.set("b", "value2");
final String s = json1.toJSONString(0, (pair) -> {
pair.setValue(ObjectUtil.defaultIfNull(pair.getValue(), StrUtil.EMPTY));
return true;
});
Assert.assertEquals("{\"a\":\"\",\"b\":\"value2\"}", s);
}
} }