All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.core.bean.ConvertUtil Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * 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.bean;

import static com.feilong.core.Validator.isNullOrEmpty;
import static com.feilong.core.lang.ObjectUtil.defaultIfNull;
import static com.feilong.core.lang.StringUtil.EMPTY;
import static com.feilong.core.util.MapUtil.newLinkedHashMap;
import static com.feilong.core.util.SortUtil.sortMapByKeyAsc;
import static java.util.Collections.emptyMap;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.collections4.Transformer;

import com.feilong.core.Validate;
import com.feilong.core.lang.ArrayUtil;
import com.feilong.core.lang.StringUtil;
import com.feilong.core.util.SortUtil;
import com.feilong.core.util.transformer.SimpleClassTransformer;
import com.feilong.lib.beanutils.ConvertUtils;
import com.feilong.lib.beanutils.ConvertUtilsBean;
import com.feilong.lib.beanutils.Converter;
import com.feilong.lib.beanutils.converters.ArrayConverter;
import com.feilong.lib.beanutils.converters.BigDecimalConverter;
import com.feilong.lib.beanutils.converters.BigIntegerConverter;
import com.feilong.lib.beanutils.converters.BooleanConverter;
import com.feilong.lib.beanutils.converters.ByteConverter;
import com.feilong.lib.beanutils.converters.CharacterConverter;
import com.feilong.lib.beanutils.converters.DoubleConverter;
import com.feilong.lib.beanutils.converters.FloatConverter;
import com.feilong.lib.beanutils.converters.IntegerConverter;
import com.feilong.lib.beanutils.converters.LongConverter;
import com.feilong.lib.beanutils.converters.NumberConverter;
import com.feilong.lib.beanutils.converters.ShortConverter;
import com.feilong.lib.beanutils.converters.StringConverter;
import com.feilong.lib.beanutils.locale.converters.DateLocaleConverter;
import com.feilong.lib.collection4.EnumerationUtils;
import com.feilong.lib.collection4.IteratorUtils;
import com.feilong.lib.collection4.MapUtils;
import com.feilong.lib.collection4.iterators.EnumerationIterator;
import com.feilong.lib.lang3.ArrayUtils;
import com.feilong.lib.lang3.LocaleUtils;
import com.feilong.lib.lang3.StringUtils;
import com.feilong.lib.lang3.tuple.Pair;

