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

com.feilong.core.lang.ObjectUtil 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.3.0
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.lang;

import static com.feilong.core.Validator.isNotNullOrEmpty;
import static com.feilong.core.Validator.isNullOrEmpty;
import static com.feilong.core.lang.StringUtil.EMPTY;
import static com.feilong.core.util.CollectionsUtil.newArrayList;
import static com.feilong.core.util.CollectionsUtil.newHashSet;
import static com.feilong.core.util.MapUtil.newHashMap;
import static com.feilong.core.util.MapUtil.newLinkedHashMap;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import com.feilong.core.Validate;
import com.feilong.core.bean.PropertyUtil;
import com.feilong.core.lang.reflect.ConstructorUtil;
import com.feilong.lib.beanutils.PropertyUtils;

/**
 * {@link Object} 工具类.
 * 
 * 

判断相等

* *
*
    *
  1. {@link com.feilong.lib.lang3.ObjectUtils#equals(Object, Object)} 支持两个值都是null的情况
  2. *
  3. {@link java.util.Objects#equals(Object, Object)} (since jdk1.7) 也支持两个值都是null的情况
  4. *
*
* * @author feilong * @see com.feilong.lib.lang3.ObjectUtils * @see java.util.Objects * @since 1.0.0 */ public final class ObjectUtil{ /** Don't let anyone instantiate this class. */ private ObjectUtil(){ //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化. //see 《Effective Java》 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } /** * 新建klass实例, 并将fromObj中的 指定属于 includePropertyNames 设置到新建的实例中. * *

重构:

* *
*

* 对于以下代码: *

* *
     * 
     * public IPage{@code } select(EarphoneforestInfoQueryForm earphoneforestInfoQueryForm){
     *     Page{@code } page = new Page<>(earphoneforestInfoQueryForm.getPageNo(), earphoneforestInfoQueryForm.getPageSize());
     * 
     *     EarphoneforestInfoQueryRequest earphoneforestInfoQueryRequest = new EarphoneforestInfoQueryRequest();
     *     PropertyUtil.copyProperties(earphoneforestInfoQueryRequest, earphoneforestInfoQueryForm);
     * 
     *     IPage{@code } iPage = earphoneforestInfoMapper.select(page, earphoneforestInfoQueryRequest);
     *     return iPage;
     * }
     * 
     * 
* * 可以重构成: * *
     * public IPage{@code } select(EarphoneforestInfoQueryForm earphoneforestInfoQueryForm){
     *     Page{@code } page = new Page<>(earphoneforestInfoQueryForm.getPageNo(), earphoneforestInfoQueryForm.getPageSize());
     * 
     *      EarphoneforestInfoQueryRequest earphoneforestInfoQueryRequest=newFrom(EarphoneforestInfoQueryRequest.class,earphoneforestInfoQueryForm);
     *     return earphoneforestInfoMapper.select(page,earphoneforestInfoQueryRequest);
     * }
     * 
* *
* * @param * the generic type * @param klass * 可以被实例化的类 * @param fromObj * 原始对象 * @param includePropertyNames * 包含的属性数组名字数组,(can be nested/indexed/mapped/combo)
* 如果是null或者empty,将会调用 {@link PropertyUtils#copyProperties(Object, Object)}
*
    *
  1. 如果没有传入includePropertyNames参数,那么直接调用{@link PropertyUtils#copyProperties(Object, Object)},否则循环调用 * {@link PropertyUtil#getProperty(Object, String)}再{@link PropertyUtil#setProperty(Object, String, Object)}到toObj对象中
  2. *
  3. 如果传入的includePropertyNames,含有 fromObj没有的属性名字,将会抛出异常
  4. *
  5. 如果传入的includePropertyNames,含有 fromObj有,但是 toObj没有的属性名字,会抛出异常,see * {@link com.feilong.lib.beanutils.PropertyUtilsBean#setSimpleProperty(Object, String, Object) copyProperties} * Line2078
  6. *
* @return 如果 klass 是null,抛出 {@link NullPointerException}
* 如果 fromObj 是null,直接返回 klass 的实例
* 如果 includePropertyNames 是null或者empty,将复制全部属性
* @see com.feilong.core.lang.reflect.ConstructorUtil#newInstance(Class, Object...) * @see com.feilong.core.bean.PropertyUtil#copyProperties(Object, Object, String...) * @since 3.1.1 */ public static T newFrom(final Class klass,Object fromObj,String...includePropertyNames){ Validate.notNull(klass, "klass can't be null!"); T t = ConstructorUtil.newInstance(klass); if (null == fromObj){ return t; } PropertyUtil.copyProperties(t, fromObj, includePropertyNames); return t; } //--------------------------------------------------------------- /** * 如果 object 是null或者empty,返回默认值 defaultValue. * *

示例:

* *
* *
     * ObjectUtil.defaultIfNullOrEmpty(null, null)      = null
     * ObjectUtil.defaultIfNullOrEmpty(null, "")        = ""
     * ObjectUtil.defaultIfNullOrEmpty(null, "zz")      = "zz"
     * ObjectUtil.defaultIfNullOrEmpty("abc", *)        = "abc"
     * ObjectUtil.defaultIfNullOrEmpty(Boolean.TRUE, *) = Boolean.TRUE
     * 
* *
* *

说明:

*
*
    *
  1. 使用该方法,可以简化你的代码
  2. *
  3. 如果使用 import static 的特性,代码会更加简洁
  4. *
  5. 如果你只需要判断 null的场景,你可以使用 {@link #defaultIfNull(Object, Object)}
  6. *
*
* * *

对下面的代码重构:

* *
* *
     * 
     * if (isNotNullOrEmpty(defaultReturnResult.getReturnObject())){
     *     return (String) defaultReturnResult.getReturnObject();
     * }else{
     *     return "redirect:/";
     * }
     * 
     * 
* * 可以重构成: * *
     * return ObjectUtil.defaultIfNullOrEmpty((String) defaultReturnResult.getReturnObject(), "redirect:/");
     * 
* *
* *

再比如:

* *
* *
     * 
     * private void putItemToMap(Map{@code >} map,String categoryName,Item item){
     *     List{@code } itemList = map.get(categoryName);
     * 
     *     if (isNullOrEmpty(itemList)){
     *         itemList = new ArrayList{@code <>}();
     *     }
     *     itemList.add(item);
     *     map.put(categoryName, itemList);
     * }
     * 
     * 
* * 可以重构成: * *
     * 
     * private void putItemToMap(Map{@code >} map,String categoryName,Item item){
     *     List{@code } itemList = ObjectUtil.defaultIfNullOrEmpty(map.get(categoryName), new ArrayList{@code }());
     *     itemList.add(item);
     *     map.put(categoryName, itemList);
     * }
     * 
* * 当然对于上面的case,你还可以直接调用 {@link com.feilong.core.util.MapUtil#putMultiValue(java.util.Map, Object, Object)} * *
* * @param * the type of the object * @param object * the {@code Object} to test, 可以是 {@code null} or empty * @param defaultValue * the default value to return, 可以是 {@code null} or empty * @return 如果 object 是null或者empty,返回 defaultValue,否则返回 object * @see #defaultIfNull(Object, Object) * @see "org.apache.commons.collections4.ListUtils#defaultIfNull(java.util.List, java.util.List)" * @since 1.7.2 */ public static T defaultIfNullOrEmpty(final T object,final T defaultValue){ return isNotNullOrEmpty(object) ? object : defaultValue; } //--------------------------------------------------------------- /** * 如果 object 是null,返回默认值 defaultValue. * *
     * ObjectUtil.defaultIfNull(null, null)      = null
     * ObjectUtil.defaultIfNull(null, "")        = ""
     * ObjectUtil.defaultIfNull(null, "zz")      = "zz"
     * ObjectUtil.defaultIfNull("abc", *)        = "abc"
     * ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
     * 
* * @param * the type of the object * @param object * the {@code Object} to test, may be {@code null} * @param defaultValue * the default value to return, may be {@code null} * @return 如果 object 是null,返回 defaultValue,否则返回 object * @since 3.0.0 */ public static T defaultIfNull(final T object,final T defaultValue){ return object != null ? object : defaultValue; } //--------------------------------------------------------------- /** * 如果 str 是null,返回默认值 {@link com.feilong.core.lang.StringUtil#EMPTY}. * *
     * ObjectUtil.defaultEmptyStringIfNull(null) = EMPTY;
     * ObjectUtil.defaultEmptyStringIfNull("a") = "a";
     * 
* *

适合场景:

* *
*

* 比如以下字符串拼接的代码: *

* *
     * 
     * return Slf4jUtil.format(
     *                 "{}-{} {}_{}_{}.svg", //
     *                 villageConfig.getId(),
     *                 defaultIfNull(categoryId, EMPTY),
     *                 defaultIfNull(villageConfig.getTitle(), EMPTY),
     *                 defaultIfNull(categoryName, EMPTY),
     *                 villageQrCodeGeneratorVO.getDataTime());
     * 
     * 
* * 可以重构成: * *
     * return Slf4jUtil.format(
     *                 "{}-{} {}_{}_{}.svg", //
     *                 villageConfig.getId(),
     *                 defaultEmptyStringIfNull(categoryId),
     *                 defaultEmptyStringIfNull(villageConfig.getTitle()),
     *                 defaultEmptyStringIfNull(categoryName),
     *                 villageQrCodeGeneratorVO.getDataTime());
     * 
* *
* * @param str * the str * @return 如果 str 是null,返回默认值 {@link com.feilong.core.lang.StringUtil#EMPTY}. * @since 3.3.6 * @apiNote 实现代码: * defaultIfNull(str, EMPTY); */ public static String defaultEmptyStringIfNull(final String str){ return defaultIfNull(str, EMPTY); } //--------------------------------------------------------------- /** * 如果 list 是null,返回默认值 {@link java.util.Collections#emptyList()}. * *
     * ObjectUtil.defaultEmptyListIfNull(null) = emptyList();
     * ObjectUtil.defaultEmptyListIfNull(toList(1)) = toList(1);
     * 
* * @param * the type of the object * @param list * the {@code Object} to test, may be {@code null} * @return 如果 list 是null,返回默认值 {@link java.util.Collections#emptyList()}. * @since 3.3.5 */ public static List defaultEmptyListIfNull(final List list){ return defaultIfNull(list, emptyList()); } /** * 如果 set 是null,返回默认值 {@link java.util.Collections#emptySet()}. * *
     * ObjectUtil.defaultEmptySetIfNull(null) = emptySet();
     * ObjectUtil.defaultEmptySetIfNull(toSet(1)) = toSet(1);
     * 
* * @param * the type of the object * @param set * the {@code Object} to test, may be {@code null} * @return 如果 set 是null,返回默认值 {@link java.util.Collections#emptySet()}. * @since 3.3.5 */ public static Set defaultEmptySetIfNull(final Set set){ return defaultIfNull(set, emptySet()); } /** * 如果 map 是null,返回默认值 {@link java.util.Collections#emptyMap()}. * *
     * ObjectUtil.defaultEmptyMapIfNull(null) = emptyMap();
     * ObjectUtil.defaultEmptyMapIfNull(toMap("name", "zhangfei")) = toMap("name", "zhangfei");
     * 
* * @param * the key type * @param * the value type * @param map * the map * @return 如果 map 是null,返回默认值 {@link java.util.Collections#emptyMap()}. * @since 3.3.5 */ public static Map defaultEmptyMapIfNull(final Map map){ return defaultIfNull(map, emptyMap()); } //--------------------------------------------------------------- /** * 如果 list 是null,返回默认值 {@link com.feilong.core.util.CollectionsUtil#newArrayList()}. * *
     * ObjectUtil.defaultNewArrayListIfNull(null) = newArrayList();
     * ObjectUtil.defaultNewArrayListIfNull(toList(1)) = toList(1);
     * 
* * @param * the type of the object * @param list * the {@code Object} to test, may be {@code null} * @return 如果 list 是null,返回默认值 {@link com.feilong.core.util.CollectionsUtil#newArrayList()}. * @since 3.3.6 */ public static List defaultNewArrayListIfNull(final List list){ return defaultIfNull(list, newArrayList()); } /** * 如果 set 是null,返回默认值 {@link com.feilong.core.util.CollectionsUtil#newHashSet()}. * *
     * ObjectUtil.defaultNewHashSetIfNull(null) = newHashSet();
     * ObjectUtil.defaultNewHashSetIfNull(toSet(1)) = toSet(1);
     * 
* * @param * the type of the object * @param set * the {@code Object} to test, may be {@code null} * @return 如果 set 是null,返回默认值 {@link com.feilong.core.util.CollectionsUtil#newHashSet()}. * @since 3.3.6 */ public static Set defaultNewHashSetIfNull(final Set set){ return defaultIfNull(set, newHashSet()); } /** * 如果 map 是null,返回默认值 {@link com.feilong.core.util.MapUtil#newHashMap()}. * *
     * ObjectUtil.defaultNewHashMapIfNull(null) = newHashMap();
     * ObjectUtil.defaultNewHashMapIfNull(toMap("name", "zhangfei")) = toMap("name", "zhangfei");
     * 
* * @param * the key type * @param * the value type * @param map * the map * @return 如果 map 是null,返回默认值 {@link com.feilong.core.util.MapUtil#newHashMap()}. * @since 3.3.6 */ public static Map defaultNewHashMapIfNull(final Map map){ return defaultIfNull(map, newHashMap()); } /** * 如果 map 是null,返回默认值 {@link com.feilong.core.util.MapUtil#newLinkedHashMap()}. * *
     * ObjectUtil.defaultNewLinkedHashMapIfNull(null) = newLinkedHashMap();
     * ObjectUtil.defaultNewLinkedHashMapIfNull(toMap("name", "zhangfei")) = toMap("name", "zhangfei");
     * 
* * @param * the key type * @param * the value type * @param map * the map * @return 如果 map 是null,返回默认值 {@link com.feilong.core.util.MapUtil#newLinkedHashMap()}. * @since 3.3.6 */ public static Map defaultNewLinkedHashMapIfNull(final Map map){ return defaultIfNull(map, newLinkedHashMap()); } //--------------------------------------------------------------- /** * 如果 pageNo 是null或者{@code <}1,返回默认值 1. * *

* 用于分页处理页面的场景 *

* *
     * ObjectUtil.defaultPageNo(null)      = 1
     * ObjectUtil.defaultPageNo(0 )        = 1
     * ObjectUtil.defaultPageNo(8) = 8
     * 
* *

重构:

* *
*

* 对于以下代码: *

* *
     * 
     * page = defaultIfNull(page, 1);
     * searchQuery.setPageIndex(page <= 0 ? 1 : page);
     * 
     * 
* * 可以重构成: * *
     * searchQuery.setPageIndex(defaultPageNo(page));
     * 
* *
* * @param pageNo * the page no * @return 如果 pageNo 是null或者{@code <}1,返回 1,否则返回 pageNo * @since 3.3.2 */ public static Integer defaultPageNo(Integer pageNo){ return defaultIfNullOrLessThanOne(pageNo, 1); } /** * 如果 i 是null或者{@code <}0,返回默认值 0. * *
     * ObjectUtil.defaultZero(null)     = 0
     * ObjectUtil.defaultZero(-1)       = 0
     * ObjectUtil.defaultZero(0)        = 0
     * ObjectUtil.defaultZero(8)        = 8
     * 
* * @param i * i * @return 如果 i 是null或者{@code <}0,返回 0,否则返回 i * @since 4.0.1 */ public static Integer defaultZero(Integer i){ if (null == i){ return 0; } if (i < 0){ return 0; } return i; } /** * 如果 i 是null或者{@code <}1,返回默认值 defaultValue. * *

* 常用于分页处理页面的场景 *

* *
     * ObjectUtil.defaultIfNullOrLessThanOne(null, null)      = null
     * ObjectUtil.defaultIfNullOrLessThanOne(null, 1)        = 1
     * ObjectUtil.defaultIfNullOrLessThanOne(0, 2)        = 2
     * ObjectUtil.defaultIfNullOrLessThanOne(8, 2) = 8
     * 
* *

重构:

* *
*

* 对于以下代码: *

* *
     * 
     * page = defaultIfNull(page, 1);
     * searchQuery.setPageIndex(page <= 0 ? 1 : page);
     * 
     * 
* * 可以重构成: * *
     * searchQuery.setPageIndex(defaultIfNullOrLessThanOne(page, 1));
     * 
* *
* * @param i * the i * @param defaultValue * the default value to return, may be {@code null} * @return 如果 i 是null或者{@code <}1,返回 defaultValue,否则返回 object * @since 3.3.2 */ public static Integer defaultIfNullOrLessThanOne(Integer i,Integer defaultValue){ if (null == i){ return defaultValue; } if (i < 1){ return defaultValue; } return i; } //--------------------------------------------------------------- /** * 判断指定的对象 object是否是数组. * *

说明:

*
*
    *
  1. 支持判断原始类型数组 primitive 和包装类型数组
  2. *
*
* *

示例:

* *
* *
     * int[] i = {};
     * ObjectUtil.isArray(i);                       =true
     * 
     * ObjectUtil.isArray(new int[] { 1, 2, 3 });   =true
     * 
     * ObjectUtil.isArray(new Integer[0]);          =true
     * ObjectUtil.isArray(new String[0]);           =true
     * 
* *
* *

instanceof和 {@link java.lang.Class#isArray()}的区别:

* *
*

* 通常使用instanceof操作符去判断一个对象 object 是否是数组 array.
* 在JVM层次,instanceof操作符 translates to a specific "instanceof" byte code, which is highly optimized in most JVM * implementations.
*

* *

* 而反射的方法(getClass().isArray()) is compiled to two separate "invokevirtual" instructions.
* The more generic optimizations applied by the JVM to these may not be as fast as the hand-tuned optimizations inherent in the * "instanceof" instruction.
*

* *

* 有两种特殊情况: null references 和 primitive arrays.
*

* * * * * * * * * * * * * * * * * * * * * *
instanceofgetClass().isArray()
null referencefalseNullPointerException
原始类型数组primitive arrayfalsetrue
*
* * @param object * the object * @return 如果 object 是null,抛出 {@link NullPointerException}
* @see Java array reflection: isArray * vs. instanceof * @see How to see if * an object is an array without using reflection? * @since 1.3.0 */ public static boolean isArray(Object object){ Validate.notNull(object, "object can't be null!"); return object.getClass().isArray(); } //--------------------------------------------------------------- /** * 判断指定的对象 object 是否是原生类型数组. * *

示例:

* *
* *
     * 
     * ObjectUtil.isPrimitiveArray(1)                           = false
     * ObjectUtil.isPrimitiveArray(1L)                          = false
     * ObjectUtil.isPrimitiveArray("1")                         = false
     * 
     * 
     * ObjectUtil.isPrimitiveArray(new int[] {})                = true
     * ObjectUtil.isPrimitiveArray(new int[] { 1, 2 })          = true
     * ObjectUtil.isPrimitiveArray(new byte[] { 1, 2 })         = true
     * 
     * ObjectUtil.isPrimitiveArray(new String[] { "1", "2" })   = false
     * 
* *
* * @param object * the object * @return 如果 object 是null,抛出 {@link NullPointerException}
* @since 1.8.4 */ public static boolean isPrimitiveArray(Object object){ Validate.notNull(object, "object can't be null!"); return isArray(object) && object.getClass().getComponentType().isPrimitive();//原始型的 } //--------------------------------------------------------------- /** *

* 对比 given {@code t} to a vararg of {@code searchTargets}, * 如果 {@code true} if the {@code t} is equal to any of the {@code searchTargets}. *

* *

* 比 apache commons-lang3 StringUtils#equalsAny 适用面更广 *

* *
     * ObjectUtil.equalsAny(null, (CharSequence[]) null) = false
     * ObjectUtil.equalsAny(null, null, null)    = true
     * ObjectUtil.equalsAny(null, "abc", "def")  = false
     * ObjectUtil.equalsAny("abc", null, "def")  = false
     * ObjectUtil.equalsAny("abc", "abc", "def") = true
     * ObjectUtil.equalsAny("abc", "ABC", "DEF") = false
     * ObjectUtil.equalsAny(5, 5, 6) = true
     * 
* * @param * the generic type * @param t * to compare, may be {@code null}. * @param searchTargets * a vararg of t, may be {@code null}. * @return {@code true} 如果 t is equal to any other element of {@code searchTargets}; * {@code false} if {@code searchTargets} is null or contains no matches. * @see com.feilong.lib.lang3.StringUtils#equalsAny(CharSequence, CharSequence...) * @since 3.1.0 */ @SafeVarargs public static boolean equalsAny(T t,T...searchTargets){ if (isNullOrEmpty(searchTargets)){ return false; } //--------------------------------------------------------------- for (T target : searchTargets){ if (Objects.equals(t, target)){ return true; } } return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy