mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add MapJoiner
This commit is contained in:
parent
d748366dfe
commit
df108a2dd7
@ -183,7 +183,7 @@ public class IterUtil {
|
|||||||
/**
|
/**
|
||||||
* 获取指定Bean列表中某个字段,生成新的列表
|
* 获取指定Bean列表中某个字段,生成新的列表
|
||||||
*
|
*
|
||||||
* @param <R> 返回元素类型
|
* @param <R> 返回元素类型
|
||||||
* @param <V> 对象类型
|
* @param <V> 对象类型
|
||||||
* @param iterable 对象列表
|
* @param iterable 对象列表
|
||||||
* @param fieldName 字段名(会通过反射获取其值)
|
* @param fieldName 字段名(会通过反射获取其值)
|
||||||
@ -197,7 +197,7 @@ public class IterUtil {
|
|||||||
/**
|
/**
|
||||||
* 获取指定Bean列表中某个字段,生成新的列表
|
* 获取指定Bean列表中某个字段,生成新的列表
|
||||||
*
|
*
|
||||||
* @param <R> 返回元素类型
|
* @param <R> 返回元素类型
|
||||||
* @param <V> 对象类型
|
* @param <V> 对象类型
|
||||||
* @param iter 对象列表
|
* @param iter 对象列表
|
||||||
* @param fieldName 字段名(会通过反射获取其值)
|
* @param fieldName 字段名(会通过反射获取其值)
|
||||||
@ -211,7 +211,7 @@ public class IterUtil {
|
|||||||
V value;
|
V value;
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
value = iter.next();
|
value = iter.next();
|
||||||
result.add((R)FieldUtil.getFieldValue(value, fieldName));
|
result.add((R) FieldUtil.getFieldValue(value, fieldName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -460,6 +460,7 @@ public class IterUtil {
|
|||||||
* @param index 位置
|
* @param index 位置
|
||||||
* @param <E> 元素类型
|
* @param <E> 元素类型
|
||||||
* @return 元素,找不到元素返回{@code null}
|
* @return 元素,找不到元素返回{@code null}
|
||||||
|
* @throws IndexOutOfBoundsException index < 0时报错
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public static <E> E get(final Iterator<E> iterator, int index) throws IndexOutOfBoundsException {
|
public static <E> E get(final Iterator<E> iterator, int index) throws IndexOutOfBoundsException {
|
||||||
|
109
hutool-core/src/main/java/cn/hutool/core/map/MapJoiner.java
Executable file
109
hutool-core/src/main/java/cn/hutool/core/map/MapJoiner.java
Executable file
@ -0,0 +1,109 @@
|
|||||||
|
package cn.hutool.core.map;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.StrJoiner;
|
||||||
|
import cn.hutool.core.text.StrUtil;
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map拼接器,可以拼接包括Map、Entry列表等。
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
*/
|
||||||
|
public class MapJoiner {
|
||||||
|
|
||||||
|
private final StrJoiner joiner;
|
||||||
|
private final String keyValueSeparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建一个MapJoiner
|
||||||
|
*
|
||||||
|
* @param separator entry之间的连接符
|
||||||
|
* @param keyValueSeparator kv之间的连接符
|
||||||
|
* @return MapJoiner
|
||||||
|
*/
|
||||||
|
public static MapJoiner of(final String separator, final String keyValueSeparator) {
|
||||||
|
return of(StrJoiner.of(separator), keyValueSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建一个MapJoiner
|
||||||
|
*
|
||||||
|
* @param joiner entry之间的Joiner
|
||||||
|
* @param keyValueSeparator kv之间的连接符
|
||||||
|
* @return MapJoiner
|
||||||
|
*/
|
||||||
|
public static MapJoiner of(final StrJoiner joiner, final String keyValueSeparator) {
|
||||||
|
return new MapJoiner(joiner, keyValueSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param joiner entry之间的Joiner
|
||||||
|
* @param keyValueSeparator kv之间的连接符
|
||||||
|
*/
|
||||||
|
public MapJoiner(final StrJoiner joiner, final String keyValueSeparator) {
|
||||||
|
this.joiner = joiner;
|
||||||
|
this.keyValueSeparator = keyValueSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加Map
|
||||||
|
*
|
||||||
|
* @param <K> 键类型
|
||||||
|
* @param <V> 值类型
|
||||||
|
* @param map Map
|
||||||
|
* @param predicate Map过滤器
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public <K, V> MapJoiner append(final Map<K, V> map, final Predicate<Map.Entry<K, V>> predicate) {
|
||||||
|
return append(map.entrySet().iterator(), predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加Entry列表
|
||||||
|
*
|
||||||
|
* @param <K> 键类型
|
||||||
|
* @param <V> 值类型
|
||||||
|
* @param parts Entry列表
|
||||||
|
* @param predicate Map过滤器
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public <K, V> MapJoiner append(final Iterator<? extends Map.Entry<K, V>> parts, final Predicate<Map.Entry<K, V>> predicate) {
|
||||||
|
if (null == parts) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<K, V> entry;
|
||||||
|
while (parts.hasNext()) {
|
||||||
|
entry = parts.next();
|
||||||
|
if (null == predicate || predicate.test(entry)) {
|
||||||
|
joiner.append(StrJoiner.of(this.keyValueSeparator).append(entry.getKey()).append(entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加其他字符串,其他字符串简单拼接
|
||||||
|
*
|
||||||
|
* @param params 字符串列表
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public MapJoiner append(final String... params) {
|
||||||
|
if(ArrayUtil.isNotEmpty(params)){
|
||||||
|
joiner.append(StrUtil.concat(false, params));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return joiner.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
import cn.hutool.core.collection.iter.ArrayIter;
|
import cn.hutool.core.collection.iter.ArrayIter;
|
||||||
import cn.hutool.core.collection.iter.IterUtil;
|
import cn.hutool.core.collection.iter.IterUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import cn.hutool.core.exceptions.UtilException;
|
import cn.hutool.core.exceptions.UtilException;
|
||||||
import cn.hutool.core.reflect.ConstructorUtil;
|
import cn.hutool.core.reflect.ConstructorUtil;
|
||||||
import cn.hutool.core.text.StrUtil;
|
import cn.hutool.core.text.StrUtil;
|
||||||
@ -605,28 +604,30 @@ public class MapUtil extends MapGetUtil {
|
|||||||
* @return 连接后的字符串,map和otherParams为空返回""
|
* @return 连接后的字符串,map和otherParams为空返回""
|
||||||
* @since 3.1.1
|
* @since 3.1.1
|
||||||
*/
|
*/
|
||||||
public static <K, V> String join(final Map<K, V> map, final String separator, final String keyValueSeparator, final boolean isIgnoreNull, final String... otherParams) {
|
public static <K, V> String join(final Map<K, V> map, final String separator, final String keyValueSeparator,
|
||||||
final StringBuilder strBuilder = StrUtil.builder();
|
final boolean isIgnoreNull, final String... otherParams) {
|
||||||
boolean isFirst = true;
|
return join(map, separator, keyValueSeparator, (entry) -> false == isIgnoreNull || entry.getKey() != null && entry.getValue() != null, otherParams);
|
||||||
if (isNotEmpty(map)) {
|
}
|
||||||
for (final Entry<K, V> entry : map.entrySet()) {
|
|
||||||
if (false == isIgnoreNull || entry.getKey() != null && entry.getValue() != null) {
|
/**
|
||||||
if (isFirst) {
|
* 将map转成字符串
|
||||||
isFirst = false;
|
*
|
||||||
} else {
|
* @param <K> 键类型
|
||||||
strBuilder.append(separator);
|
* @param <V> 值类型
|
||||||
}
|
* @param map Map,为空返回otherParams拼接
|
||||||
strBuilder.append(Convert.toStr(entry.getKey())).append(keyValueSeparator).append(Convert.toStr(entry.getValue()));
|
* @param separator entry之间的连接符
|
||||||
}
|
* @param keyValueSeparator kv之间的连接符
|
||||||
}
|
* @param predicate 键值对过滤
|
||||||
}
|
* @param otherParams 其它附加参数字符串(例如密钥)
|
||||||
// 补充其它字符串到末尾,默认无分隔符
|
* @return 连接后的字符串,map和otherParams为空返回""
|
||||||
if (ArrayUtil.isNotEmpty(otherParams)) {
|
* @since 3.1.1
|
||||||
for (final String otherParam : otherParams) {
|
*/
|
||||||
strBuilder.append(otherParam);
|
public static <K, V> String join(final Map<K, V> map, final String separator, final String keyValueSeparator,
|
||||||
}
|
final Predicate<Entry<K, V>> predicate, final String... otherParams) {
|
||||||
}
|
return MapJoiner.of(separator, keyValueSeparator)
|
||||||
return strBuilder.toString();
|
.append(map, predicate)
|
||||||
|
.append(otherParams)
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------- filter
|
// ----------------------------------------------------------------------------------------------- filter
|
||||||
|
@ -9,6 +9,7 @@ import cn.hutool.core.util.ObjUtil;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,7 +197,14 @@ public class StrJoiner implements Appendable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 追加对象到拼接器中
|
* 追加对象到拼接器中,支持:<br>
|
||||||
|
* <ul>
|
||||||
|
* <li>null,按照 {@link #nullMode} 策略追加</li>
|
||||||
|
* <li>array,逐个追加</li>
|
||||||
|
* <li>{@link Iterator},逐个追加</li>
|
||||||
|
* <li>{@link Iterable},逐个追加</li>
|
||||||
|
* <li>{@link Map.Entry},追加键,分隔符,再追加值</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param obj 对象,支持数组、集合等
|
* @param obj 对象,支持数组、集合等
|
||||||
* @return this
|
* @return this
|
||||||
@ -210,6 +218,9 @@ public class StrJoiner implements Appendable, Serializable {
|
|||||||
append((Iterator<?>) obj);
|
append((Iterator<?>) obj);
|
||||||
} else if (obj instanceof Iterable) {
|
} else if (obj instanceof Iterable) {
|
||||||
append(((Iterable<?>) obj).iterator());
|
append(((Iterable<?>) obj).iterator());
|
||||||
|
}else if (obj instanceof Map.Entry) {
|
||||||
|
final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
|
||||||
|
append(entry.getKey()).append(entry.getValue());
|
||||||
} else {
|
} else {
|
||||||
append(ObjUtil.toString(obj));
|
append(ObjUtil.toString(obj));
|
||||||
}
|
}
|
||||||
|
25
hutool-core/src/test/java/cn/hutool/core/map/MapJoinerTest.java
Executable file
25
hutool-core/src/test/java/cn/hutool/core/map/MapJoinerTest.java
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
package cn.hutool.core.map;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MapJoinerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void joinMapTest(){
|
||||||
|
final Dict v1 = Dict.of().set("id", 12).set("name", "张三").set("age", 23);
|
||||||
|
final MapJoiner joiner = MapJoiner.of("+", "-");
|
||||||
|
joiner.append(v1, null);
|
||||||
|
|
||||||
|
Assert.assertEquals("id-12+name-张三+age-23", joiner.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void joinMapWithPredicateTest(){
|
||||||
|
final Dict v1 = Dict.of().set("id", 12).set("name", "张三").set("age", 23);
|
||||||
|
final MapJoiner joiner = MapJoiner.of("+", "-");
|
||||||
|
joiner.append(v1, (entry)->"age".equals(entry.getKey()));
|
||||||
|
|
||||||
|
Assert.assertEquals("age-23", joiner.toString());
|
||||||
|
}
|
||||||
|
}
|
@ -240,4 +240,11 @@ public class MapUtilTest {
|
|||||||
Assert.assertTrue(v2s.contains(13));
|
Assert.assertTrue(v2s.contains(13));
|
||||||
Assert.assertTrue(v2s.contains("李四"));
|
Assert.assertTrue(v2s.contains("李四"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void joinIgnoreNullTest() {
|
||||||
|
final Dict v1 = Dict.of().set("id", 12).set("name", "张三").set("age", null);
|
||||||
|
final String s = MapUtil.joinIgnoreNull(v1, ",", "=");
|
||||||
|
Assert.assertEquals("id=12,name=张三", s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user