/**
 * 常用类型转换处理.
 * 
 * 

关于类型转换:

* *
*
    *
  • {@link ConvertUtilsBean#registerPrimitives(boolean) registerPrimitives(boolean throwException)}
  • *
  • {@link ConvertUtilsBean#registerStandard(boolean,boolean) registerStandard(boolean throwException, boolean defaultNull);}
  • *
  • {@link ConvertUtilsBean#registerOther(boolean) registerOther(boolean throwException);}
  • *
  • {@link ConvertUtilsBean#registerArrays(boolean,int) registerArrays(boolean throwException, int defaultArraySize);}
  • *
*
* *

{@link ConvertUtils} 几个方法的区别:

* *
* * * * * * * * * * * * * * * * * * * * * * * * * * *
方法说明
{@link ConvertUtils#convert(Object)}将指定的value转成string.
* 如果value是array,将会返回数组第一个元素转成string.
* 将会使用注册的 java.lang.String{@link Converter},
* 允许应用定制 Object{@code ->}String conversions(默认使用简单的使用 toString())
* see {@link ConvertUtilsBean#convert(Object)}
{@link ConvertUtils#convert(String, Class)}将String value转成 指定Class 类型的对象 (如果可能),否则返回string.
* see {@link ConvertUtilsBean#convert(String, Class)}
{@link ConvertUtils#convert(String[], Class)}将数组转成指定class类型的对象.
* 如果指定的Class类型是数组类型,那么返回值的类型将是数组的类型.否则将会构造一个指定类型的数组返回.
* see {@link ConvertUtilsBean#convert(String[], Class)}
* see {@link #toArray(String[], Class)}
{@link ConvertUtils#convert(Object, Class)}将value转成指定Class类型的对象,如果Class的转换器没有注册,那么传入的value原样返回.
* see {@link ConvertUtilsBean#convert(Object, Class)}
* see {@link #convert(Object, Class)}
*
* *

* standard {@link Converter} instances are provided for all of the following destination Classes: *

* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
字段说明
{@link java.math.BigDecimal}no default value
{@link java.math.BigInteger}no default value
boolean and {@link java.lang.Boolean}default to false
byte and {@link java.lang.Byte}default to zero
char and {@link java.lang.Character}default to a space
{@link java.lang.Class}no default value
double and {@link java.lang.Double}default to zero
float and {@link java.lang.Float}default to zero
int and {@link java.lang.Integer}default to zero
long and {@link java.lang.Long}default to zero
short and {@link java.lang.Short}default to zero
{@link java.lang.String}default to null
{@link java.io.File}no default value
{@link java.net.URL}no default value
{@link java.sql.Date}no default value
{@link java.sql.Time}no default value
{@link java.sql.Timestamp}no default value
*
* * @author feilong * @see com.feilong.lib.beanutils.ConvertUtils * @see com.feilong.lib.beanutils.converters.AbstractConverter#handleMissing(Class) * @see com.feilong.lib.beanutils.locale.LocaleConvertUtils * @since 1.3.0 */ public final class ConvertUtil{ /** Don't let anyone instantiate this class. */ private ConvertUtil(){ //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化. //see 《Effective Java》 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } //--------------------------------------------------------------- static{ //初始化注册器. ConvertUtil.registerStandardDefaultNull(); } //--------------------------------------------------------------- /** * Register standard default null. * * @see ConvertUtilsBean#registerPrimitives(boolean) registerPrimitives(boolean throwException) * @see ConvertUtilsBean#registerStandard(boolean,boolean) registerStandard(boolean throwException, boolean defaultNull) * @see ConvertUtilsBean#registerOther(boolean) registerOther(boolean throwException) * @see ConvertUtilsBean#registerArrays(boolean,int) registerArrays(boolean throwException, int defaultArraySize) * @see ConvertUtilsBean#deregister(Class) ConvertUtilsBean.deregister(Class) * @since 1.11.2 */ public static void registerStandardDefaultNull(){ ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class); ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class); ConvertUtils.register(new BooleanConverter(null), Boolean.class); ConvertUtils.register(new ByteConverter(null), Byte.class); ConvertUtils.register(new CharacterConverter(null), Character.class); ConvertUtils.register(new DoubleConverter(null), Double.class); ConvertUtils.register(new FloatConverter(null), Float.class); ConvertUtils.register(new IntegerConverter(null), Integer.class); ConvertUtils.register(new LongConverter(null), Long.class); ConvertUtils.register(new ShortConverter(null), Short.class); ConvertUtils.register(new StringConverter(null), String.class); } //--------------------------------------------------------------- /** * Register simple date locale converter. * * @param pattern * the pattern * @since 1.11.2 */ public static void registerSimpleDateLocaleConverter(String pattern){ DateLocaleConverter dateLocaleConverter = new DateLocaleConverter(null, Locale.getDefault(), pattern); ConvertUtils.register(dateLocaleConverter, Date.class); } //---------------------toBoolean------------------------------------------ /** * 将 toBeConvertedValue 转换成 {@link Boolean}类型. * *

示例:

* *
* *
     * 
     * ConvertUtil.toBoolean(null)      =   null
     * 
     * ConvertUtil.toBoolean(1L)        =   true
     * ConvertUtil.toBoolean("1")       =   true
     * ConvertUtil.toBoolean("9")       =   null
     * ConvertUtil.toBoolean("1,2,3")   =   null
     * 
* *
* *

逻辑及规则:

* *
* *
    *
  • 如果 "true", "yes", "y", "on", "1" (忽视大小写), 返回 true
  • *
  • 如果 "false", "no", "n", "off", "0" (忽视大小写), 返回 false
  • *
  • 其他抛出 conversionException, 但是在 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#handleError(Class, Object, Throwable) handleError(Class, Object, * Throwable)} 方法里面返回默认值 是 null *
* *

* 你也可以调用 {@link com.feilong.lib.beanutils.converters.BooleanConverter#BooleanConverter(String[], String[], Object) * BooleanConverter(String[], String[], Object)} 设置 trueStrings 和 falseStrings *

*
* *

和 {@link Boolean#parseBoolean(String)}的区别:

* *
*

* {@link Boolean#parseBoolean(String)},仅当 (String != null) 并且 String.equalsIgnoreCase("true") 返回 true *

*
* * @param toBeConvertedValue * object * @return 如果 toBeConvertedValue 是null,返回null
* @see #convert(Object, Class) * @see com.feilong.lib.beanutils.converters.BooleanConverter * @see com.feilong.lib.lang3.BooleanUtils * @see java.lang.Boolean#parseBoolean(String) */ public static Boolean toBoolean(Object toBeConvertedValue){ return new BooleanConverter(null).convert(Boolean.class, toBeConvertedValue); } //----------------------toInteger----------------------------------------- /** * 将 toBeConvertedValue 转换成 {@link Integer}类型. * *

示例:

* *
* *
     * 
     * ConvertUtil.toInteger(null)                  = null
     * ConvertUtil.toInteger("aaaa")                = null
     * ConvertUtil.toInteger(8L)                    = 8
     * ConvertUtil.toInteger("8")                   = 8
     * ConvertUtil.toInteger(new BigDecimal("8"))   = 8
     * 
* *

* 如果传入的参数 toBeConvertedValue数组,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#convertArray(Object)} L227: *

* *
     * ConvertUtil.toInteger(new String[] { "1", "2", "3" }) = 1
     * 
* *

* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.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;
     * }
     * 
* *

* 当然对于这种场景,最快捷的:调用支持默认值的 {@link #toInteger(Object, Integer)} 方法 *

* *
     * 
     * public static Integer getCurrentPageNo(HttpServletRequest request,String pageParamName){
     *     String pageNoString = RequestUtil.getParameter(request, pageParamName);
     *     return ConvertUtil.toInteger(pageNoString, 1);
     * }
     * 
* *
* * @param toBeConvertedValue * 值 * @return 如果 toBeConvertedValue 是null,返回 null
* 如果传入的参数 toBeConvertedValue数组,那么取第一个元素进行转换
* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换
* 如果找不到转换器或者转换的时候出现了异常,返回 null * @see com.feilong.lib.beanutils.converters.IntegerConverter * @see com.feilong.lib.lang3.math.NumberUtils#toInt(String) * @see #toInteger(Object, Integer) */ public static Integer toInteger(Object toBeConvertedValue){ return toInteger(toBeConvertedValue, null); } /** * 将 toBeConvertedValue 转换成 {@link 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数组,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#convertArray(Object)} L227: *

* *
     * ConvertUtil.toInteger(new String[] { "1", "2", "3" }, 8) = 1
     * 
* *

* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.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);
     * }
     * 
* *
* * @param toBeConvertedValue * 值 * @param defaultValue * 默认值 * @return 如果 toBeConvertedValue 是null,返回 defaultValue
* 如果传入的参数 toBeConvertedValue数组,那么取第一个元素进行转换
* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换
* 如果找不到转换器或者转换的时候出现了异常,返回 defaultValue * @see com.feilong.lib.beanutils.converters.IntegerConverter * @since 1.6.1 */ public static Integer toInteger(Object toBeConvertedValue,Integer defaultValue){ return new IntegerConverter(defaultValue).convert(Integer.class, toBeConvertedValue); } //------------------------toLong--------------------------------------- /** * 将 toBeConvertedValue 转换成 {@link Long}类型. * *

示例:

* *
* *
     * ConvertUtil.toLong(null)                     = null
     * ConvertUtil.toLong("aaaa")                   = null
     * ConvertUtil.toLong(8)                        = 8L
     * ConvertUtil.toLong("8")                      = 8L
     * ConvertUtil.toLong(new BigDecimal("8"))      = 8L
     * 
* *

* 如果传入的参数 toBeConvertedValue数组,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#convertArray(Object)} L227: *

* *
     * ConvertUtil.toLong(new String[] { "1", "2", "3" }) = 1L
     * 
* *

* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#convertArray(Object)} Line234: *

* *
     * ConvertUtil.toLong(toList("1", "2")) = 1L
     * 
* *
* * @param toBeConvertedValue * 包含数字的对象. * @return 如果 toBeConvertedValue 是null,返回 null
* 如果传入的参数 toBeConvertedValue数组,那么取第一个元素进行转换
* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换
* 如果找不到转换器或者转换的时候出现了异常,返回 null * @see #convert(Object, Class) * @see com.feilong.lib.beanutils.converters.LongConverter * @see com.feilong.lib.lang3.math.NumberUtils#toLong(String) */ public static Long toLong(Object toBeConvertedValue){ return new LongConverter(null).convert(Long.class, toBeConvertedValue); } //------------------------toBigDecimal--------------------------------------- /** * 将 toBeConvertedValue 转换成 {@link 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数组,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#convertArray(Object)} L227: *

* *
     * ConvertUtil.toBigDecimal(new String[] { "1", "2", "3" }) = BigDecimal.valueOf(1)
     * 
* *

* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换,参见 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#convertArray(Object)} Line234: *

* *
     * ConvertUtil.toBigDecimal(toList("1", "2")) = BigDecimal.valueOf(1)
     * 
* *
* *

{@link java.lang.Double} 转成 {@link java.math.BigDecimal}注意点:

* *
* *

* 推荐使用 {@link BigDecimal#valueOf(double)},不建议使用 new BigDecimal(double),参见 JDK API
*

* *
    *
  • {@code new BigDecimal(0.1) ====> 0.1000000000000000055511151231257827021181583404541015625}
  • *
  • {@code BigDecimal.valueOf(0.1) ====> 0.1}
  • *
* *

* 本方法底层调用的是 {@link NumberConverter#toNumber(Class, Class, Number) * NumberConverter#toNumber(Class, Class, Number)},正确的处理了 {@link java.lang.Double} 转成 {@link java.math.BigDecimal} *

*
* * @param toBeConvertedValue * 值 * @return 如果 toBeConvertedValue 是null,返回 null
* 如果传入的参数 toBeConvertedValue数组,那么取第一个元素进行转换
* 如果传入的参数 toBeConvertedValue集合,那么取第一个元素进行转换
* 如果找不到转换器或者转换的时候出现了异常,返回 null * @see #convert(Object, Class) * @see com.feilong.lib.beanutils.converters.NumberConverter#toNumber(Class, Class, Number) * @see com.feilong.lib.beanutils.converters.BigDecimalConverter */ public static BigDecimal toBigDecimal(Object toBeConvertedValue){ return new BigDecimalConverter(null).convert(BigDecimal.class, toBeConvertedValue); } //--------------------------------------------------------------- //数组 /** * 将 toBeConvertedValue 转成{@link Integer} 数组. * *

说明:

*
* *

* 核心实现,参见 {@link ArrayConverter#convertToType(Class, Object)} *

* *
*
如果参数 toBeConvertedValue数组 或者 {@link Collection}
* *
*

* 参见{@link com.feilong.lib.beanutils.converters.ArrayConverter#convertToType(Class, Object) * 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不是数组也不是{@link Collection}
* *
*

* 那么首先会调用 {@link ArrayConverter#convertToCollection(Class, Object)} 将 toBeConvertedValue转成集合,转换逻辑参见 * {@link ArrayConverter#convertToCollection(Class, Object)}: *

* *
    *
  1. 如果 toBeConvertedValue是{@link Number}, {@link Boolean} 或者 {@link java.util.Date} ,那么构造只有一个 * toBeConvertedValue 元素的 List返回.
  2. *
  3. 其他类型将转成字符串,然后调用 {@link 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.
    • *
    * *
  4. *
* *

* 得到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的时候,会调用 * {@link com.feilong.lib.beanutils.converters.NumberConverter#convertToType(Class, Object)},具体的规则是: *

* *
* *
*
1.如果 元素是 Number类型
*
那么会调用 {@link com.feilong.lib.beanutils.converters.NumberConverter#toNumber(Class, Class, Number)}
* *
2.如果 元素是 Boolean类型
*
那么 true被转成1,false 转成 0
* *
3.其他情况
*
将元素转成字符串,并trim,再进行转换
* *
4.元素是null的情况
*
如果有元素是null,那么会调用 {@link com.feilong.lib.beanutils.converters.AbstractConverter#convert(Class, Object)},会调用 * {@link com.feilong.lib.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" })                         = new Integer[] {}
     * 
* *
* *
* * @param toBeConvertedValue * 需要被转换的值 * @return 如果 toBeConvertedValue 是null,返回 null
* @see #convert(Object, Class) * @see com.feilong.lib.beanutils.converters.ArrayConverter */ public static Integer[] toIntegers(Object toBeConvertedValue){ return convert(toBeConvertedValue, Integer[].class); } /** * 将 toBeConvertedValue 转成Long 数组. * *

说明:

*
* *

* 核心实现,参见 {@link ArrayConverter#convertToType(Class, Object)} *

* *
*
如果参数 toBeConvertedValue数组 或者 {@link Collection}
* *
*

* 参见{@link com.feilong.lib.beanutils.converters.ArrayConverter#convertToType(Class, Object) * 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不是数组也不是{@link Collection}
* *
*

* 那么首先会调用 {@link ArrayConverter#convertToCollection(Class, Object)} 将 toBeConvertedValue转成集合,转换逻辑参见 * {@link ArrayConverter#convertToCollection(Class, Object)}: *

* *
    *
  1. 如果 toBeConvertedValue是{@link Number}, {@link Boolean} 或者 {@link java.util.Date} ,那么构造只有一个 * toBeConvertedValue 元素的 List返回.
  2. *
  3. 其他类型将转成字符串,然后调用 {@link 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.
    • *
    * *
  4. *
* *

* 得到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的时候,会调用 * {@link com.feilong.lib.beanutils.converters.NumberConverter#convertToType(Class, Object)},具体的规则是: *

* *
* *
*
1.如果 元素是 Number类型
*
那么会调用 {@link com.feilong.lib.beanutils.converters.NumberConverter#toNumber(Class, Class, Number)}
* *
2.如果 元素是 Boolean类型
*
那么 true被转成1L,false 转成 0L
* *
3.其他情况
*
将元素转成字符串,并trim,再进行转换
* *
4.元素是null的情况
*
如果有元素是null,那么会调用 {@link com.feilong.lib.beanutils.converters.AbstractConverter#convert(Class, Object)},会调用 * {@link com.feilong.lib.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 {@code <} j; ++i){
     *         ids[i] = Long.parseLong(orderIdArray[i]);
     *     }
     *     return ids;
     * }
     * 
     * 
* * 可以重构成: * *
     * 
     * protected long[] getOrderIdLongs(String orderIds){
     *     return toLongs(orderIds);
     * }
     * 
* *
* * @param toBeConvertedValue * the to be converted value * @return 如果 toBeConvertedValue 是null,返回 null
* @see com.feilong.lib.beanutils.ConvertUtils#convert(Object, Class) * @see com.feilong.lib.beanutils.converters.ArrayConverter * @see #convert(Object, Class) */ public static Long[] toLongs(Object toBeConvertedValue){ return convert(toBeConvertedValue, Long[].class); } //--------------------------------------------------------------- /** * 把对象 toBeConvertedValue 转换成字符串. * *

示例:

* *
* *
     * ConvertUtil.toString(1)                  =   "1"
     * ConvertUtil.toString(toLong(8L))         =   "8"
     * ConvertUtil.toString(toBigDecimal(1.0))  =   "1.00"
     * ConvertUtil.toString(new Double(1.0))  =   "1.00"
     * ConvertUtil.toString(new Float(1.0))  =   "1.00"
     * 
     * ConvertUtil.toString(toList("张飞", "关羽", "", "赵云"))  =   "张飞,关羽,,赵云"
     * ConvertUtil.toString(toArray("张飞", "关羽", "", "赵云"))  =   "张飞,关羽,,赵云"
     * ConvertUtil.toString(toArray(null, "关羽", "", "赵云"))  =   ",关羽,,赵云"
     * 
* *
* * @param toBeConvertedValue * 参数值 * @return 如果 toBeConvertedValue 是null,返回 null
* 如果 toBeConvertedValue 是 {@link CharSequence},直接 toString返回
* 如果 toBeConvertedValue 是 数组,那么调用 {@link ConvertUtil#toString(Object[], String)}
* 如果 toBeConvertedValue 是 {@link Collection},那么调用 {@link ConvertUtil#toString(Object[], String)}
* 如果 toBeConvertedValue 是 {@link Date},那么返回 {@link com.feilong.core.DatePattern#COMMON_DATE_AND_TIME} 格式字符串
* 如果 toBeConvertedValue 是 {@link BigDecimal}或者是{@link Float}或者是 {@link Double},那么返回 * {@link com.feilong.core.NumberPattern#TWO_DECIMAL_POINTS} 2 位小数点格式字符串
* 其他调用 {@link com.feilong.core.bean.ConvertUtil#convert(Object, Class)} * @see com.feilong.lib.beanutils.converters.ArrayConverter#convertToString(Object) * @see com.feilong.lib.beanutils.ConvertUtils#convert(Object) * @see com.feilong.lib.beanutils.ConvertUtilsBean#convert(Object) * @see com.feilong.lib.beanutils.converters.StringConverter * * @see java.util.Arrays#toString(Object[]) * @since 1.14.0 call {@link com.feilong.core.bean.ToStringHandler#toStringValue(Object)} */ public static String toString(Object toBeConvertedValue){ return ToStringHandler.toStringValue(toBeConvertedValue); } //--------------------------------------------------------------- /** * 将集合 collection 使用拼接 connector 拼接成字符串. * *

示例:

* *
* *
     * List{@code } list = com.feilong.core.bean.ConvertUtil.toList("feilong", "", "xinge");
     * ConvertUtil.toString(list,",");
     * 
* * 输出: * *
     * feilong,,xinge
     * 
* *
* * 你还可以使用这个方法来将集合换行输出,比如: * *
     * List{@code } list = toList("飞龙", "小金", "四金", "金金金金");
     * 
     * LOGGER.debug(ConvertUtil.toString(list, System.lineSeparator()));
     * 
* * 输出: * *
     * 飞龙
     * 小金
     * 四金
     * 金金金金
     * 
* *
* *

说明

*
* *
    *
  1. 如果有元素是null,使用{@link StringUtils#EMPTY}替代拼接
  2. *
  3. 最后一个元素后面不拼接拼接符
  4. *
*
* * @param collection * 集合,建议元素泛型不要使用自定义的对象(比如UserCommand等),因为这个方法是迭代collection,拿每个元素的字符串格式 进行拼接 * @param connector * the connector * @return 如果 collection 是null或者empty,返回 {@link StringUtils#EMPTY}
* @see "org.springframework.util.StringUtils#collectionToDelimitedString(Collection, String, String, String)" * @see "org.apache.commons.collections4.IteratorUtils#toString(Iterator)" * @see com.feilong.lib.lang3.StringUtils#join(Iterable, String) * @since 1.11.0 */ public static String toString(final Collection collection,String connector){ return isNullOrEmpty(collection) ? EMPTY : // toString(collection.toArray(), new ToStringConfig(connector)); } /** * 将数组 arrays 通过 connector 拼接成字符串. * *

示例:

* *
* *
     * ConvertUtil.toString(null,",")               =   ""
     * ConvertUtil.toString(toArray(),",")          =   ""
     * 
     * ConvertUtil.toString(toArray("a","b"),",")   =   "a,b"
     * 
     * Integer[] array3 = { 2, null, 1, null };
     * ConvertUtil.toString(array3,",")             =   "2,,1,"
     * 
* *
* *

如果原始类型数组需要转换:

*
* *

* 需要先使用下列的方式先转成包装类型数组 *

* *
    *
  1. {@link ArrayUtils#toObject(boolean[])}
  2. *
  3. {@link ArrayUtils#toObject(byte[])}
  4. *
  5. {@link ArrayUtils#toObject(char[])}
  6. *
  7. {@link ArrayUtils#toObject(double[])}
  8. *
  9. {@link ArrayUtils#toObject(float[])}
  10. *
  11. {@link ArrayUtils#toObject(int[])}
  12. *
  13. {@link ArrayUtils#toObject(long[])}
  14. *
  15. {@link ArrayUtils#toObject(short[])}
  16. *
*
* *

说明

*
* *
    *
  1. 如果有元素是null,使用{@link StringUtils#EMPTY}替代拼接
  2. *
  3. 最后一个元素后面不拼接拼接符
  4. *
*
* * @param arrays * 支持包装类型,不直接支持原始类型 * @param connector * the connector * @return 如果 arrays 是null 或者Empty,返回 {@link StringUtils#EMPTY}
* @see com.feilong.lib.lang3.builder.ToStringStyle * @see com.feilong.lib.lang3.StringUtils#join(Object[], String) * @since 1.11.0 */ public static String toString(Object[] arrays,String connector){ return isNullOrEmpty(arrays) ? EMPTY : toString(arrays, new ToStringConfig(connector)); } //--------------------------------------------------------------- // toString use ToStringConfig /** * 将集合 collection 使用拼接配置 toStringConfig 拼接成字符串. * *

示例:

* *
* *
     * List{@code } list = new ArrayList{@code <>}();
     * list.add("feilong");
     * list.add("");
     * list.add("xinge");
     * 
     * ToStringConfig toStringConfig = new ToStringConfig(",");
     * toStringConfig.setIsJoinNullOrEmpty(false);
     * 
     * ConvertUtil.toString(list,toStringConfig);
     * 
* * 输出: * *
     * feilong,xinge
     * 
* *
* * 你还可以使用这个方法来将集合换行输出,比如: * *
     * List{@code } list = toList("飞龙", "小金", "四金", "金金金金");
     * 
     * ToStringConfig toStringConfig = new ToStringConfig(System.lineSeparator());
     * LOGGER.debug(ConvertUtil.toString(list, toStringConfig));
     * 
* * 输出: * *
     * 飞龙
     * 小金
     * 四金
     * 金金金金
     * 
* *
* *

关于 default {@link ToStringConfig}:

*
* *

* 如果参数 toStringConfig 是null,则使用默认的规则:
*

* *
    *
  1. 连接符使用{@link ToStringConfig#DEFAULT_CONNECTOR}
  2. *
  3. 拼接null或者empty元素
  4. *
  5. 如果元素是null,使用{@link StringUtils#EMPTY}替代拼接
  6. *
  7. 最后一个元素后面不拼接拼接符
  8. *
*
* *

关于 {@link ToStringConfig} prefix(since 1.12.9):

*
* *

* 如果你需要在拼接每个元素的时候,给每个元素加上前缀, 比如 solr 查询, 运营人员配置了一些商品code ,1533312,1533292,1785442, 此时你需要生成 * code:1533312 OR code:1533292 OR code:1785442 字符串去solr 中查询 *

* *

* 此时你可以这么调用 *

* *
     * 
     * String configItemCodes = "1533312,1533292,1785442";
     * String[] tokenizeToStringArray = StringUtil.tokenizeToStringArray(configItemCodes, ",");
     * List{@code } list = toList(tokenizeToStringArray);
     * ToStringConfig toStringConfig = new ToStringConfig(" OR ", false, "code:");
     * String string = ConvertUtil.toString(list, toStringConfig);
     * 
* * 返回: * *

* code:1533312 OR code:1533292 OR code:1785442 *

* *
* * @param collection * 集合,建议元素泛型不要使用自定义的对象(比如UserCommand等),因为这个方法是迭代collection,拿每个元素的字符串格式 进行拼接 * @param toStringConfig * 连接字符串 实体 * @return 如果 collection 是null或者empty,返回 {@link StringUtils#EMPTY}
* 如果 toStringConfig 是null,使用默认 {@link ToStringConfig#DEFAULT_CONNECTOR}以及 joinNullOrEmpty 进行连接
* 都不是null,会循环,拼接toStringConfig.getConnector() * @see "org.springframework.util.StringUtils#collectionToDelimitedString(Collection, String, String, String)" * @see "org.apache.commons.collections4.IteratorUtils#toString(Iterator)" * @see com.feilong.lib.lang3.StringUtils#join(Iterable, String) * @since 1.8.4 change param order */ public static String toString(final Collection collection,ToStringConfig toStringConfig){ return isNullOrEmpty(collection) ? EMPTY : toString(collection.toArray(), toStringConfig); } /** * 将数组 arrays 通过{@link ToStringConfig} 拼接成字符串. * *

示例:

* *
* *
     * 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"
     * 
* *
* *

如果原始类型数组需要转换:

*
* *

* 需要先使用下列的方式先转成包装类型数组 *

* *
    *
  1. {@link ArrayUtils#toObject(boolean[])}
  2. *
  3. {@link ArrayUtils#toObject(byte[])}
  4. *
  5. {@link ArrayUtils#toObject(char[])}
  6. *
  7. {@link ArrayUtils#toObject(double[])}
  8. *
  9. {@link ArrayUtils#toObject(float[])}
  10. *
  11. {@link ArrayUtils#toObject(int[])}
  12. *
  13. {@link ArrayUtils#toObject(long[])}
  14. *
  15. {@link ArrayUtils#toObject(short[])}
  16. *
*
* *

关于 default {@link ToStringConfig}:

*
* *

* 如果参数 toStringConfig 是null,则使用默认的规则:
*

* *
    *
  1. 连接符使用{@link ToStringConfig#DEFAULT_CONNECTOR}
  2. *
  3. 拼接null或者empty元素
  4. *
  5. 如果元素是null,使用{@link StringUtils#EMPTY}替代拼接
  6. *
  7. 最后一个元素后面不拼接拼接符
  8. *
*
* *

关于 {@link ToStringConfig} prefix(since 1.12.9):

*
* *

* 如果你需要在拼接每个元素的时候,给每个元素加上前缀, 比如 solr 查询, 运营人员配置了一些商品code ,1533312,1533292,1785442, 此时你需要生成 * code:1533312 OR code:1533292 OR code:1785442 字符串去solr 中查询 *

* *

* 此时你可以这么调用 *

* *
     * 
     * String configItemCodes = "1533312,1533292,1785442";
     * String{@code []} tokenizeToStringArray = StringUtil.tokenizeToStringArray(configItemCodes, ",");
     * ToStringConfig toStringConfig = new ToStringConfig(" OR ", false, "code:");
     * String string = ConvertUtil.toString(tokenizeToStringArray, toStringConfig);
     * 
* * 返回: * *

* code:1533312 OR code:1533292 OR code:1785442 *

* *
* * @param arrays * 支持包装类型,不直接支持原始类型 * @param toStringConfig * the to string config * @return 如果 arrays 是null 或者Empty,返回 {@link StringUtils#EMPTY}
* 如果 toStringConfig 是null,使用默认 {@link ToStringConfig#DEFAULT_CONNECTOR}以及 joinNullOrEmpty 进行连接
* 否则循环,拼接 {@link ToStringConfig#getConnector()} * @see com.feilong.lib.lang3.builder.ToStringStyle * @see com.feilong.lib.lang3.StringUtils#join(Object[], String) * @see com.feilong.lib.lang3.StringUtils#join(Iterable, String) * @since 1.8.4 change param order */ public static String toString(Object[] arrays,ToStringConfig toStringConfig){ if (isNullOrEmpty(arrays)){ return EMPTY; } //--------------------------------------------------------------- ToStringConfig useToStringConfig = defaultIfNull(toStringConfig, new ToStringConfig()); String connector = useToStringConfig.getConnector(); boolean isJoinNullOrEmpty = useToStringConfig.getIsJoinNullOrEmpty(); String prefix = useToStringConfig.getPrefix(); //--------------------------------------------------------------- StringBuilder sb = new StringBuilder(); for (Object element : arrays){ //如果是null或者empty,但是参数值是不拼接,那么跳过,继续循环 if (isNullOrEmpty(element) && !isJoinNullOrEmpty){ continue; } //--------------------------------------------------------------- //since 1.12.9 support prefix sb.append(defaultIfNull(prefix, EMPTY)); //value转换 //注意:如果value是null,StringBuilder 将拼接 "null" 字符串,详见 java.lang.AbstractStringBuilder#append(String) sb.append(defaultIfNull(element, EMPTY)); //see StringUtils.defaultString(t) //--------------------------------------------------------------- if (null != connector){//注意可能传过来的是换行符,不能使用Validator.isNullOrEmpty来判断 sb.append(connector);//放心大胆的拼接 connector, 不判断是否是最后一个,最后会截取 } } return StringUtil.substringWithoutLast(sb, connector); } //--------------------------------------------------------------- /** * 将集合 collection 转成Enumeration. * *

说明:

*
*
    *
  1. 一般情况,你可能不需要这个方法,不过在一些API的时候,需要Enumeration参数,此时调用这个方法来进行转换会比较方便
  2. *
*
* *

示例:

* *
* *
     * ConvertUtil.toEnumeration(null) = Collections.emptyEnumeration()
     * 
* *
* * @param * the generic type * @param collection * 集合 * @return 如果 collection 是null,返回 {@link Collections#emptyEnumeration()}
* 否则返回{@link Collections#enumeration(Collection)} * @see Collections#enumeration(Collection) * @since 1.4.0 */ public static Enumeration toEnumeration(final Collection collection){ return null == collection ? Collections. emptyEnumeration() : Collections.enumeration(collection); } //--------------------------------------------------------------- //toMap /** * 将 keyvalue 直接转成map. * *

说明:

*
*
    *
  1. 返回是的是 {@link LinkedHashMap}
  2. * *
  3. *

    * 非常适合单key的场景,比如 *

    * *
         * Map{@code } paramMap = newHashMap();
         * paramMap.put("name", "jinxin");
         * request.setParamMap(paramMap);
         * 
    * * 上面的3行代码可以重写成 * *
         * request.setParamMap(toMap("name", "jinxin"));
         * 
    * *

    * 一行代码就搞定了,很简洁,有木有~~ *

    * *
  4. *
*
* *

示例:

* *
* *
     * LOGGER.debug(JsonUtil.format(ConvertUtil.toMap("张飞", "丈八蛇矛")));
     * 
* * 返回: * *
     * {"张飞": "丈八蛇矛"}
     * 
* *
* * *

重构:

* *
*

* 对于以下代码: *

* *
     * private List{@code } loadShopCommandList(){
     *     Map{@code } paraMap = newHashMap();
     *     paraMap.put("orgTypeId", OrgType.ID_SHOP_TYPE);
     * 
     *     return shopCommandDao.findShopListByOrgaTypeId(paraMap);
     * }
     * 
* * 可以重构成: * *
     * private List{@code } loadShopCommandList(){
     *   Map{@code } paraMap = ConvertUtil.toMap("orgTypeId", (Object) OrgType.ID_SHOP_TYPE);
     *     return shopCommandDao.findShopListByOrgaTypeId(paraMap);
     * }
     * 
* *
* * @param * the key type * @param * the value type * @param key * the key * @param value * the value * @return 将 keyvalue 直接转成map * @see com.feilong.lib.lang3.ArrayUtils#toMap(Object[]) * @see java.util.Collections#singletonMap(Object, Object) * @see "com.google.common.collect.ImmutableMap#of(K, V)" * @since 1.7.1 */ public static Map toMap(K key,V value){ Map map = new LinkedHashMap<>();//不设置初始值 ,可能调用再PUT 这样浪费性能 map.put(key, value); return map; } /** * 将 key1value1/key2value2 直接转成map. * *

说明:

*
*
    *
  1. 返回是的是 {@link LinkedHashMap}
  2. * *
  3. *

    * 非常适合2个key的场景,比如 *

    * *
         * Map{@code } paramMap =newHashMap();
         * paramMap.put("name", "jinxin");
         * paramMap.put("age", "18");
         * request.setParamMap(paramMap);
         * 
    * * 上面的3行代码可以重写成 * *
         * request.setParamMap(toMap("name", "jinxin", "age", "18"));
         * 
    * *

    * 一行代码就搞定了,很简洁,有木有~~ *

    * *
  4. *
*
* *

重构:

* *
*

* 对于以下代码: *

* *
     * Map{@code } map = newHashMap();
     * map.put("itemId", itemId);
     * map.put("memberId", memberId);
     * memberFavoritesDao.findMemberFavoritesByMemberIdAndItemId(map);
     * 
* * 可以重构成: * *
     * Map{@code } map = ConvertUtil.toMap("itemId", itemId, "memberId", memberId);
     * memberFavoritesDao.findMemberFavoritesByMemberIdAndItemId(map);
     * 
* *
* * @param * the key type * @param * the value type * @param key1 * the key 1 * @param value1 * the value 1 * @param key2 * the key 2 * @param value2 * the value 2 * @return 将 key1value1/key2value2 直接转成map * @see com.feilong.lib.lang3.ArrayUtils#toMap(Object[]) * @see java.util.Collections#singletonMap(Object, Object) * @see "com.google.common.collect.ImmutableMap#of(K, V)" * @since 1.9.5 */ public static Map toMap(K key1,V value1,K key2,V value2){ Map map = toMap(key1, value1); map.put(key2, value2); return map; } /** * 将 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"
     * }
     * 
* *
* *

说明:

*
*
    *
  1. 返回的map 经过了 {@link SortUtil#sortMapByKeyAsc(Map)}排序处理,方便输出日志
  2. *
*
* *

关于 Properties

* *
*

* Properties 是 Map的实现类 ,其 key和value 是String 类型. *

* *

* 因此Properties 可以强制转换成map *

*
* * @param properties * the properties * @return 如果 properties 是null或者empty,返回 {@link Collections#emptyMap()}
* @see "org.apache.commons.collections4.MapUtils#toProperties(Map)" * @since 1.7.1 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Map toMap(Properties properties){ if (isNullOrEmpty(properties)){ return emptyMap(); } return sortMapByKeyAsc((Map) properties);//为了log方便,使用 treeMap } /** * 将诸如 Map{@code } 类型转成 Map{@code } 类型. * *

说明:

*
*
    *
  1. 适合只是简单的将key value类型转换,而不需要自己再构建Transformer,再去调用 {@link #toMap(Map, Transformer, Transformer)} ,简化操作
  2. *
  3. 返回的是 {@link LinkedHashMap},顺序依照入参 inputMap
  4. *
  5. 返回的是新的map,原来的toMap参数不受影响
  6. *
  7. 也支持诸如 Map{@code } 转 Map{@code } (key和value 使用不同的转换器)
  8. *
  9. 也支持诸如 Map{@code } 转 Map{@code } (单值转数组)
  10. *
  11. 也支持诸如 Map{@code } 转 Map{@code } (数组转数组)
  12. *
*
* * *

示例:

* *
* *

* 场景1: 将Map{@code } 转 Map{@code } 类型 *

* *
     * 
     * Map{@code } map = toMap("1", "2");
     * Map{@code } returnMap = toMap(map, Integer.class);
     * 
     * // 输出测试
     * for (Map.Entry{@code } entry : returnMap.entrySet()){
     *     String key = entry.getKey();
     *     Integer value = entry.getValue();
     *     LOGGER.debug("key:[{}],value:[{}]", key, value);
     * }
     * 
     * 
* * 返回: * *
     * key:["1"],value:[2]
     * 
* *
* *

* 场景2: Map{@code } 转 Map{@code } *

* *
     * 
     * Map{@code } map = toMap("1", "2,2");
     * 
     * //key和value转成不同的类型
     * Map{@code } returnMap = toMap(map,  Integer[].class);
     * 
     * // 输出测试
     * for (Map.Entry{@code } entry : returnMap.entrySet()){
     *     String key = entry.getKey();
     *     Integer[] value = entry.getValue();
     * 
     *     LOGGER.debug("key:[{}],value:[{}]", key, value);
     * }
     * 
     * 
* * 返回: * *
     * key:["1"],value:[[2, 2]]
     * 
* *
* *

* 场景3: Map{@code } 转 Map{@code } *

* *
     * 
     * Map{@code } map = toMap(toArray("1"), toArray("2", "8"));
     * 
     * //key和value转成不同的类型
     * Map{@code } returnMap = toMap(map, Long[].class);
     * 
     * assertThat(returnMap, allOf(hasEntry(toArray("1"), toArray(2L, 8L))));
     * 
* *
* * @param * the key type * @param * the value type * @param * 返回的map ,value的类型 * @param inputMap * the input map * @param valueTargetType * value 需要转换成什么类型,类型可以和原map的类型相同或者可以设置为null,均表示返回的map使用inputMap原样的value,不会进行类型转换 * @return 如果 inputMap 是null或者empty,返回 {@link Collections#emptyMap()}
* 如果 valueTargetType 是null,那么value 直接使用inputMap的 value
* @see #toMap(Map, Class, Class) * @see issues661 * @since 1.10.5 */ public static Map toMap(Map inputMap,final Class valueTargetType){ return toMap(inputMap, null, valueTargetType); } /** * 将诸如 Map{@code } 类型转成 Map{@code } 类型. * *

说明:

*
*
    *
  1. 适合只是简单的将key value类型转换,而不需要自己再构建Transformer,再去调用 {@link #toMap(Map, Transformer, Transformer)} ,简化操作
  2. *
  3. 返回的是 {@link LinkedHashMap},顺序依照入参 inputMap
  4. *
  5. 返回的是新的map,原来的toMap参数不受影响
  6. *
  7. 也支持诸如 Map{@code } 转 Map{@code } (key和value 使用不同的转换器)
  8. *
  9. 也支持诸如 Map{@code } 转 Map{@code } (单值转数组)
  10. *
  11. 也支持诸如 Map{@code } 转 Map{@code } (数组转数组)
  12. *
*
* * *

示例:

* *
* *

* 场景1: 将Map{@code } 转 Map{@code } 类型 *

* *
     * 
     * Map{@code } map = toMap("1", "2");
     * Map{@code } returnMap = toMap(map, Integer.class, Integer.class);
     * 
     * // 输出测试
     * for (Map.Entry{@code } entry : returnMap.entrySet()){
     *     Integer key = entry.getKey();
     *     Integer value = entry.getValue();
     *     LOGGER.debug("key:[{}],value:[{}]", key, value);
     * }
     * 
     * 
* * 返回: * *
     * key:[1],value:[2]
     * 
* *
* *

* 场景2: Map{@code } 转 Map{@code } *

* *
     * 
     * Map{@code } map = toMap("1", "2,2");
     * 
     * //key和value转成不同的类型
     * Map{@code } returnMap = toMap(map, Integer.class, Integer[].class);
     * 
     * // 输出测试
     * for (Map.Entry{@code } entry : returnMap.entrySet()){
     *     Integer key = entry.getKey();
     *     Integer[] value = entry.getValue();
     * 
     *     LOGGER.debug("key:[{}],value:[{}]", key, value);
     * }
     * 
     * 
* * 返回: * *
     * key:[1],value:[[2, 2]]
     * 
* *
* *

* 场景3: Map{@code } 转 Map{@code } *

* *
     * 
     * Map{@code } map = toMap(toArray("1"), toArray("2", "8"));
     * 
     * //key和value转成不同的类型
     * Map{@code } returnMap = toMap(map, Integer[].class, Long[].class);
     * 
     * assertThat(returnMap, allOf(hasEntry(toArray(1), toArray(2L, 8L))));
     * 
* *
* * @param * the key type * @param * the value type * @param * 返回的map ,key的类型 * @param * 返回的map ,value的类型 * @param inputMap * the input map * @param keyTargetType * key需要转换成什么类型,类型可以和原map的类型相同或者可以设置为null,均表示返回的map使用inputMap原样的key,不会进行类型转换 * @param valueTargetType * value 需要转换成什么类型,类型可以和原map的类型相同或者可以设置为null,均表示返回的map使用inputMap原样的value,不会进行类型转换 * @return 如果 inputMap 是null或者empty,返回 {@link Collections#emptyMap()}
* 如果 keyTargetType 是null,那么key直接使用inputMap的key
* 如果 valueTargetType 是null,那么value 直接使用inputMap的 value
* @see #toMap(Map, Transformer, Transformer) * @see issues497 * @since 1.9.2 */ public static Map toMap(Map inputMap,final Class keyTargetType,final Class valueTargetType){ if (isNullOrEmpty(inputMap)){ return emptyMap(); } Transformer keyTransformer = null == keyTargetType ? null : new SimpleClassTransformer<>(keyTargetType); Transformer valueTransformer = null == valueTargetType ? null : new SimpleClassTransformer<>(valueTargetType); return toMap(inputMap, keyTransformer, valueTransformer); } /** * 将诸如 Map{@code } 类型转成 Map{@code } 类型. * *

说明:

*
*
    *
  1. 适合复杂的类型转换场景,如果只是简单的类型转换,你可以直接调用 {@link #toMap(Map, Class, Class)}
  2. *
  3. 返回的是 {@link LinkedHashMap},顺序依照入参 inputMap
  4. *
  5. 返回的是新的map,原来的toMap参数不受影响
  6. *
  7. 也支持诸如 Map{@code } 转 Map{@code } (key和value 使用不同的转换器)
  8. *
  9. 也支持诸如 Map{@code } 转 Map{@code } (单值转数组)
  10. *
  11. 也支持诸如 Map{@code } 转 Map{@code } (数组转数组)
  12. *
*
* *

示例:

* *
* *

* 场景1: 将Map{@code } 转 Map{@code } 类型 *

* *
     * 
     * Map{@code } map = toMap("1", "2");
     * 
     * //key和value 都转成integer 使用相同的转换器
     * Transformer{@code } transformer = new SimpleClassTransformer{@code <>}(Integer.class);
     * 
     * Map{@code } returnMap = toMap(map, transformer, transformer);
     * 
     * // 输出测试
     * for (Map.Entry{@code } entry : returnMap.entrySet()){
     *     Integer key = entry.getKey();
     *     Integer value = entry.getValue();
     *     LOGGER.debug("key:[{}],value:[{}]", key, value);
     * }
     * 
     * 
* * 返回: * *
     * key:[1],value:[2]
     * 
* *
* *

* 场景2: Map{@code } 转 Map{@code } *

* *
     * 
     * Map{@code } map = toMap("1", "2,2");
     * 
     * Transformer{@code } keyTransformer = new SimpleClassTransformer{@code <>}(Integer.class);
     * Transformer{@code } valueTransformer = new SimpleClassTransformer{@code <>}(Integer[].class);
     * 
     * //key和value转成不同的类型
     * Map{@code } returnMap = toMap(map, keyTransformer, valueTransformer);
     * 
     * // 输出测试
     * for (Map.Entry{@code } entry : returnMap.entrySet()){
     *     Integer key = entry.getKey();
     *     Integer[] value = entry.getValue();
     * 
     *     LOGGER.debug("key:[{}],value:[{}]", key, value);
     * }
     * 
     * 
* * 返回: * *
     * key:[1],value:[[2, 2]]
     * 
* *
* *

* 场景3: Map{@code } 转 Map{@code } *

* *
     * 
     * Map{@code } map = toMap(toArray("1"), toArray("2", "8"));
     * 
     * Transformer{@code } keyTransformer = new SimpleClassTransformer{@code <>}(Integer[].class);
     * Transformer{@code } valueTransformer = new SimpleClassTransformer{@code <>}(Long[].class);
     * 
     * //key和value转成不同的类型
     * Map{@code } returnMap = toMap(map, keyTransformer, valueTransformer);
     * 
     * assertThat(returnMap, allOf(hasEntry(toArray(1), toArray(2L, 8L))));
     * 
* *
* * @param * the key type * @param * the value type * @param * 返回的map ,key的类型 * @param * 返回的map ,value的类型 * @param inputMap * the input map * @param keyTransformer * key 转换器,如果是null,那么key直接使用inputMap的key
* @param valueTransformer * value 转换器,如果是null,那么value直接使用inputMap的value
* @return 如果 inputMap 是null或者empty,返回 {@link Collections#emptyMap()}
* 如果 keyTransformer 是null,那么key直接使用inputMap的key
* 如果 valueTransformer 是null,那么value 直接使用inputMap的 value
* @see "org.apache.commons.collections4.MapUtils#transformedMap(Map, Transformer, Transformer)" * @see "org.apache.commons.collections4.map.TransformedMap#transformedMap(Map, Transformer, Transformer)" * @see issues497 * @since 1.9.2 */ @SuppressWarnings("unchecked") public static Map toMap( Map inputMap, final Transformer keyTransformer, final Transformer valueTransformer){ if (isNullOrEmpty(inputMap)){ return emptyMap(); } //--------------------------------------------------------------- Map returnMap = new LinkedHashMap<>(inputMap.size()); for (Map.Entry entry : inputMap.entrySet()){ K key = entry.getKey(); V value = entry.getValue(); returnMap.put( null == keyTransformer ? (I) key : keyTransformer.transform(key), null == valueTransformer ? (J) value : valueTransformer.transform(value)); } return returnMap; } /** * 将 mapEntryCollection 转成map ({@link LinkedHashMap}). * *

说明:

* *
*
    *
  1. 返回是的是 {@link LinkedHashMap},顺序依照参数 mapEntryCollection,key是 {@link java.util.Map.Entry#getKey()},value 是 * {@link java.util.Map.Entry#getValue()}
  2. *
  3. {@link java.util.Map.Entry} 已知实现类,你可以使用 {@link Pair},或者 {@link java.util.AbstractMap.SimpleEntry}
  4. *
*
* *

{@link Pair} 示例:

* *
* *
     * Map{@code } map = toMap(toList(//
     *                 Pair.of("张飞", "丈八蛇矛"),
     *                 Pair.of("关羽", "青龙偃月刀"),
     *                 Pair.of("赵云", "龙胆枪"),
     *                 Pair.of("刘备", "双股剑")));
     * LOGGER.debug(JsonUtil.format(map));
     * 
* * 返回: * *
     * {
     * "张飞": "丈八蛇矛",
     * "关羽": "青龙偃月刀",
     * "赵云": "龙胆枪",
     * "刘备": "双股剑"
     * }
     * 
* *
* *

{@link java.util.AbstractMap.SimpleEntry} 示例:

* *
* *
     * Map{@code } map = ConvertUtil.toMap(
     *                 toList(
     *                                 new SimpleEntry{@code <>}("张飞", "丈八蛇矛"),
     *                                 new SimpleEntry{@code <>}("关羽", "青龙偃月刀"),
     *                                 new SimpleEntry{@code <>}("赵云", "龙胆枪"),
     *                                 new SimpleEntry{@code <>}("刘备", "双股剑")));
     * LOGGER.debug(JsonUtil.format(map));
     * 
* * 返回: * *
     * {
     * "张飞": "丈八蛇矛",
     * "关羽": "青龙偃月刀",
     * "赵云": "龙胆枪",
     * "刘备": "双股剑"
     * }
     * 
* *
* * @param * the value type * @param * the key type * @param * the element type * @param mapEntryCollection * the map entry collection * @return 如果 mapEntryCollection 是null,返回 {@link Collections#emptyMap()}
* 如果 mapEntryCollection 有元素是null,将会抛出异常 {@link IllegalArgumentException} * @see com.feilong.lib.lang3.ArrayUtils#toMap(Object[]) * @since 1.7.1 */ public static > Map toMap(Collection mapEntryCollection){ if (null == mapEntryCollection){ return emptyMap(); } Validate.noNullElements(mapEntryCollection, "mapEntryCollection can't has null elememt!"); Map map = newLinkedHashMap(mapEntryCollection.size()); for (Map.Entry entry : mapEntryCollection){ map.put(entry.getKey(), entry.getValue()); } return map; } /** * 将 {@link java.util.Map.Entry}数组转成map ({@link LinkedHashMap}). * *

说明:

* *
*
    *
  1. 返回是的是 {@link LinkedHashMap},顺序依照参数 {@link java.util.Map.Entry}数组顺序,key是 {@link java.util.Map.Entry#getKey()},value 是 * {@link java.util.Map.Entry#getValue()}
  2. *
  3. {@link java.util.Map.Entry} 已知实现类,你可以使用 {@link Pair},或者 {@link java.util.AbstractMap.SimpleEntry}
  4. *
*
* *

{@link Pair} 示例:

* *
* *
     * Map{@code } map = ConvertUtil.toMapUseEntrys(
     *                 Pair.of("张飞", "丈八蛇矛"),
     *                 Pair.of("关羽", "青龙偃月刀"),
     *                 Pair.of("赵云", "龙胆枪"),
     *                 Pair.of("刘备", "双股剑"));
     * LOGGER.debug(JsonUtil.format(map));
     * 
* * 返回: * *
     * {
     * "张飞": "丈八蛇矛",
     * "关羽": "青龙偃月刀",
     * "赵云": "龙胆枪",
     * "刘备": "双股剑"
     * }
     * 
     * 
* *
* *

{@link java.util.AbstractMap.SimpleEntry} 示例:

* *
* *
     * 
     * Map{@code } map = ConvertUtil.toMapUseEntrys(
     *                 new SimpleEntry{@code <>}("张飞", "丈八蛇矛"),
     *                 new SimpleEntry{@code <>}("关羽", "青龙偃月刀"),
     *                 new SimpleEntry{@code <>}("赵云", "龙胆枪"),
     *                 new SimpleEntry{@code <>}("刘备", "双股剑"));
     * LOGGER.debug(JsonUtil.format(map));
     * 
     * 
* * 返回: * *
     * {
     * "张飞": "丈八蛇矛",
     * "关羽": "青龙偃月刀",
     * "赵云": "龙胆枪",
     * "刘备": "双股剑"
     * }
     * 
     * 
* *
* * *

重构:

* *
*

* 以前初始化全局map的时候,你可能会这么写 *

* *
     * 
     * // 除数和单位的map,必须是有顺序的 从大到小.
     * private static final Map{@code } DIVISOR_AND_UNIT_MAP = new LinkedHashMap{@code <>}();
     * 
     * 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{@code } 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
     * 
     * 
* *

* 代码更加简洁 *

* *
* * @param * the value type * @param * the key type * @param mapEntrys * the entrys * @return 如果 entrys 是null,返回 {@link Collections#emptyMap()}
* 如果 entrys 有元素是null,将会抛出异常 {@link IllegalArgumentException} * @see com.feilong.lib.lang3.tuple.ImmutablePair#ImmutablePair(Object, Object) * @see com.feilong.lib.lang3.tuple.Pair#of(Object, Object) * @since 1.7.1 * @since 1.9.5 change name */ @SafeVarargs public static Map toMapUseEntrys(Map.Entry...mapEntrys){ if (null == mapEntrys){ return emptyMap(); } Validate.noNullElements(mapEntrys, "mapEntrys can't has null elememt!"); Map map = newLinkedHashMap(mapEntrys.length); for (Map.Entry entry : mapEntrys){ map.put(entry.getKey(), entry.getValue()); } return map; } //-------------------------toProperties-------------------------------------- /** * 将map转成 {@link Properties}. * *

说明:

*
*
    *
  1. 由于 Properties 只能保存非空的key和value,因此如果map 有key或者value是null,将会抛出{@link NullPointerException}
  2. *
*
* *

示例:

* *
* *
     * Map{@code } map = toMap("name", "feilong");
     * Properties properties = ConvertUtil.toProperties(map);
     * 
     * LOGGER.debug(JsonUtil.format(properties));
     * 
* * 返回: * *
     * {"name": "feilong"}
     * 
* *
* * @param map * the map * @return 如果 map 是null,返回 empty Properties
* @see "org.apache.commons.collections4.MapUtils#toProperties(Map)" * @since 1.7.3 */ public static Properties toProperties(final Map map){ return MapUtils.toProperties(map); } //--------------------------toList------------------------------------- /** * 将枚举 enumeration 转成 {@link List}. * *

示例:

* *
* *
     * toList((Enumeration{@code }) null) = emptyList()
     * 
* *
* * @param * the generic type * @param enumeration * the enumeration * @return 如果 enumeration 是null,返回 {@link Collections#emptyList()}
* 否则返回 {@link Collections#list(Enumeration)} * @see Collections#emptyList() * @see Collections#EMPTY_LIST * @see Collections#list(Enumeration) * @see EnumerationUtils#toList(Enumeration) * @since 1.0.7 */ public static List toList(final Enumeration enumeration){ return null == enumeration ? Collections. emptyList() : Collections.list(enumeration); } /** * 将 集合 collection 转成 list. * *

说明:

*
*
    *
  1. 此方法很适合快速的将set转成list这样的操作
  2. *
*
* *

示例:

* *
* *
     * Set{@code } set = new LinkedHashSet{@code <>}();
     * Collections.addAll(set, "a", "a", "b", "b");
     * LOGGER.debug("{}", toList(set));
     * 
* * 返回: * *
     * [a,b]
     * 
* *
* * @param * the generic type * @param collection * the collection * @return 如果 collection 是null,返回 {@link Collections#emptyList()}
* 如果 collection instanceof List,那么强转成 list返回
* 否则返回 new ArrayList(collection) * @see "org.apache.commons.collections4.IterableUtils#toList(Iterable)" * @see "org.apache.commons.collections4.IteratorUtils#toList(Iterator)" * @since 1.6.1 */ public static List toList(final Collection collection){ if (null == collection){ return Collections. emptyList(); } return collection instanceof List ? (List) collection : new ArrayList<>(collection); } /** * 数组转成 ({@link java.util.ArrayList ArrayList}). * *

说明:

*
*
    *
  1. 此方法返回的list可以进行add等操作
  2. *
  3. 如果直接使用{@link java.util.Arrays#asList(Object...) Arrays#asList(Object...)}返回的list没有实现 {@link java.util.Collection#add(Object) * Collection#add(Object)}等方法,执行list.add("c");操作的话会导致异常!
  4. *
  5. 而本方法使用 {@link ArrayList#ArrayList(java.util.Collection)} 来进行重新封装返回,可以执行正常的list操作
  6. *
*
* * *

特别适合:

* *
* *

* 如果你要通过以下方式来构造list: *

* *
     * 
     * List{@code } list = new ArrayList{@code <>}();
     * list.add("feilong1");
     * list.add("feilong2");
     * list.add("feilong2");
     * list.add("feilong3");
     * 
     * 
* * 此时你可以使用: * *
     * List{@code } list = toList("feilong1", "feilong2", "feilong2", "feilong3");
     * 
* *

* 代码会更简洁 *

*
* *

甚至于:

* *
* *

* 有很多时候,参数需要一个对象list,构造的时候,你需要这样 *

* *
     * 
     * List{@code } userAddresseList = new ArrayList{@code <>}();
     * UserAddress userAddress = new UserAddress();
     * userAddress.setAddress("上海");
     * userAddresseList.add(userAddress);
     * 
     * 
* * 你可以重构成: * *
     * UserAddress userAddress = new UserAddress();
     * userAddress.setAddress("上海");
     * List{@code } userAddresseList = toList(userAddress);
     * 
* *
* * @param * the generic type * @param arrays * T数组 * @return 如果 arrays 是null或者empty,返回 {@link Collections#emptyList()}
* * 提别提醒:注意动态数组(Varargs)的陷阱: * *
     *         assertEquals(emptyList(), toList((User[]) null));
     *         
     *         //-------------------------------------------------
     * 
     *         List{@code } list = newArrayList();
     *         list.add(null);
     * 
     *         assertEquals(list, toList((User) null));
     *         
* * 否则返回 {@code new ArrayList(Arrays.asList(arrays));} * @see java.util.Arrays#asList(Object...) * @see java.util.Collections#singleton(Object) * @see java.util.Collections#addAll(Collection, Object...) * @see java.util.Collections#singletonList(Object) * @see "org.springframework.util.CollectionUtils#arrayToList(Object)" */ @SafeVarargs public static List toList(T...arrays){ return isNullOrEmpty(arrays) ? Collections. emptyList() : new ArrayList<>(Arrays.asList(arrays)); } //---------------------------toSet------------------------------------ /** * 数组转成 Set ({@link java.util.LinkedHashSet LinkedHashSet}). * *

说明:

*
*
    *
  1. 此方法返回的是{@link java.util.LinkedHashSet LinkedHashSet}
  2. *
*
* *

特别适合:

* *
* *

* 如果你要通过以下方式来构造Set: *

* *
     * 
     * Set{@code } set = new LinkedHashSet{@code <>}();
     * set.add("feilong1");
     * set.add("feilong2");
     * set.add("feilong2");
     * set.add("feilong3");
     * 
     * 
* * 此时你可以使用: * *
     * Set{@code } set = toSet("feilong1", "feilong2", "feilong2", "feilong3");
     * 
* *

* 代码会更简洁 *

*
* *

甚至于:

* *
* *

* 有很多时候,参数需要一个对象Set,构造的时候,你需要这样 *

* *
     * Set{@code } userAddresseSet = new LinkedHashSet{@code <>}();
     * UserAddress userAddress = new UserAddress();
     * userAddress.setAddress("上海");
     * userAddresseSet.add(userAddress);
     * 
* * 你可以重构成: * *
     * UserAddress userAddress = new UserAddress();
     * userAddress.setAddress("上海");
     * Set{@code } userAddresseSet = toSet(userAddress);
     * 
* *
* * @param * the generic type * @param arrays * the arrays * @return 如果 arrays 是null或者empty,返回 {@link Collections#emptySet()}
* * 提别提醒:注意动态数组(Varargs)的陷阱: * *
     *         assertEquals(emptySet(), toSet((User[]) null));
     *         
     *         //-------------------------------------------------
     * 
     *         Set{@code } set = new LinkedHashSet{@code <>}();
     *         set.add(null);
     * 
     *         assertEquals(list, toSet((User) null));
     *         
* * 否则返回 {@code new LinkedHashSet(Arrays.asList(arrays));} * @see "com.google.common.collect.Sets#newHashSet(E...)" * @since 1.9.6 */ @SafeVarargs public static Set toSet(T...arrays){ return isNullOrEmpty(arrays) ? Collections. emptySet() : new LinkedHashSet<>(Arrays.asList(arrays)); } //----------------------------toArray----------------------------------- /** * 将动态数组转成数组. * *

示例:

* *
* *
     * String[] array = ConvertUtil.toArray("1", "2");                  =   ["1", "2"];
     * 
     * String[] emptyArray = ConvertUtil.{@code }toArray();     =   [] ; //= new String[] {};
     * Integer[] emptyArray = ConvertUtil.{@code }toArray();   =   [] ; //= new Integer[] {};
     * 
     * //注意
     * String[] nullArray = ConvertUtil.toArray(null)                   =   null;
     * ConvertUtil.toArray((String) null)                               =   new String[] { null }
     * 
* *
* *

注意:

* *
*

* 数组是具体化的(reified),而泛型在运行时是被擦除的(erasure)。
* 数组是在运行时才去判断数组元素的类型约束,而泛型正好相反,在运行时,泛型的类型信息是会被擦除的,只有编译的时候才会对类型进行强化。 *

* * 泛型擦除的规则: * *
    *
  1. 所有参数化容器类都被擦除成非参数化的(raw type); 如 List{@code }、List{@code >}都被擦除成 List
  2. *
  3. 所有参数化数组都被擦除成非参数化的数组;如 List{@code }[],被擦除成 List[]
  4. *
  5. Raw type 的容器类,被擦除成其自身,如 List{@code }被擦 除成 List
  6. *
  7. 原生类型(int,String 还有 wrapper 类)都擦除成他们的自身
  8. *
  9. 参数类型 E,如果没有上限,则被擦除成 Object
  10. *
  11. 所有约束参数如{@code }、{@code }都被擦 除成 E
  12. *
  13. 如果有多个约束,擦除成第一个,如{@code },则擦除成 Object
  14. *
* *

* 这将会导致下面的代码: *

* *
     * 
     * public static {@code } Map{@code } toArrayValueMap(Map{@code } singleValueMap){
     *     Map{@code } arrayValueMap = newLinkedHashMap(singleValueMap.size());//保证顺序和参数singleValueMap顺序相同
     *     for (Map.Entry{@code } entry : singleValueMap.entrySet()){
     *         arrayValueMap.put(entry.getKey(), toArray(entry.getValue()));//注意此处的Value不要声明成V,否则会变成Object数组
     *     }
     *     return arrayValueMap;
     * }
     * 
* * 调用的时候, * *
     * Map{@code } singleValueMap = MapUtil.newLinkedHashMap(2);
     * singleValueMap.put("province", "江苏省");
     * singleValueMap.put("city", "南通市");
     * 
     * Map{@code } arrayValueMap = MapUtil.toArrayValueMap(singleValueMap);
     * String[] strings = arrayValueMap.get("province");//此时返回的是 Object[]
     * 
* * 会出现异常 * *
     * java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
     * 
* *
* * @param * the generic type * @param arrays * the arrays * @return 如果 arrays 是null,返回null
* @see com.feilong.lib.lang3.ArrayUtils#toArray(Object...) * @since commons-lang 3 * @since 1.6.0 */ @SafeVarargs public static T[] toArray(T...arrays){ return ArrayUtils.toArray(arrays); } /** * 将集合 collection 转成数组. * *

示例:

* *
* *
     * List{@code } list = new ArrayList{@code <>}();
     * 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"]
     * 
* *
* * @param * the generic type * @param collection * collection * @param arrayComponentType * 数组组件类型的 Class * @return 如果 collection 是null,直接返回null
* 如果 arrayComponentType 是null,抛出 {@link NullPointerException}
* @see java.lang.reflect.Array#newInstance(Class, int) * @see java.lang.reflect.Array#newInstance(Class, int...) * @see java.util.Collection#toArray() * @see java.util.Collection#toArray(Object[]) * @see java.util.List#toArray() * @see java.util.List#toArray(Object[]) * @see java.util.Vector#toArray() * @see java.util.Vector#toArray(Object[]) * @see java.util.LinkedList#toArray() * @see java.util.LinkedList#toArray(Object[]) * @see java.util.ArrayList#toArray() * @see java.util.ArrayList#toArray(Object[]) * * @see "org.apache.commons.collections4.IteratorUtils#toArray(Iterator,Class)" * @see "org.springframework.util.StringUtils#toStringArray(Collection)" * @since 1.2.2 */ @SuppressWarnings("squid:S1168") //Empty arrays and collections should be returned instead of null public static T[] toArray(Collection collection,Class arrayComponentType){ if (null == collection){ // since 1.8.6 return null; } Validate.notNull(arrayComponentType, "arrayComponentType must not be null"); // 如果采用大家常用的把a的length设为0,就需要反射API来创建一个大小为size的数组,而这对性能有一定的影响. // 所以最好的方式就是直接把a的length设为Collection的size从而避免调用反射API来达到一定的性能优化. T[] array = ArrayUtil.newArray(arrayComponentType, collection.size()); //注意,toArray(new Object[0]) 和 toArray() 在功能上是相同的. return collection.toArray(array); } /** * 将字符串数组 toBeConvertedValue 转成指定类型 targetType 的数组. * *

示例:

* *
* *
     * String[] ss = { "2", "1" };
     * toArray(ss, Long.class);                                     =   new Long[] { 2L, 1L }
     * 
     * ConvertUtil.toArray((String[]) null, Serializable.class)     =   null
     * 
* *
* * @param * the generic type * @param toBeConvertedValue * the values * @param targetType * 要被转换的目标类型 * @return 如果 toBeConvertedValue 是null,那么返回null
* 如果 targetType 是null,抛出 {@link NullPointerException}
* 否则调用 {@link ConvertUtils#convert(String[], Class)} * @see com.feilong.lib.beanutils.ConvertUtils#convert(String[], Class) * @see com.feilong.lib.beanutils.ConvertUtilsBean#convert(String[], Class) * @since 1.6.0 */ @SuppressWarnings("unchecked") public static T[] toArray(String[] toBeConvertedValue,Class targetType){ //如果指定的类型 本身就是数组类型的class,那么返回的类型就是该数组类型,否则将基于指定类型构造数组. return null == toBeConvertedValue ? null : (T[]) ConvertUtils.convert(toBeConvertedValue, targetType); } //--------------------------------------------------------------- /** * 将 toBeConvertedValue 转成{@link String}数组. * *

说明:

* *
* *
    * *
  1. * *

    * 该方法很适合将 非字符串数组的数组 转换成 字符串数组,比如 *

    * *
    * *
         * 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" ]
         * 
    * *
    * *
  2. * *
  3. *

    * 也可以将字符串 解析成数组 in the Java language into a List individual Strings for each element, 根据以下规则: *

    * *

    字符串转成数组的规则:

    * *
    * *

    * 参见 {@link com.feilong.lib.beanutils.converters.ArrayConverter} *

    * *
      *
    • 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"]
         * 
    * *
    * *
  4. *
* *
* * @param toBeConvertedValue * the to be converted value * @return 如果 toBeConvertedValue 是null,返回null
* @see com.feilong.lib.beanutils.converters.ArrayConverter#convertToType(Class, Object) * @see com.feilong.lib.beanutils.converters.ArrayConverter#parseElements(Class, String) * @see #convert(Object, Class) * @since 1.4.0 */ public static String[] toStrings(Object toBeConvertedValue){ return convert(toBeConvertedValue, String[].class); } /** * 将 toBeConvertedValue转成{@link Iterator}类型. * *

示例:

* *
* *
     * // null
     * toIterator(null) = null
     * 
     * //PrimitiveArray
     * int[] i2 = { 1, 2 };
     * Iterator{@code } iterator = toIterator(i2);
     * 
     * //逗号分隔的字符串
     * Iterator{@code } iterator = toIterator("1,2");
     * 
     * //collection
     * List{@code } list = new ArrayList{@code <>}();
     * list.add("aaaa");
     * list.add("nnnnn");
     * 
     * Iterator{@code } iterator = toIterator(list);
     * 
     * //Enumeration
     * Enumeration{@code } enumeration = new StringTokenizer("this is a test");
     * Iterator{@code } iterator = toIterator(enumeration);
     * 
     * 
     * 
     * 
     * 
     * 

支持以下类型:

* *
*
    *
  • 逗号分隔的字符串,先使用{@link ConvertUtil#toStrings(Object)} 转成数组
  • *
  • 数组(包括 包装类型数组 以及 原始类型数组)
  • *
  • 如果是{@link java.util.Map},将 {@link java.util.Map#values()} 转成{@link java.util.Iterator}
  • *
  • {@link java.util.Collection}
  • *
  • {@link java.util.Iterator}
  • *
  • {@link java.util.Enumeration}
  • *
  • {@link java.util.Dictionary}
  • *
  • {@link org.w3c.dom.Node}
  • *
  • {@link org.w3c.dom.NodeList}
  • *
*
* * @param * the generic type * @param toBeConvertedValue * the to be converted value * @return 如果 toBeConvertedValue 是null,返回null
* 如果 toBeConvertedValue 是字符串,先转成数组,再转成迭代器
* 否则转成 {@link IteratorUtils#getIterator(Object)} * @see Collection#iterator() * @see EnumerationIterator#EnumerationIterator(Enumeration) * @see IteratorUtils#asIterator(Enumeration) * @see IteratorUtils#getIterator(Object) * @see "org.apache.taglibs.standard.tag.common.core.ForEachSupport#supportedTypeForEachIterator(Object)" * @since Commons Collections4.0 */ @SuppressWarnings("unchecked") public static Iterator toIterator(Object toBeConvertedValue){ if (null == toBeConvertedValue){ return null; } // 逗号分隔的字符串 if (toBeConvertedValue instanceof String){ return toIterator(toStrings(toBeConvertedValue)); } return (Iterator) IteratorUtils.getIterator(toBeConvertedValue); } /** * 将 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{@code }[] klasses = new Class{@code }[length];
     * for (int i = 0, j = length; i {@code <} j; ++i){
     *     klasses[i] = (Class{@code }) actualTypeArguments[i];
     * }
     * 
     * return klasses;
     * 
     * 
* * 现在可以重构成: * *
     * Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
     * return convert(actualTypeArguments, Class[].class);
     * 
* *
* *

注意:

* *
* *
    * *
  1. 如果targetType的转换器没有注册,那么传入的value原样返回,
    * 比如ConvertUtil.convert("zh_CN", Locale.class) 由于找不到converter,那么返回"zh_CN". *
  2. * *
  3. 如果转换不了,会使用默认值
  4. * *
  5. 如果传的 toBeConvertedValuetoBeConvertedValue.getClass().isArray() 或者 {@link Collection} *
    * *
    *
    如果 targetType 不是数组
    *
    *

    * 那么会取第一个元素进行转换,
    * 参见{@link com.feilong.lib.beanutils.converters.AbstractConverter#convert(Class, Object)},调用的 * {@link com.feilong.lib.beanutils.converters.AbstractConverter#convertArray(Object)} 方法 *

    *
    * *
    如果 targetType 是数组
    *
    参见 {@link com.feilong.lib.beanutils.converters.ArrayConverter#convertToType(Class, Object) ArrayConverter#convertToType(Class, * Object)} 会基于targetType 构造一个数组对象,大小长度就是 toBeConvertedValue的大小或者长度, 然后迭代 toBeConvertedValue 依次进行转换
    * *
    * *
    *
  6. *
*
* * *

注意:

* *
* *

* 该方法不适合 list转换成字符串,比如: *

* *
     * ConvertUtil.toString(toList("张飞", "关羽", "", "赵云"), String.class) = "张飞"
     * 
* *

* ,请使用 {@link #toString(Collection, ToStringConfig)} *

* *
* *

* 该方法也不适合 array 转换成字符串,比如: *

* *
     * Integer[] int1 = { 2, null, 1, null };
     * LOGGER.debug(ConvertUtil.toString(int1),String.class);        = 2
     * 
* *

* 请使用 {@link #toString(Object[], ToStringConfig)} *

* *
* *

对于 Array 转成 String:

* *
* *

* 参见 {@link com.feilong.lib.beanutils.converters.ArrayConverter#convertToString(Object) ArrayConverter#convertToString(Object)}
* * 在转换的过程中,如果发现object是数组,将使用 {@link java.lang.reflect.Array#get(Object, int) Array#get(Object, int)}来获得数据,
* 如果发现不是数组,将会将object转成集合 {@link com.feilong.lib.beanutils.converters.ArrayConverter#convertToCollection(Class, Object) * ArrayConverter#convertToCollection(Class, Object)}再转成迭代器 {@link java.util.Collection#iterator() Collection.iterator()} *

* *

* 在将object转成集合 {@link com.feilong.lib.beanutils.converters.ArrayConverter#convertToCollection(Class, 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[] {'.', '-'}用于{@link java.io.StreamTokenizer}分隔字符串
boolean onlyFirstToString = true;只转第一个值
*
*
* * @param * the generic type * @param toBeConvertedValue * 需要被转换的对象/值 * @param targetType * 要转成什么类型 * @return 如果 targetType 是null,抛出 {@link NullPointerException}
* 如果 toBeConvertedValue 是null,那么直接返回null
* 否则返回 {@link com.feilong.lib.beanutils.ConvertUtils#convert(Object, Class)} * @see com.feilong.lib.beanutils.ConvertUtils#convert(Object, Class) * @see com.feilong.lib.beanutils.converters.AbstractConverter#convert(Class, Object) * @see com.feilong.lib.beanutils.converters.ArrayConverter#convertToType(Class, Object) */ @SuppressWarnings("unchecked") public static T convert(Object toBeConvertedValue,Class targetType){ Validate.notNull(targetType, "targetType can't be null!"); return null == toBeConvertedValue ? null : (T) ConvertUtils.convert(toBeConvertedValue, targetType); } //--------------------------------------------------------------- /** * 将对象转成 {@link Locale}. * *

示例:

* *
* *
     * ConvertUtil.toLocale(null)       = null
     * ConvertUtil.toLocale("zh_CN")    = Locale.CHINA
     * 
* *
* * @param locale * 可以是 null ,字符串 或者 直接的 {@link Locale}对象 * @return 如果 locale 是null,返回 null
* 如果 locale instanceof Locale,返回 (Locale) locale
* 如果 locale instanceof String,返回 {@link LocaleUtils#toLocale(String)}
* 其他的类型,将抛出 {@link UnsupportedOperationException} * @see com.feilong.lib.lang3.LocaleUtils#toLocale(String) * @since 1.7.2 */ public static Locale toLocale(Object locale){ if (null == locale){ return null; } //--------------------------------------------------------------- if (locale instanceof Locale){ return (Locale) locale; } if (locale instanceof String){ return LocaleUtils.toLocale((String) locale); } //--------------------------------------------------------------- throw new UnsupportedOperationException("input param [locale] type is:[" + locale.getClass().getName() + "] not support!"); } }