在我们日常开发工作中, 类型转换是跑不掉的,下面特别封装十分常用的方法
主要由下面几个部分组成:
1.转成数组
方法
Description
toArray(T...)
将动态数组转成数组.
toArray(Collection, Class)
将集合 collection 转成数组.
toArray(String[], Class)
将字符串数组 toBeConvertedValue 转成指定类型 targetType 的数组.
1.1 toArray(T...)
将动态数组转成数组.
示例:
String[] array = ConvertUtil.toArray("1", "2"); = ["1", "2"];
String[] emptyArray = ConvertUtil.toArray(); = [] ; //= new String[] {};
Integer[] emptyArray = ConvertUtil.toArray(); = [] ; //= new Integer[] {};
//注意
String[] nullArray = ConvertUtil.toArray(null) = null;
ConvertUtil.toArray((String) null) = new String[] { null }
注意:
数组是具体化的(reified),而泛型在运行时是被擦除的(erasure)。
数组是在运行时才去判断数组元素的类型约束,而泛型正好相反,在运行时,泛型的类型信息是会被擦除的,只有编译的时候才会对类型进行强化。
**泛型擦除的规则: **
所有参数化容器类都被擦除成非参数化的(raw type); 如 List、List>都被擦除成 List
所有参数化数组都被擦除成非参数化的数组;如 List[],被擦除成 List[]
Raw type 的容器类,被擦除成其自身,如 List被擦 除成 List
原生类型(int,String 还有 wrapper 类)都擦除成他们的自身
参数类型 E,如果没有上限,则被擦除成 Object
所有约束参数如 Extends E>、都被擦 除成 E
如果有多个约束,擦除成第一个,如,则擦除成 Object
这将会导致下面的代码:
public static Map toArrayValueMap(Map singleValueMap){
Map arrayValueMap = newLinkedHashMap(singleValueMap.size());//保证顺序和参数singleValueMap顺序相同
for (Map.Entry entry : singleValueMap.entrySet()){
arrayValueMap.put(entry.getKey(), toArray(entry.getValue()));//注意此处的Value不要声明成V,否则会变成Object数组
}
return arrayValueMap;
}
调用的时候,
Map singleValueMap = MapUtil.newLinkedHashMap(2);
singleValueMap.put("province", "江苏省");
singleValueMap.put("city", "南通市");
Map arrayValueMap = MapUtil.toArrayValueMap(singleValueMap);
String[] strings = arrayValueMap.get("province");//此时返回的是 Object[]
会出现异常
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
1.2 toArray(Collection, Class)
将集合 collection 转成数组.
示例:
List list = new ArrayList<>();
list.add("xinge");
list.add("feilong");
以前你需要写成:
list.toArray(new String[list.size()]);
现在你只需要写成:
String[] array = ConvertUtil.toArray(list, String.class);
LOGGER.info(JsonUtil.format(array));
返回:
["xinge","feilong"]
1.3 toArray(String[], Class)
将字符串数组 toBeConvertedValue 转成指定类型 targetType 的数组.
示例:
String[] ss = { "2", "1" };
toArray(ss, Long.class); = new Long[] { 2L, 1L }
ConvertUtil.toArray((String[]) null, Serializable.class) = null
2.转成List
方法
Description
toList(T...)
数组转成 (ArrayList).
toList(Collection)
将 集合 collection 转成 list.
toList(Enumeration)
将枚举 enumeration 转成 List.
2.1 toList(T...)
数组转成 (ArrayList).
说明:
此方法返回的list可以进行add等操作
如果直接使用Arrays#asList(Object...)返回的list没有实现 Collection#add(Object)等方法,执行list.add("c");操作的话会导致异常!
而本方法使用 ArrayList.ArrayList(java.util.Collection) 来进行重新封装返回,可以执行正常的list操作
特别适合:
如果你要通过以下方式来构造list:
List list = new ArrayList<>();
list.add("feilong1");
list.add("feilong2");
list.add("feilong2");
list.add("feilong3");
此时你可以使用:
List list = toList("feilong1", "feilong2", "feilong2", "feilong3");
代码会更简洁
甚至于:
有很多时候,参数需要一个对象list,构造的时候,你需要这样
List userAddresseList = new ArrayList<>();
UserAddress userAddress = new UserAddress();
userAddress.setAddress("上海");
userAddresseList.add(userAddress);
你可以重构成:
UserAddress userAddress = new UserAddress();
userAddress.setAddress("上海");
List userAddresseList = toList(userAddress);
2.2 toList(Collection)
将 集合 collection 转成 list.
说明:
此方法很适合快速的将set转成list这样的操作
示例:
Set set = new LinkedHashSet<>();
Collections.addAll(set, "a", "a", "b", "b");
LOGGER.debug("{}", toList(set));
返回:
[a,b]
2.3 toList(Enumeration)
将枚举 enumeration 转成 List.
示例:
toList((Enumeration) null) = emptyList()
3.转成Map
方法
Description
toMap(K, V)
将 key 和 value 直接转成map.
toMap(K, V, K, V)
将 key1 和 value1/key2 和 value2 直接转成map.
toMap(Map, Class, Class)
将诸如 Map 类型转成 Map 类型.
toMap(Map, Transformer, Transformer)
将诸如 Map 类型转成 Map 类型.
toMap(Properties)
将 properties 转换成map.
toMap(Collection)
将 mapEntryCollection 转成map (LinkedHashMap).
toMapUseEntrys(Entry...)
将 java.util.Map.Entry数组转成map (LinkedHashMap).
3.1 toMap(K, V)
将 key 和 value 直接转成map.
说明:
返回是的是 LinkedHashMap
非常适合单key的场景,比如
Map paramMap = new HashMap<>();
paramMap.put("name", "jinxin");
request.setParamMap(paramMap);
上面的3行代码可以重写成
request.setParamMap(toMap("name", "jinxin"));
一行代码就搞定了,很简洁,有木有~~
示例:
LOGGER.debug(JsonUtil.format(ConvertUtil.toMap("张飞", "丈八蛇矛")));
返回:
{"张飞": "丈八蛇矛"}
重构:
对于以下代码:
private List loadShopCommandList(){
Map paraMap = new HashMap<>();
paraMap.put("orgTypeId", OrgType.ID_SHOP_TYPE);
return shopCommandDao.findShopListByOrgaTypeId(paraMap);
}
可以重构成:
private List loadShopCommandList(){
return shopCommandDao.findShopListByOrgaTypeId(ConvertUtil.toMap("orgTypeId", (Object) OrgType.ID_SHOP_TYPE));
}
3.2 toMap(K, V, K, V)
将 key1 和 value1/key2 和 value2 直接转成map.
说明:
返回是的是 LinkedHashMap
非常适合2个key的场景,比如
Map paramMap = new HashMap<>();
paramMap.put("name", "jinxin");
paramMap.put("age", "18");
request.setParamMap(paramMap);
上面的3行代码可以重写成
request.setParamMap(toMap("name", "jinxin", "age", "18"));
一行代码就搞定了,很简洁,有木有~~
重构:
对于以下代码:
Map map = new HashMap<>();
map.put("itemId", itemId);
map.put("memberId", memberId);
memberFavoritesDao.findMemberFavoritesByMemberIdAndItemId(map);
可以重构成:
Map map = ConvertUtil.toMap("itemId", itemId, "memberId", memberId);
memberFavoritesDao.findMemberFavoritesByMemberIdAndItemId(map);
3.3 toMap(Map, Class, Class)
将诸如 Map 类型转成 Map 类型.
说明:
适合只是简单的将key value类型转换,而不需要自己再构建Transformer,再去调用 toMap(Map, Transformer, Transformer) ,简化操作
返回的是 LinkedHashMap,顺序依照入参 inputMap
返回的是新的map,原来的toMap参数不受影响
也支持诸如 Map 转 Map (key和value 使用不同的转换器)
也支持诸如 Map 转 Map (单值转数组)
也支持诸如 Map 转 Map (数组转数组)
示例:
场景1: 将Map 转 Map 类型
Map map = toMap("1", "2");
Map returnMap = toMap(map, Integer.class, Integer.class);
// 输出测试
for (Map.Entry entry : returnMap.entrySet()){
Integer key = entry.getKey();
Integer value = entry.getValue();
LOGGER.debug("key:[{}],value:[{}]", key, value);
}
返回:
key:[1],value:[2]
场景2: Map 转 Map
Map map = toMap("1", "2,2");
//key和value转成不同的类型
Map returnMap = toMap(map, Integer.class, Integer[].class);
// 输出测试
for (Map.Entry entry : returnMap.entrySet()){
Integer key = entry.getKey();
Integer[] value = entry.getValue();
LOGGER.debug("key:[{}],value:[{}]", key, value);
}
返回:
key:[1],value:[[2, 2]]
场景3: Map 转 Map
Map map = toMap(toArray("1"), toArray("2", "8"));
//key和value转成不同的类型
Map returnMap = toMap(map, Integer[].class, Long[].class);
assertThat(returnMap, allOf(hasEntry(toArray(1), toArray(2L, 8L))));
3.4 toMap(Map, Transformer, Transformer)
将诸如 Map 类型转成 Map 类型.
说明:
适合复杂的类型转换场景,如果只是简单的类型转换,你可以直接调用 toMap(Map, Class, Class)
返回的是 LinkedHashMap,顺序依照入参 inputMap
返回的是新的map,原来的toMap参数不受影响
也支持诸如 Map 转 Map (key和value 使用不同的转换器)
也支持诸如 Map 转 Map (单值转数组)
也支持诸如 Map 转 Map (数组转数组)
示例:
**场景1: **将Map 转 Map 类型
Map map = toMap("1", "2");
//key和value 都转成integer 使用相同的转换器
Transformer transformer = new SimpleClassTransformer<>(Integer.class);
Map returnMap = toMap(map, transformer, transformer);
// 输出测试
for (Map.Entry entry : returnMap.entrySet()){
Integer key = entry.getKey();
Integer value = entry.getValue();
LOGGER.debug("key:[{}],value:[{}]", key, value);
}
返回:
key:[1],value:[2]
场景2: Map 转 Map
Map map = toMap("1", "2,2");
Transformer keyTransformer = new SimpleClassTransformer<>(Integer.class);
Transformer valueTransformer = new SimpleClassTransformer<>(Integer[].class);
//key和value转成不同的类型
Map returnMap = toMap(map, keyTransformer, valueTransformer);
// 输出测试
for (Map.Entry entry : returnMap.entrySet()){
Integer key = entry.getKey();
Integer[] value = entry.getValue();
LOGGER.debug("key:[{}],value:[{}]", key, value);
}
返回:
key:[1],value:[[2, 2]]
场景3: Map 转 Map
Map map = toMap(toArray("1"), toArray("2", "8"));
Transformer keyTransformer = new SimpleClassTransformer<>(Integer[].class);
Transformer valueTransformer = new SimpleClassTransformer<>(Long[].class);
//key和value转成不同的类型
Map returnMap = toMap(map, keyTransformer, valueTransformer);
assertThat(returnMap, allOf(hasEntry(toArray(1), toArray(2L, 8L))));
3.5 toMap(Properties)
将 properties 转换成map.
示例:
Properties properties = new Properties();
properties.setProperty("name", "feilong");
properties.setProperty("age", "18");
properties.setProperty("country", "china");
LOGGER.debug(JsonUtil.format(toMap(properties)));
返回:
{
"age": "18",
"country": "china",
"name": "feilong"
}
说明:
返回的map 经过了 SortUtil.sortMapByKeyAsc(Map)排序处理,方便输出日志
3.6 toMapUseEntrys(Entry...)
将 java.util.Map.Entry数组转成map (LinkedHashMap).
说明:
返回是的是 LinkedHashMap,顺序依照参数 java.util.Map.Entry数组顺序,key是 java.util.Map.Entry.getKey(),value 是 java.util.Map.Entry.getValue()
java.util.Map.Entry 已知实现类,你可以使用 Pair,或者 java.util.AbstractMap.SimpleEntry
Pair 示例:
Map map = ConvertUtil.toMapUseEntrys(
Pair.of("张飞", "丈八蛇矛"),
Pair.of("关羽", "青龙偃月刀"),
Pair.of("赵云", "龙胆枪"),
Pair.of("刘备", "双股剑"));
LOGGER.debug(JsonUtil.format(map));
返回:
{
"张飞": "丈八蛇矛",
"关羽": "青龙偃月刀",
"赵云": "龙胆枪",
"刘备": "双股剑"
}
java.util.AbstractMap.SimpleEntry 示例:
Map map = ConvertUtil.toMapUseEntrys(
new SimpleEntry<>("张飞", "丈八蛇矛"),
new SimpleEntry<>("关羽", "青龙偃月刀"),
new SimpleEntry<>("赵云", "龙胆枪"),
new SimpleEntry<>("刘备", "双股剑"));
LOGGER.debug(JsonUtil.format(map));
返回:
{
"张飞": "丈八蛇矛",
"关羽": "青龙偃月刀",
"赵云": "龙胆枪",
"刘备": "双股剑"
}
重构:
以前初始化全局map的时候,你可能会这么写
// 除数和单位的map,必须是有顺序的 从大到小.
private static final Map DIVISOR_AND_UNIT_MAP = new LinkedHashMap<>();
static{
DIVISOR_AND_UNIT_MAP.put(FileUtils.ONE_TB, "TB");//(Terabyte,太字节,或百万兆字节)=1024GB,其中1024=2^10(2的10次方)
DIVISOR_AND_UNIT_MAP.put(FileUtils.ONE_GB, "GB");//(Gigabyte,吉字节,又称“千兆”)=1024MB
DIVISOR_AND_UNIT_MAP.put(FileUtils.ONE_MB, "MB");//(Megabyte,兆字节,简称“兆”)=1024KB
DIVISOR_AND_UNIT_MAP.put(FileUtils.ONE_KB, "KB");//(Kilobyte 千字节)=1024B
}
现在你可以重构成:
// 除数和单位的map,必须是有顺序的 从大到小.
private static final Map DIVISOR_AND_UNIT_MAP = ConvertUtil.toMapUseEntrys(
Pair.of(FileUtils.ONE_TB, "TB"), //(Terabyte,太字节,或百万兆字节)=1024GB,其中1024=2^10(2的10次方)
Pair.of(FileUtils.ONE_GB, "GB"), //(Gigabyte,吉字节,又称“千兆”)=1024MB
Pair.of(FileUtils.ONE_MB, "MB"), //(Megabyte,兆字节,简称“兆”)=1024KB
Pair.of(FileUtils.ONE_KB, "KB")); //(Kilobyte 千字节)=1024B
代码更加简洁
3.7 toMap(Collection)
将 mapEntryCollection 转成map (LinkedHashMap).
说明:
返回是的是 LinkedHashMap,顺序依照参数 mapEntryCollection,key是 java.util.Map.Entry.getKey(),value 是 java.util.Map.Entry.getValue()
java.util.Map.Entry 已知实现类,你可以使用 Pair,或者 java.util.AbstractMap.SimpleEntry
Pair 示例:
Map map = toMap(toList(//
Pair.of("张飞", "丈八蛇矛"),
Pair.of("关羽", "青龙偃月刀"),
Pair.of("赵云", "龙胆枪"),
Pair.of("刘备", "双股剑")));
LOGGER.debug(JsonUtil.format(map));
返回:
{
"张飞": "丈八蛇矛",
"关羽": "青龙偃月刀",
"赵云": "龙胆枪",
"刘备": "双股剑"
}
java.util.AbstractMap.SimpleEntry 示例:
Map map = ConvertUtil.toMap(
toList(
new SimpleEntry<>("张飞", "丈八蛇矛"),
new SimpleEntry<>("关羽", "青龙偃月刀"),
new SimpleEntry<>("赵云", "龙胆枪"),
new SimpleEntry<>("刘备", "双股剑")));
LOGGER.debug(JsonUtil.format(map));
返回:
{
"张飞": "丈八蛇矛",
"关羽": "青龙偃月刀",
"赵云": "龙胆枪",
"刘备": "双股剑"
}
4.转成常用类型
方法
Description
toInteger(Object)
将 toBeConvertedValue 转换成 Integer类型.
toInteger(Object, Integer)
将 toBeConvertedValue 转换成 Integer类型,如果转换不了返回默认值 defaultValue.
toIntegers(Object)
将 toBeConvertedValue 转成Integer 数组.
toBoolean(Object)
将 toBeConvertedValue 转换成 Boolean类型.
toLong(Object)
将 toBeConvertedValue 转换成 Long类型.
toLongs(Object)
将 toBeConvertedValue 转成Long 数组.
toBigDecimal(Object)
将 toBeConvertedValue 转换成 java.math.BigDecimal.
4.1 toInteger(Object)
将 toBeConvertedValue 转换成 Integer类型.
示例:
ConvertUtil.toInteger(null) = null
ConvertUtil.toInteger("aaaa") = null
ConvertUtil.toInteger(8L) = 8
ConvertUtil.toInteger("8") = 8
ConvertUtil.toInteger(new BigDecimal("8")) = 8
如果传入的参数 toBeConvertedValue 是 数组,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) L227:
ConvertUtil.toInteger(new String[] { "1", "2", "3" }) = 1
如果传入的参数 toBeConvertedValue 是 集合,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) Line234:
ConvertUtil.toInteger(toList("1", "2")) = 1
该方法非常适用 获取request请求的分页参数
示例:
原来的写法:
public static Integer getCurrentPageNo(HttpServletRequest request,String pageParamName){
String pageNoString = RequestUtil.getParameter(request, pageParamName);
try{
int pageNo = Integer.parseInt(pageNoString);
return pageNo;
}catch (Exception e){
LOGGER.error(e.getClass().getName(), e);
}
return 1; // 不带这个参数或者转换异常返回1
}
现在可以更改成:
public static Integer getCurrentPageNo(HttpServletRequest request,String pageParamName){
String pageNoString = RequestUtil.getParameter(request, pageParamName);
Integer pageNo = ConvertUtil.toInteger(pageNoString);
return null == pageNo ? 1 : pageNo;
}
当然对于这种场景,最快捷的:调用支持默认值的 toInteger(Object, Integer) 方法
public static Integer getCurrentPageNo(HttpServletRequest request,String pageParamName){
String pageNoString = RequestUtil.getParameter(request, pageParamName);
return ConvertUtil.toInteger(pageNoString, 1);
}
4.2 toInteger(Object, Integer)
将 toBeConvertedValue 转换成 Integer类型,如果转换不了返回默认值 defaultValue.
示例:
ConvertUtil.toInteger(null,null) = null
ConvertUtil.toInteger(null,1) = 1
ConvertUtil.toInteger("aaaa",1) = 1
ConvertUtil.toInteger(8L,1) = 8
ConvertUtil.toInteger("8",1) = 8
ConvertUtil.toInteger(new BigDecimal("8"),1) = 8
如果传入的参数 toBeConvertedValue 是 数组,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) L227:
ConvertUtil.toInteger(new String[] { "1", "2", "3" }, 8) = 1
如果传入的参数 toBeConvertedValue 是 集合,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) Line234:
ConvertUtil.toInteger(toList("1", "2"), 8) = 1
该方法非常适用 获取request请求的分页参数
示例:
原来的写法:
public static Integer getCurrentPageNo(HttpServletRequest request,String pageParamName){
String pageNoString = RequestUtil.getParameter(request, pageParamName);
try{
int pageNo = Integer.parseInt(pageNoString);
return pageNo;
}catch (Exception e){
LOGGER.error(e.getClass().getName(), e);
}
return 1; // 不带这个参数或者转换异常返回1
}
现在可以更改成:
public static Integer getCurrentPageNo(HttpServletRequest request,String pageParamName){
String pageNoString = RequestUtil.getParameter(request, pageParamName);
return ConvertUtil.toInteger(pageNoString, 1);
}
4.3 toIntegers(Object)
将 toBeConvertedValue 转成Integer 数组.
说明:
核心实现,参见 ArrayConverter.convertToType(Class, Object)
如果参数 toBeConvertedValue是 数组 或者 Collection ,参见ArrayConverter#convertToType(Class,Object),会构造一个Integer数组,长度就是 toBeConvertedValue的大小或者长度,然后迭代toBeConvertedValue依次逐个进行转换
示例:
ConvertUtil.toIntegers(new String[] { "1", "2", "3" }) = [1,2,3]
ConvertUtil.toIntegers(toList("1", "2", "3")) = [1,2,3]
如果参数 toBeConvertedValue不是数组也不是Collection
那么首先会调用 ArrayConverter.convertToCollection(Class, Object) 将 toBeConvertedValue转成集合,转换逻辑参见 ArrayConverter.convertToCollection(Class, Object):
如果 toBeConvertedValue是Number, Boolean 或者 java.util.Date ,那么构造只有一个 toBeConvertedValue 元素的 List返回.
其他类型将转成字符串,然后调用 ArrayConverter.parseElements(Class, String)转成list.
具体转换逻辑为:
字符串期望是一个逗号分隔的字符串.
字符串可以被'{' 开头 和 '}'结尾的分隔符包裹,程序内部会自动截取.
会去除前后空白.
Elements in the list may be delimited by single or double quotes. Within a quoted elements, the normal Java escape sequences are valid.
得到list之后,会构造一个Integer数组,长度就是 toBeConvertedValue的大小或者长度,然后迭代toBeConvertedValue依次逐个进行转换
示例:
ConvertUtil.toIntegers("1,2,3") = new Integer[] { 1, 2, 3 }
ConvertUtil.toIntegers("{1,2,3}") = new Integer[] { 1, 2, 3 }
ConvertUtil.toIntegers("{ 1 ,2,3}") = new Integer[] { 1, 2, 3 }
ConvertUtil.toIntegers("1,2, 3") = new Integer[] { 1, 2, 3 }
ConvertUtil.toIntegers("1,2 , 3") = new Integer[] { 1, 2, 3 }
每个元素转换成 Integer的时候,会调用 org.apache.commons.beanutils.converters.NumberConverter.convertToType(Class, Object),具体的规则是:
1.如果 元素是 Number类型
那么会调用 org.apache.commons.beanutils.converters.NumberConverter.toNumber(Class, Class, Number)
2.如果 元素是 Boolean类型
那么 true被转成1,false 转成 0
3.其他情况
将元素转成字符串,并trim,再进行转换
4.元素是null的情况
如果有元素是null,那么会调用 org.apache.commons.beanutils.converters.AbstractConverter.convert(Class, Object),会调用 org.apache.commons.beanutils.converters.AbstractConverter.handleMissing(Class) 方法,没有默认值的话,会抛出异常,然后catch之后返回 empty Integer 数组
示例:
ConvertUtil.toIntegers(toList("1", "2", " 3")) = new Integer[] { 1, 2, 3 }
ConvertUtil.toIntegers(toArray(true, false, false)) = new Integer[] { 1, 0, 0 }
ConvertUtil.toIntegers(new String[] { "1", null, "2", "3" })
4.4 toBoolean(Object)
将 toBeConvertedValue 转换成 Boolean类型.
示例:
ConvertUtil.toBoolean(null) = null
ConvertUtil.toBoolean(1L) = true
ConvertUtil.toBoolean("1") = true
ConvertUtil.toBoolean("9") = false
ConvertUtil.toBoolean("1,2,3") = false
逻辑及规则:
如果 "true", "yes", "y", "on", "1", 返回 true
如果 "false", "no", "n", "off", "0", 返回 false
其他抛出 conversionException, 但是在 handleError(Class, Object, Throwable) 方法里面返回默认值, BooleanConverter 的默认值,参见 registerStandard(boolean, boolean)
你也可以调用 BooleanConverter(String[], String[], Object) 设置 trueStrings 和 falseStrings
和 Boolean.parseBoolean(String)的区别:
Boolean.parseBoolean(String),仅当 (String != null) 并且 String.equalsIgnoreCase("true") 返回 true
4.5 toLong(Object)
将 toBeConvertedValue 转换成 Long类型.
示例:
ConvertUtil.toLong(null) = null
ConvertUtil.toLong("aaaa") = null
ConvertUtil.toLong(8) = 8L
ConvertUtil.toLong("8") = 8L
ConvertUtil.toLong(new BigDecimal("8")) = 8L
如果传入的参数 toBeConvertedValue 是 数组,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) L227:
ConvertUtil.toLong(new String[] { "1", "2", "3" }) = 1L
如果传入的参数 toBeConvertedValue 是 集合,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) Line234:
ConvertUtil.toLong(toList("1", "2")) = 1L
4.6 toLongs(Object)
将 toBeConvertedValue 转成Long 数组.
说明:
核心实现,参见 ArrayConverter.convertToType(Class, Object)
如果参数 toBeConvertedValue 是 数组 或者 Collection
参见ArrayConverter#convertToType(Class,Object)
会构造一个Long数组,长度就是 toBeConvertedValue的大小或者长度,然后迭代toBeConvertedValue依次逐个进行转换
示例:
ConvertUtil.toLongs(new String[] { "1", "2", "3" } = [1L,2L,3L]
ConvertUtil.toLongs(toList("1", "2", "3")) = [1L,2L,3L]
如果参数 toBeConvertedValue不是数组也不是Collection
那么首先会调用 ArrayConverter.convertToCollection(Class, Object) 将 toBeConvertedValue转成集合,转换逻辑参见 ArrayConverter.convertToCollection(Class, Object):
如果 toBeConvertedValue是Number, Boolean 或者 java.util.Date ,那么构造只有一个 toBeConvertedValue 元素的 List返回.
其他类型将转成字符串,然后调用 ArrayConverter.parseElements(Class, String)转成list.
具体转换逻辑为:
字符串期望是一个逗号分隔的字符串.
字符串可以被'{' 开头 和 '}'结尾的分隔符包裹,程序内部会自动截取.
会去除前后空白.
Elements in the list may be delimited by single or double quotes. Within a quoted elements, the normal Java escape sequences are valid.
得到list之后,会构造一个Long数组,长度就是 toBeConvertedValue的大小或者长度,然后迭代toBeConvertedValue依次逐个进行转换
示例:
ConvertUtil.toLongs("1,2,3") = new Long[] { 1L, 2L, 3L }
ConvertUtil.toLongs("{1,2,3}") = new Long[] { 1L, 2L, 3L }
ConvertUtil.toLongs("{ 1 ,2,3}") = new Long[] { 1L, 2L, 3L }
ConvertUtil.toLongs("1,2, 3") = new Long[] { 1L, 2L, 3L }
ConvertUtil.toLongs("1,2 , 3") = new Long[] { 1L, 2L, 3L }
每个元素转换成 Integer的时候,会调用 org.apache.commons.beanutils.converters.NumberConverter.convertToType(Class, Object),具体的规则是:
1.如果 元素是 Number类型
那么会调用 org.apache.commons.beanutils.converters.NumberConverter.toNumber(Class, Class, Number)
2.如果 元素是 Boolean类型
那么 true被转成1L,false 转成 0L
3.其他情况
将元素转成字符串,并trim,再进行转换
4.元素是null的情况
如果有元素是null,那么会调用 org.apache.commons.beanutils.converters.AbstractConverter.convert(Class, Object),会调用 org.apache.commons.beanutils.converters.AbstractConverter.handleMissing(Class) 方法,没有默认值的话,会抛出异常,然后catch之后返回 empty Integer 数组
示例:
ConvertUtil.toLongs(toList("1", "2", " 3")) = new Long[] { 1L, 2L, 3L }
ConvertUtil.toLongs(toArray(true, false, false)) = new Long[] { 1L, 0L, 0L }
ConvertUtil.toLongs(new String[] { "1", null, "2", "3" }) = new Long[] {}
特别适合以下形式的代码:
protected long[] getOrderIdLongs(String orderIds){
// 确认交易时候插入数据库的时候,不应该会出现空的情况
String[] orderIdArray = orderIds.split(",");
int orderLength = orderIdArray.length;
long[] ids = new long[orderLength];
for (int i = 0, j = orderLength; i < j; ++i){
ids[i] = Long.parseLong(orderIdArray[i]);
}
return ids;
}
可以重构成:
protected long[] getOrderIdLongs(String orderIds){
return toLongs(orderIds);
}
4.7 toBigDecimal(Object)
将 toBeConvertedValue 转换成 java.math.BigDecimal.
示例:
ConvertUtil.toBigDecimal(null) = null
ConvertUtil.toBigDecimal("aaaa") = null
ConvertUtil.toBigDecimal(8) = BigDecimal.valueOf(8)
ConvertUtil.toBigDecimal("8") = BigDecimal.valueOf(8)
ConvertUtil.toBigDecimal(new BigDecimal("8")) = BigDecimal.valueOf(8)
如果传入的参数 toBeConvertedValue 是 数组,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) L227:
ConvertUtil.toBigDecimal(new String[] { "1", "2", "3" }) = BigDecimal.valueOf(1)
如果传入的参数 toBeConvertedValue 是 集合,那么取第一个元素进行转换,参见 AbstractConverter.convertArray(Object) Line234:
ConvertUtil.toBigDecimal(toList("1", "2")) = BigDecimal.valueOf(1)
java.lang.Double 转成 java.math.BigDecimal注意点:
推荐使用 BigDecimal.valueOf(double),不建议使用 new BigDecimal(double),参见 JDK API
new BigDecimal(0.1) ====> 0.1000000000000000055511151231257827021181583404541015625
BigDecimal.valueOf(0.1) ====> 0.1
本方法底层调用的是 NumberConverter#toNumber(Class, Class, Number),正确的处理了 java.lang.Double 转成 java.math.BigDecimal
5.转成字符串
方法
Description
toString(Object)
把对象 toBeConvertedValue 转换成字符串.
toString(Object[], ToStringConfig)
将数组 arrays 通过ToStringConfig 拼接成字符串.
toString(Collection>, ToStringConfig)
将集合 collection 使用拼接配置 toStringConfig 拼接成字符串.
5.1 toString(Object)
把对象 toBeConvertedValue 转换成字符串.
示例:
ConvertUtil.toString(1) = "1"
ConvertUtil.toString(toBigDecimal(1.0)) = "1.0"
ConvertUtil.toString(toLong(8L)) = "8"
注意:
该方法不适合 list转换成字符串,比如:
ConvertUtil.toString(toList("张飞", "关羽", "", "赵云")) = "张飞"
,请使用 toString(Collection, ToStringConfig)
该方法也不适合 array 转换成字符串,比如:
Integer[] int1 = { 2, null, 1, null };
LOGGER.debug(ConvertUtil.toString(int1)); = 2
**请使用 toString(Object [], ToStringConfig) **
对于 Array 转成 String:
参见 ArrayConverter#convertToString(Object)
在转换的过程中,如果发现object是数组,将使用 Array#get(Object, int)来获得数据,
如果发现不是数组,将会将object转成集合 ArrayConverter#convertToCollection(Class, Object)再转成迭代器 Collection.iterator()
在将object转成集合 ArrayConverter#convertToCollection(Class, Object)时候,有以下规则:
The string is expected to be a comma-separated list of values.
字符串可以被'{' and '}'分隔符包裹.
去除前后空白.
Elements in the list may be delimited by single or double quotes. Within a quoted elements, the normal Java escape sequences are valid.
**默认: **
字段
说明
int defaultSize
指定构建的默认数组的大小 or if less than zero indicates that a null default value should be used.
char delimiter = ','
分隔符,转成的string中的元素分隔符
char[] allowedChars = new char[] {'.', '-'}
用于java.io.StreamTokenizer分隔字符串
boolean onlyFirstToString = true;
只转第一个值
5.2 toString(Object[], ToStringConfig)
将数组 arrays 通过 ToStringConfig 拼接成字符串.
支持包装类型以及原始类型,比如 Integer [] arrays 或者 int []arrays
示例:
ConvertUtil.toString(toArray("a","b"),new ToStringConfig()) = "a,b"
ToStringConfig toStringConfig=new ToStringConfig(",");
toStringConfig.setIsJoinNullOrEmpty(false);
ConvertUtil.toString(toArray("a","b",null),new ToStringConfig()) = "a,b"
int[] ints = { 2, 1 };
ConvertUtil.toString(toArray(ints),new ToStringConfig()) = "2,1"
关于 default ToStringConfig:
如果参数 toStringConfig 是null,则使用默认的规则:
连接符使用ToStringConfig.DEFAULT_CONNECTOR
拼接null或者empty元素
如果元素是null,使用StringUtils.EMPTY替代拼接
最后一个元素后面不拼接拼接符
5.3 toString(Collection>, ToStringConfig)
将集合 collection 使用拼接配置 toStringConfig 拼接成字符串.
示例:
List list = new ArrayList<>();
list.add("feilong");
list.add("");
list.add("xinge");
ToStringConfig toStringConfig = new ToStringConfig(",");
toStringConfig.setIsJoinNullOrEmpty(false);
ConvertUtil.toString(list,toStringConfig);
**输出: **
feilong,xinge
你还可以使用这个方法来将集合换行输出,比如:
List list = toList("飞龙", "小金", "四金", "金金金金");
ToStringConfig toStringConfig = new ToStringConfig(SystemUtils.LINE_SEPARATOR);
LOGGER.debug(ConvertUtil.toString(list, toStringConfig));
**输出: **
飞龙
小金
四金
金金金金
关于 default ToStringConfig:
如果参数 toStringConfig 是null,则使用默认的规则:
连接符使用ToStringConfig.DEFAULT_CONNECTOR
拼接null或者empty元素
如果元素是null,使用StringUtils.EMPTY替代拼接
最后一个元素后面不拼接拼接符
6.转成字符串数组
方法
Description
toStrings(Object)
将 toBeConvertedValue 转成String数组.
将 toBeConvertedValue 转成String数组.
说明:
该方法很适合将 非字符串数组的数组 转换成 字符串数组,比如
URL[] urls = {
URLUtil.newURL("http://www.exiaoshuo.com/jinyiyexing0/"),
URLUtil.newURL("http://www.exiaoshuo.com/jinyiyexing1/"),
URLUtil.newURL("http://www.exiaoshuo.com/jinyiyexing2/"),
null };
LOGGER.debug(JsonUtil.format(ConvertUtil.toStrings(urls)));
返回:
[
"http://www.exiaoshuo.com/jinyiyexing0/",
"http://www.exiaoshuo.com/jinyiyexing1/",
"http://www.exiaoshuo.com/jinyiyexing2/",
null
]
还有诸如 Integer[]转成 String[]
ConvertUtil.toStrings(new Integer[] { 1, 2, 5 }) = [ "1", "2", "5" ]
也可以将字符串 解析成数组 in the Java language into a List individual Strings for each element, 根据以下规则:
The string is expected to be a comma-separated list of values.
自动去除开头的 '{' 和 结束的'}'.
每个元素前后的空格将会去除.
Elements in the list may be delimited by single or double quotes. Within a quoted elements, the normal Java escape sequences are valid.
**示例: **
ConvertUtil.toStrings("{5,4, 8,2;8 9_5@3`a}"); = ["5","4","8","2","8","9","5","3","a"]
7.其他转换
方法
Description
toEnumeration(Collection)
将集合 collection 转成Enumeration.
toIterator(Object)
将 toBeConvertedValue转成Iterator类型.
toLocale(Object)
将对象转成 Locale.
toProperties(Map)
将map转成 Properties.
convert(Object, Class)
将 toBeConvertedValue 转成指定 targetType 类型的对象.
7.1 toEnumeration(Collection)
将集合 collection 转成Enumeration.
说明:
一般情况,你可能不需要这个方法,不过在一些API的时候,需要Enumeration参数,此时调用这个方法来进行转换会比较方便
示例:
ConvertUtil.toEnumeration(null) = Collections.emptyEnumeration()
7.2 toIterator(Object)
将 toBeConvertedValue 转成Iterator类型.
示例:
// null
toIterator(null) = null
//PrimitiveArray
int[] i2 = { 1, 2 };
Iterator iterator = toIterator(i2);
//逗号分隔的字符串
Iterator iterator = toIterator("1,2");
//collection
List list = new ArrayList<>();
list.add("aaaa");
list.add("nnnnn");
Iterator iterator = toIterator(list);
//Enumeration
Enumeration enumeration = new StringTokenizer("this is a test");
Iterator iterator = toIterator(enumeration);
支持以下类型:
逗号分隔的字符串,先使用ConvertUtil.toStrings(Object) 转成数组
数组(包括 包装类型数组 以及 原始类型数组)
如果是java.util.Map,将 java.util.Map.values() 转成java.util.Iterator
java.util.Collection
java.util.Iterator
java.util.Enumeration
java.util.Dictionary
org.w3c.dom.Node
org.w3c.dom.NodeList
7.3 toLocale(Object)
将对象转成 Locale.
示例:
ConvertUtil.toLocale(null) = null
ConvertUtil.toLocale("zh_CN") = Locale.CHINA
7.4 toProperties(Map)
将map转成 Properties.
说明:
由于 Properties 只能保存非空的key和value,因此如果map 有key或者value是null,将会抛出 NullPointerException
示例:
Map map = toMap("name", "feilong");
Properties properties = ConvertUtil.toProperties(map);
LOGGER.debug(JsonUtil.format(properties));
返回:
{"name": "feilong"}
7.5 convert(Object, Class)
将 toBeConvertedValue 转成指定 targetType 类型的对象.
示例:
ConvertUtil.convert("1", Integer.class) =1
ConvertUtil.convert("", Integer.class) =0
ConvertUtil.convert("1", Long.class) =1
此外,该方法特别适合数组类型的转换,比如 Type[] 转成 Class []:
原来的写法:
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
int length = actualTypeArguments.length;
Class>[] klasses = new Class>[length];
for (int i = 0, j = length; i < j; ++i){
klasses[i] = (Class>) actualTypeArguments[i];
}
return klasses;
现在可以重构成:
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
return convert(actualTypeArguments, Class[].class);
注意:
如果targetType的转换器没有注册,那么传入的value原样返回,
比如ConvertUtil.convert("zh_CN", Locale.class) 由于找不到converter,那么返回"zh_CN".
如果转换不了,会使用默认值
如果传的 toBeConvertedValue 是 toBeConvertedValue.getClass().isArray() 或者 Collection
如果 targetType 不是数组
那么会取第一个元素进行转换,
参见AbstractConverter.convert(Class, Object),调用的 AbstractConverter.convertArray(Object) 方法
如果 targetType 是数组
参见 ArrayConverter#convertToType(Class, Object) 会基于targetType 构造一个数组对象,大小长度就是 toBeConvertedValue的大小或者长度, 然后迭代 toBeConvertedValue 依次进行转换