mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix code
This commit is contained in:
@@ -195,6 +195,15 @@ public class BeanUtil {
|
||||
if (null == bean || StrUtil.isBlank(expression)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 先尝试直接获取属性
|
||||
if (bean instanceof Map) {
|
||||
final Map<?, ?> map = (Map<?, ?>) bean;
|
||||
if(map.containsKey(expression)){
|
||||
return (T) map.get(expression);
|
||||
}
|
||||
}
|
||||
|
||||
return (T) BeanPath.of(expression).getValue(bean);
|
||||
}
|
||||
|
||||
|
@@ -164,6 +164,9 @@ public class BeanPath implements Iterator<BeanPath> {
|
||||
*/
|
||||
public Object getValue(final Object bean) {
|
||||
final Object value = this.node.getValue(bean);
|
||||
if(null == value){
|
||||
return null;
|
||||
}
|
||||
if (!hasNext()) {
|
||||
return value;
|
||||
}
|
||||
|
@@ -52,6 +52,9 @@ public class NameNode implements Node {
|
||||
|
||||
@Override
|
||||
public Object getValue(final Object bean) {
|
||||
if(null == bean){
|
||||
return null;
|
||||
}
|
||||
if ("$".equals(name)) {
|
||||
return bean;
|
||||
}
|
||||
|
@@ -43,10 +43,7 @@ import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.Normalizer;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -2485,6 +2482,46 @@ public class CharSequenceUtil extends StrValidator {
|
||||
public static String indexedFormat(final CharSequence pattern, final Object... arguments) {
|
||||
return MessageFormat.format(pattern.toString(), arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本,使用 {varName} 占位<br>
|
||||
* map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {key} 表示
|
||||
* @param map 参数值对
|
||||
* @return 格式化后的文本
|
||||
*/
|
||||
public static String formatByMap(final CharSequence template, final Map<?, ?> map) {
|
||||
return formatByMap(template, map, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本,使用 {varName} 占位<br>
|
||||
* map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {key} 表示
|
||||
* @param map 参数值对
|
||||
* @param ignoreNull 是否忽略 {@code null} 值,忽略则 {@code null} 值对应的变量不被替换,否则替换为""
|
||||
* @return 格式化后的文本
|
||||
* @since 5.4.3
|
||||
*/
|
||||
public static String formatByMap(final CharSequence template, final Map<?, ?> map, final boolean ignoreNull) {
|
||||
return StrFormatter.formatByBean(template, map, ignoreNull);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本,使用 {varName} 占位<br>
|
||||
* bean = User:{a: "aValue", b: "bValue"} format("{a} and {b}", bean) ---=》 aValue and bValue
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {key} 表示
|
||||
* @param bean 参数Bean
|
||||
* @param ignoreNull 是否忽略 {@code null} 值,忽略则 {@code null} 值对应的变量不被替换,否则替换为""
|
||||
* @return 格式化后的文本
|
||||
* @since 5.4.3
|
||||
*/
|
||||
public static String formatByBean(final CharSequence template, final Object bean, final boolean ignoreNull) {
|
||||
return StrFormatter.formatByBean(template, bean, ignoreNull);
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region ----- wrap
|
||||
|
@@ -18,7 +18,6 @@ package org.dromara.hutool.core.text;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.func.FunctionPool;
|
||||
import org.dromara.hutool.core.text.placeholder.StrFormatter;
|
||||
import org.dromara.hutool.core.text.split.SplitUtil;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
|
||||
@@ -26,7 +25,6 @@ import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字符串工具类<br>
|
||||
@@ -36,10 +34,10 @@ import java.util.Map;
|
||||
* 字符串分割<strong>split</strong>参考:{@link SplitUtil} <br>
|
||||
* 多字符串判空<strong>hasBlank</strong>参考:{@link ArrayUtil}
|
||||
* </p>
|
||||
* @see SplitUtil#split(CharSequence, CharSequence) 对字符串分割
|
||||
* @see ArrayUtil#hasBlank(CharSequence...) 对多个字符串判空
|
||||
*
|
||||
* @author Looly
|
||||
* @see SplitUtil#split(CharSequence, CharSequence) 对字符串分割
|
||||
* @see ArrayUtil#hasBlank(CharSequence...) 对多个字符串判空
|
||||
*/
|
||||
public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
|
||||
@@ -130,6 +128,7 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
}
|
||||
|
||||
// region ----- str
|
||||
|
||||
/**
|
||||
* 将对象转为字符串<br>
|
||||
*
|
||||
@@ -164,9 +163,9 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
|
||||
if (obj instanceof String) {
|
||||
return (String) obj;
|
||||
}else if(obj instanceof char[]){
|
||||
} else if (obj instanceof char[]) {
|
||||
return new String((char[]) obj);
|
||||
}else if (obj instanceof byte[]) {
|
||||
} else if (obj instanceof byte[]) {
|
||||
return str((byte[]) obj, charset);
|
||||
} else if (obj instanceof Byte[]) {
|
||||
return str((Byte[]) obj, charset);
|
||||
@@ -240,7 +239,7 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
* @param value char[]值,注意这个数组不可修改!!
|
||||
* @return String
|
||||
*/
|
||||
public static String strFast(final char[] value){
|
||||
public static String strFast(final char[] value) {
|
||||
return FunctionPool.createString(value);
|
||||
}
|
||||
// endregion
|
||||
@@ -372,30 +371,4 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
public static String similar(final String str1, final String str2, final int scale) {
|
||||
return TextSimilarity.similar(str1, str2, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本,使用 {varName} 占位<br>
|
||||
* map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {key} 表示
|
||||
* @param map 参数值对
|
||||
* @return 格式化后的文本
|
||||
*/
|
||||
public static String format(final CharSequence template, final Map<?, ?> map) {
|
||||
return format(template, map, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本,使用 {varName} 占位<br>
|
||||
* map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {key} 表示
|
||||
* @param map 参数值对
|
||||
* @param ignoreNull 是否忽略 {@code null} 值,忽略则 {@code null} 值对应的变量不被替换,否则替换为""
|
||||
* @return 格式化后的文本
|
||||
* @since 5.4.3
|
||||
*/
|
||||
public static String format(final CharSequence template, final Map<?, ?> map, final boolean ignoreNull) {
|
||||
return StrFormatter.format(template, map, ignoreNull);
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ package org.dromara.hutool.core.text.placeholder;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.map.reference.WeakConcurrentMap;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.text.placeholder.template.NamedPlaceholderStrTemplate;
|
||||
@@ -70,27 +71,31 @@ public class StrFormatter {
|
||||
return strPattern;
|
||||
}
|
||||
return ((SinglePlaceholderStrTemplate) CACHE.computeIfAbsent(MutableEntry.of(strPattern, placeHolder), k ->
|
||||
StrTemplate.of(strPattern).placeholder(placeHolder).build()))
|
||||
.format(argArray);
|
||||
StrTemplate.of(strPattern).placeholder(placeHolder).build()))
|
||||
.format(argArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本,使用 {varName} 占位<br>
|
||||
* map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) ---=》 aValue and bValue
|
||||
* bean = User:{a: "aValue", b: "bValue"} format("{a} and {b}", bean) ---=》 aValue and bValue
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {key} 表示
|
||||
* @param map 参数值对
|
||||
* @param bean 参数Bean
|
||||
* @param ignoreNull 是否忽略 {@code null} 值,忽略则 {@code null} 值对应的变量不被替换,否则替换为""
|
||||
* @return 格式化后的文本
|
||||
* @since 5.7.10
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static String format(final CharSequence template, final Map<?, ?> map, final boolean ignoreNull) {
|
||||
public static String formatByBean(final CharSequence template, final Object bean, final boolean ignoreNull) {
|
||||
if (null == template) {
|
||||
return null;
|
||||
}
|
||||
if (null == map || map.isEmpty()) {
|
||||
return template.toString();
|
||||
|
||||
if (bean instanceof Map) {
|
||||
if (MapUtil.isEmpty((Map<?, ?>) bean)) {
|
||||
return template.toString();
|
||||
}
|
||||
}
|
||||
// Bean的空检查需要反射,性能很差,此处不检查
|
||||
|
||||
return ((NamedPlaceholderStrTemplate) CACHE.computeIfAbsent(MutableEntry.of(template, ignoreNull), k -> {
|
||||
final NamedPlaceholderStrTemplate.Builder builder = StrTemplate.ofNamed(template.toString());
|
||||
@@ -100,7 +105,7 @@ public class StrFormatter {
|
||||
builder.addFeatures(StrTemplate.Feature.FORMAT_NULL_VALUE_TO_EMPTY);
|
||||
}
|
||||
return builder.build();
|
||||
})).format(map);
|
||||
})).format(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -22,6 +22,7 @@ import org.dromara.hutool.core.collection.CollUtil;
|
||||
import org.dromara.hutool.core.collection.ListUtil;
|
||||
import org.dromara.hutool.core.exception.HutoolException;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.math.NumberUtil;
|
||||
import org.dromara.hutool.core.text.StrPool;
|
||||
import org.dromara.hutool.core.text.placeholder.StrTemplate;
|
||||
@@ -353,7 +354,7 @@ public class NamedPlaceholderStrTemplate extends StrTemplate {
|
||||
* @return 格式化字符串
|
||||
*/
|
||||
public String format(final Map<String, ?> map) {
|
||||
if (map == null) {
|
||||
if (MapUtil.isEmpty(map)) {
|
||||
return getTemplate();
|
||||
}
|
||||
return format(map::get, map::containsKey);
|
||||
|
@@ -12,6 +12,8 @@
|
||||
|
||||
package org.dromara.hutool.core.text;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.dromara.hutool.core.text.placeholder.StrFormatter;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -62,4 +64,20 @@ public class StrFormatterTest {
|
||||
final String result3 = StrFormatter.formatWith("this is \\\\$$$ for $$$", "$$$", "a", "b");
|
||||
Assertions.assertEquals("this is \\a for b", result3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatByBeanTest() {
|
||||
final User user = new User("张三", 18, true);
|
||||
final String s = StrFormatter.formatByBean("User name: {name}, age: {age}, gender: {gender}", user, true);
|
||||
|
||||
Assertions.assertEquals("User name: 张三, age: 18, gender: true", s);
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
private static class User{
|
||||
private String name;
|
||||
private int age;
|
||||
private boolean gender;
|
||||
}
|
||||
}
|
||||
|
@@ -89,10 +89,10 @@ public class StrUtilTest {
|
||||
@Test
|
||||
public void formatTest() {
|
||||
final String template = "你好,我是{name},我的电话是:{phone}";
|
||||
final String result = StrUtil.format(template, Dict.of().set("name", "张三").set("phone", "13888881111"));
|
||||
final String result = StrUtil.formatByMap(template, Dict.of().set("name", "张三").set("phone", "13888881111"));
|
||||
Assertions.assertEquals("你好,我是张三,我的电话是:13888881111", result);
|
||||
|
||||
final String result2 = StrUtil.format(template, Dict.of().set("name", "张三").set("phone", null));
|
||||
final String result2 = StrUtil.formatByMap(template, Dict.of().set("name", "张三").set("phone", null));
|
||||
Assertions.assertEquals("你好,我是张三,我的电话是:{phone}", result2);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user