diff --git a/feilong-context/src/main/java/com/feilong/context/converter/StringToBeanConverter.java b/feilong-core/src/main/java/com/feilong/context/converter/StringToBeanConverter.java
old mode 100755
new mode 100644
similarity index 95%
rename from feilong-context/src/main/java/com/feilong/context/converter/StringToBeanConverter.java
rename to feilong-core/src/main/java/com/feilong/context/converter/StringToBeanConverter.java
index d49d37ef7..9748e2b1f
--- a/feilong-context/src/main/java/com/feilong/context/converter/StringToBeanConverter.java
+++ b/feilong-core/src/main/java/com/feilong/context/converter/StringToBeanConverter.java
@@ -1,45 +1,47 @@
-/*
- * Copyright (C) 2008 feilong
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.feilong.context.converter;
-
-/**
- * 将字符串转成 bean 的转换器.
- *
- *
- * 功能和{@link org.apache.commons.collections4.Transformer} 类似,但是更专业和具体
- *
- *
- * @author feilong
- * @param
- * the generic type
- * @see org.apache.commons.collections4.Transformer
- * @see "org.springframework.core.convert.converter.Converter"
- * @see "org.springframework.core.convert.support.StringToEnumConverterFactory"
- * @since 1.8.3
- * @since 1.11.2 rename from AbstractParse
- */
-public interface StringToBeanConverter {
-
- /**
- * 转换.
- *
- * @param value
- * the value
- * @return 如果 value
是null或者empty,返回 null
- */
- T convert(String value);
-
-}
+/*
+ * Copyright (C) 2008 feilong
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.feilong.context.converter;
+
+/**
+ * 将字符串转成 bean 的转换器.
+ *
+ *
+ * 功能和{@link org.apache.commons.collections4.Transformer} 类似,但是更专业和具体
+ *
+ *
+ * @author feilong
+ * @param
+ * the generic type
+ * @see org.apache.commons.collections4.Transformer
+ * @see "org.springframework.core.convert.converter.Converter"
+ * @see "org.springframework.core.convert.support.StringToEnumConverterFactory"
+ * @since 1.8.3
+ * @since 1.11.2 rename from AbstractParse
+ * @since 4.1.2 move from feilong-context
+ */
+@FunctionalInterface
+public interface StringToBeanConverter {
+
+ /**
+ * 转换.
+ *
+ * @param value
+ * the value
+ * @return 如果 value
是null或者empty,返回 null
+ */
+ T convert(String value);
+
+}
diff --git a/feilong-core/src/main/java/com/feilong/core/lang/StringUtil.java b/feilong-core/src/main/java/com/feilong/core/lang/StringUtil.java
index 7549acbfc..79fd44e55 100644
--- a/feilong-core/src/main/java/com/feilong/core/lang/StringUtil.java
+++ b/feilong-core/src/main/java/com/feilong/core/lang/StringUtil.java
@@ -41,6 +41,7 @@
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
+import com.feilong.context.converter.StringToBeanConverter;
import com.feilong.core.CharsetType;
import com.feilong.core.Validate;
import com.feilong.core.bean.ConvertUtil;
@@ -1172,6 +1173,8 @@ public static boolean tokenizeToArrayContains(String config,String delimiter
return false;
}
+ //---------------------------------------------------------------
+
/**
* 将 189=988;200=455;这种格式的字符串转换成map , map的key 是189这种, value 是988,455 这种等号后面的值,使用逗号分隔成list.
*
@@ -1195,15 +1198,15 @@ public static boolean tokenizeToArrayContains(String config,String delimiter
*
*
*
- * @param config
+ * @param configString
* 189=988;200=455; 这种格式的配置字符串, 用分号分隔一组, 等号分隔key 和value
- * @return 如果 config
是null,返回 emptyMap()
- * 如果 config
是empty,返回 emptyMap()
+ * @return 如果 configString
是null,返回 emptyMap()
+ * 如果 configString
是empty,返回 emptyMap()
* @since 3.3.4
* @apiNote 自动去除空格,忽略空
*/
- public static Map toSingleValueMap(String config){
- return toSingleValueMap(config, String.class, String.class);
+ public static Map toSingleValueMap(String configString){
+ return toSingleValueMap(configString, String.class, String.class);
}
/**
@@ -1232,50 +1235,130 @@ public static Map toSingleValueMap(String config){
* the generic type
* @param
* the value type
- * @param config
+ * @param configString
* 189=988;200=455; 这种格式的配置字符串, 用分号分隔一组, 等号分隔key 和value
* @param keyClass
* key转换的类型,比如上面的背景中, 189 可以转换成String Long Integer
* @param valueElementClass
* value转换的类型,比如上面的背景中, 455 可以转换成String Long Integer
- * @return 如果 config
是null,返回 emptyMap()
- * 如果 config
是empty,返回 emptyMap()
+ * @return 如果 configString
是null,返回 emptyMap()
+ * 如果 configString
是empty,返回 emptyMap()
* 如果 keyClass
是null,抛出 {@link NullPointerException}
* 如果 valueElementClass
是null,抛出 {@link NullPointerException}
* @since 3.3.4
* @apiNote 自动去除空格,忽略空
*/
- public static Map toSingleValueMap(String config,Class keyClass,Class valueElementClass){
+ public static Map toSingleValueMap(String configString,Class keyClass,Class valueElementClass){
+ return toMap(configString, keyClass, (valueString) -> {
+ return convert(valueString, valueElementClass);
+ });
+ }
- if (isNullOrEmpty(config)){
+ /**
+ * 将 73034693=0-50;11487680=0-43;51099626=0-50; 这种格式的字符串转换成map.
+ *
+ *
+ * map的key 是73034693这种, value 可以TrackQueryExtendParam对象
+ *
+ *
+ * public class TrackQueryExtendParam{
+ *
+ * // 单集编号 最小.
+ * private Integer minEpisodeNumber;
+ *
+ * // 单集编号 最大.
+ * private Integer maxEpisodeNumber;
+ *
+ * //setter/getter 省略
+ * }
+ *
+ *
+ *
+ * 解析代码示例:
+ *
+ *
+ *
+ *
+ *
+ * String configString = "73034693=0-50;\n"//
+ * + "11487680=0-43;\n"//
+ * + "51099626=0-50;";
+ *
+ * Map{@code } map = StringUtil.toMap(configString, Long.class, (valueString) -> {
+ * String[] albumQueryParamsArray = StringUtil.tokenizeToStringArray(valueString, "-");
+ * if (isNullOrEmpty(albumQueryParamsArray)){
+ * return null;
+ * }
+ * try{
+ * //只有1个
+ * if (1 == size(albumQueryParamsArray)){
+ * //默认 0-x
+ * Integer max = toInteger(albumQueryParamsArray[0]);
+ * return new TrackQueryExtendParam(0, max);
+ * }
+ *
+ * Integer min = toInteger(albumQueryParamsArray[0]);
+ * Integer max = toInteger(albumQueryParamsArray[1]);
+ * return new TrackQueryExtendParam(min, max);
+ *
+ * }catch (Exception e){
+ * return null;
+ * }
+ * });
+ *
+ *
+ *
+ *
+ *
+ * @param
+ * the generic type
+ * @param
+ * the value type
+ * @param configString
+ * 73034693=0-50;11487680=0-43;51099626=0-50; 这种格式的配置字符串, 用分号分隔一组, 等号分隔key 和value
+ * @param keyClass
+ * key转换的类型,比如上面的背景中, 73034693 可以转换成String Long Integer
+ * @param valueStringToBeanConverter
+ * value转换的类型
+ * @return 如果 configString
是null,返回 emptyMap()
+ * 如果 configString
是empty,返回 emptyMap()
+ * 如果 keyClass
是null,抛出 {@link NullPointerException}
+ * 如果 stringToBeanConverter
是null,抛出 {@link NullPointerException}
+ * @since 4.1.2
+ * @apiNote 自动去除空格,忽略空
+ */
+ public static Map toMap(String configString,Class keyClass,StringToBeanConverter valueStringToBeanConverter){
+ if (isNullOrEmpty(configString)){
return emptyMap();
}
- Validate.notNull(keyClass, "keyClass can't be null!");
- Validate.notNull(valueElementClass, "valueElementClass can't be null!");
+ //entry之间的分隔符
+ String entryDelimiters = ";";
+ //key 和value之间的分隔符
+ String keyAndValueDelimiters = "=";
- //---------------------------------------------------------------
-
- String[] entrys = StringUtil.tokenizeToStringArray(config, ";");
+ String[] entrys = StringUtil.tokenizeToStringArray(configString, entryDelimiters);
if (isNullOrEmpty(entrys)){
return emptyMap();
}
+ //---------------------------------------------------------------
+ Validate.notNull(keyClass, "keyClass can't be null!");
+ Validate.notNull(valueStringToBeanConverter, "stringToBeanConverter can't be null!");
+ //---------------------------------------------------------------
Map map = newHashMap();
for (String keyAndValueString : entrys){
if (isNullOrEmpty(keyAndValueString)){
continue;
}
-
- String[] keyAndValues = StringUtil.tokenizeToStringArray(keyAndValueString, "=");
+ String[] keyAndValues = StringUtil.tokenizeToStringArray(keyAndValueString, keyAndValueDelimiters);
if (size(keyAndValues) != 2){
continue;
}
-
//---------------------------------------------------------------
- map.put(
- convert(keyAndValues[0], keyClass), //
- convert(keyAndValues[1], valueElementClass));
+ T key = ConvertUtil.convert(keyAndValues[0], keyClass);
+ V value = valueStringToBeanConverter.convert(keyAndValues[1]);
+ map.put(key, value);
}
return map;
}
@@ -1306,55 +1389,24 @@ public static Map toSingleValueMap(String config,Class keyClass,
* the generic type
* @param
* the value type
- * @param config
+ * @param configString
* 189=988,900;200=455; 这种格式的配置字符串, 用分号分隔一组, 等号分隔key 和value
* @param keyClass
* key转换的类型,比如上面的背景中, 189 可以转换成String Long Integer
* @param valueElementClass
* value转换的类型,比如上面的背景中, 455 可以转换成String Long Integer
- * @return 如果 config
是null,返回 emptyMap()
- * 如果 config
是empty,返回 emptyMap()
+ * @return 如果 configString
是null,返回 emptyMap()
+ * 如果 configString
是empty,返回 emptyMap()
* 如果 keyClass
是null,抛出 {@link NullPointerException}
* 如果 valueElementClass
是null,抛出 {@link NullPointerException}
* @since 3.3.4
* @apiNote 自动去除空格,忽略空
*/
- public static Map> toMultiValueMap(String config,Class keyClass,Class valueElementClass){
- if (isNullOrEmpty(config)){
- return emptyMap();
- }
-
- Validate.notNull(keyClass, "keyClass can't be null!");
- Validate.notNull(valueElementClass, "valueElementClass can't be null!");
-
- //---------------------------------------------------------------
- String[] entrys = tokenizeToStringArray(config, ";");
- if (isNullOrEmpty(entrys)){
- return emptyMap();
- }
-
- //---------------------------------------------------------------
-
- Map> map = newHashMap();
- for (String entry : entrys){
- if (isNullOrEmpty(entry)){
- continue;
- }
-
- String[] keyAndValuesMapping = tokenizeToStringArray(entry, "=");
- if (size(keyAndValuesMapping) != 2){
- continue;
- }
-
- //---------------------------------------------------------------
- T key = convert(keyAndValuesMapping[0], keyClass);
-
- String[] values = StringUtil.tokenizeToStringArray(keyAndValuesMapping[1], ",");
- List valueList = toList(toArray(values, valueElementClass));
-
- map.put(key, valueList);
- }
- return map;
+ public static Map> toMultiValueMap(String configString,Class keyClass,Class valueElementClass){
+ return toMap(configString, keyClass, (valueString) -> {
+ String[] values = StringUtil.tokenizeToStringArray(valueString, ",");
+ return toList(toArray(values, valueElementClass));
+ });
}
// [start]format
diff --git a/feilong-core/src/test/java/com/feilong/core/lang/stringutil/StringUtilSuiteTests.java b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/StringUtilSuiteTests.java
index a1601fafb..de9624f1d 100644
--- a/feilong-core/src/test/java/com/feilong/core/lang/stringutil/StringUtilSuiteTests.java
+++ b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/StringUtilSuiteTests.java
@@ -61,6 +61,7 @@
ToSingleValueMapTest.class,
ToSingleValueMapConvertTest.class,
ToMultiValueMapTest.class,
+ ToMapConvertTest.class,
//
})
public class StringUtilSuiteTests{
diff --git a/feilong-core/src/test/java/com/feilong/core/lang/stringutil/ToMapConvertTest.java b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/ToMapConvertTest.java
new file mode 100644
index 000000000..f3ae81565
--- /dev/null
+++ b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/ToMapConvertTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 feilong
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.feilong.core.lang.stringutil;
+
+import static com.feilong.core.Validator.isNullOrEmpty;
+import static com.feilong.core.bean.ConvertUtil.toInteger;
+import static com.feilong.core.bean.ConvertUtil.toLong;
+import static com.feilong.core.util.CollectionsUtil.size;
+import static java.util.Collections.emptyMap;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.feilong.context.converter.StringToBeanConverter;
+import com.feilong.core.lang.StringUtil;
+
+public class ToMapConvertTest{
+
+ StringToBeanConverter valueStringToBeanConverter = (value) -> {
+ return value;
+ };
+
+ @Test
+ public void toMap(){
+ assertEquals(emptyMap(), StringUtil.toMap("", String.class, null));
+ assertEquals(emptyMap(), StringUtil.toMap(" ", String.class, null));
+ assertEquals(emptyMap(), StringUtil.toMap(null, String.class, null));
+ }
+
+ //---------------------------------------------------------------
+
+ @Test(expected = NullPointerException.class)
+ public void toMap1(){
+ StringUtil.toMap("1=2", null, null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void toMap12(){
+ StringUtil.toMap("1=2", String.class, (StringToBeanConverter) null);
+ }
+
+ //---------------------------------------------------------------
+
+ @Test
+ public void toMap123(){
+ Map map = StringUtil.toMap("1=2", String.class, valueStringToBeanConverter);
+ assertThat(map, allOf(hasEntry("1", "2")));
+ }
+
+ @Test
+ public void toMap1223(){
+ Map map = StringUtil.toMap("1=2;", String.class, valueStringToBeanConverter);
+ assertThat(map, allOf(hasEntry("1", "2")));
+ }
+
+ @Test
+ public void toMap1333223(){
+ Map map = StringUtil.toMap("1=2;", Long.class, (value) -> {
+ return toLong(value);
+ });
+
+ assertThat(map, allOf(hasEntry(1L, 2L)));
+ }
+
+ @Test
+ public void toMap1333223Integer(){
+ Map map = StringUtil.toMap("1=2;", Integer.class, (value) -> {
+ return toInteger(value);
+ });
+
+ assertThat(map, allOf(hasEntry(1, 2)));
+ }
+
+ @Test
+ public void toMap1333223Integer222(){
+ Map map = StringUtil.toMap("1=2;89=100;200=230", Integer.class, (value) -> {
+ return toInteger(value);
+ });
+
+ assertThat(
+ map,
+ allOf(//
+ hasEntry(1, 2),
+ hasEntry(89, 100),
+ hasEntry(200, 230)));
+ }
+
+ @Test
+ public void toMap222(){
+ String configString = "73034693=0-50;\n"//
+ + "11487680=0-43;\n"//
+ + "51099626=0-50;";
+
+ Map map = StringUtil.toMap(configString, Long.class, (valueString) -> {
+ String[] albumQueryParamsArray = StringUtil.tokenizeToStringArray(valueString, "-");
+ if (isNullOrEmpty(albumQueryParamsArray)){
+ return null;
+ }
+ try{
+ //只有1个
+ if (1 == size(albumQueryParamsArray)){
+ //默认 0-x
+ Integer max = toInteger(albumQueryParamsArray[0]);
+ return new TrackQueryExtendParam(0, max);
+ }
+
+ Integer min = toInteger(albumQueryParamsArray[0]);
+ Integer max = toInteger(albumQueryParamsArray[1]);
+ return new TrackQueryExtendParam(min, max);
+
+ }catch (Exception e){
+ return null;
+ }
+ });
+
+ assertThat(
+ map,
+ allOf(//
+ hasEntry(73034693L, new TrackQueryExtendParam(0, 50)),
+ hasEntry(11487680L, new TrackQueryExtendParam(0, 43)),
+ hasEntry(51099626L, new TrackQueryExtendParam(0, 50))));
+ }
+}
\ No newline at end of file
diff --git a/feilong-core/src/test/java/com/feilong/core/lang/stringutil/ToSingleValueMapConvertTest.java b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/ToSingleValueMapConvertTest.java
index 6c5b04deb..014ea4fab 100644
--- a/feilong-core/src/test/java/com/feilong/core/lang/stringutil/ToSingleValueMapConvertTest.java
+++ b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/ToSingleValueMapConvertTest.java
@@ -45,7 +45,7 @@ public void toSingleValueMap1(){
@Test(expected = NullPointerException.class)
public void toSingleValueMap12(){
- StringUtil.toSingleValueMap("1=2", String.class, null);
+ StringUtil.toSingleValueMap("1=2", String.class, (Class) null);
}
//---------------------------------------------------------------
diff --git a/feilong-core/src/test/java/com/feilong/core/lang/stringutil/TrackQueryExtendParam.java b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/TrackQueryExtendParam.java
new file mode 100644
index 000000000..a77355b30
--- /dev/null
+++ b/feilong-core/src/test/java/com/feilong/core/lang/stringutil/TrackQueryExtendParam.java
@@ -0,0 +1,115 @@
+package com.feilong.core.lang.stringutil;
+
+import com.feilong.lib.lang3.builder.EqualsBuilder;
+import com.feilong.lib.lang3.builder.HashCodeBuilder;
+import com.feilong.lib.lang3.builder.ToStringBuilder;
+import com.feilong.lib.lang3.builder.ToStringStyle;
+
+/**
+ * 查询参数.
+ */
+public class TrackQueryExtendParam{
+
+ /** 单集编号 最小. */
+ private Integer minEpisodeNumber;
+
+ /** 单集编号 最大. */
+ private Integer maxEpisodeNumber;
+
+ //---------------------------------------------------------------
+
+ /**
+ *
+ */
+ public TrackQueryExtendParam(){
+ super();
+ }
+
+ /**
+ * @param minEpisodeNumber
+ * @param maxEpisodeNumber
+ */
+ public TrackQueryExtendParam(Integer minEpisodeNumber, Integer maxEpisodeNumber){
+ super();
+ this.minEpisodeNumber = minEpisodeNumber;
+ this.maxEpisodeNumber = maxEpisodeNumber;
+ }
+
+ //---------------------------------------------------------------
+
+ /**
+ * To string.
+ *
+ * @return the string
+ */
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString(){
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.DEFAULT_STYLE);
+ }
+
+ /**
+ * Gets the 单集编号 最小.
+ *
+ * @return the 单集编号 最小
+ */
+ public Integer getMinEpisodeNumber(){
+ return minEpisodeNumber;
+ }
+
+ /**
+ * Sets the 单集编号 最小.
+ *
+ * @param minEpisodeNumber
+ * the new 单集编号 最小
+ */
+ public void setMinEpisodeNumber(Integer minEpisodeNumber){
+ this.minEpisodeNumber = minEpisodeNumber;
+ }
+
+ /**
+ * Gets the 单集编号 最大.
+ *
+ * @return the 单集编号 最大
+ */
+ public Integer getMaxEpisodeNumber(){
+ return maxEpisodeNumber;
+ }
+
+ /**
+ * Sets the 单集编号 最大.
+ *
+ * @param maxEpisodeNumber
+ * the new 单集编号 最大
+ */
+ public void setMaxEpisodeNumber(Integer maxEpisodeNumber){
+ this.maxEpisodeNumber = maxEpisodeNumber;
+ }
+
+ //---------------------------------------------------------------
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode(){
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj){
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+}
\ No newline at end of file