java 字符串转龙,全能类型转换器 ConvertUtil

在我们日常开发工作中, 类型转换是跑不掉的,下面特别封装十分常用的方法

主要由下面几个部分组成:

04f40d2ae20e588b7f8f056a11f4828c.png

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 依次进行转换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值