Java常用工具类整理

目录

 

1  org.apache.commons.lang3.StringUtils

1.1 isBlank

1.2 isEmpty

1.3 blank系列

1.4 empty系列

1.5 trim

1.6 isNumeric

2 org.apache.commons.collections4.CollectionUtils

2.1 isEmpty

3 org.apache.commons.collections4.MapUtils

2.1 isEmpty

4 org.springframework.beans.BeanUtils

4.1 copyProperties

Java内省机制:getPropertyDescriptors(Class clazz) 

遇到的问题:类的内部类不会被copy?

Java内省机制了解下

5 com.google.common.collect.Maps

6 com.google.common.collect.Lists


1  org.apache.commons.lang3.StringUtils

1.1 isBlank

字符串为null""字符串只含有空格返回true

    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            //当前字符不是空格则返回false
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }

试一下:

- StringUtils.isBlank(""): true
- "".length: 0
- StringUtils.isBlank(" "): true
- " ".length: 1
- StringUtils.isBlank("bob"): false
- StringUtils.isBlank(" bob "): false

1.2 isEmpty

字符串为null""返回true

    public static boolean isEmpty(final CharSequence cs) {
        return cs == null || cs.length() == 0;
    }

1.3 blank系列

isAnyBlank:存在任意一个为blank
isNoneBlank:没有blank,非isAnyBlank
isAllBlank:全都是blank
    // StringUtils.isAnyBlank(new String[] {})  = false
    public static boolean isAnyBlank(final CharSequence... css) {
      if (ArrayUtils.isEmpty(css)) {
        return false;
      }
      for (final CharSequence cs : css){
        if (isBlank(cs)) {
          return true;
        }
      }
      return false;
    }


    // StringUtils.isAllBlank(new String[] {})  = true
    public static boolean isAllBlank(final CharSequence... css) {
        if (ArrayUtils.isEmpty(css)) {
            return true;
        }
        for (final CharSequence cs : css) {
            if (isNotBlank(cs)) {
               return false;
            }
        }
        return true;
    }

1.4 empty系列

类同1.3blank系列

1.5 trim

去掉前后的控制符(control characters, char <= 32),如果使用字符串的trim方法,str为null就会报错,StringUtils做了一层友好封装

    // StringUtils.trim(" \b \t \n \f \r ") = ""
    public static String trim(final String str) {
        return str == null ? null : str.trim();
    }
trimToEmpty:return str == null ? EMPTY : str.trim();

与trim不同的是,如果str为null,返回""

trimToNull:return isEmpty(trim(str)) ? null : trim(str);

与trim不同的是,若trim后的结果为empty,则返回null

1.6 isNumeric

检查CharSequence是否仅包含Unicode数字。小数点不是Unicode数字,并且返回false。

    public static boolean isNumeric(final CharSequence cs) {
        if (isEmpty(cs)) {
            return false;
        }
        final int sz = cs.length();
        for (int i = 0; i < sz; i++) {
            if (!Character.isDigit(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    // 返回一个值,该值指示字符的常规类别
    public static boolean isDigit(int codePoint) {
        return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
    }

    /**
     * General category "Nd" in the Unicode specification.
     * @since   1.1
     */
    public static final byte DECIMAL_DIGIT_NUMBER        = 9;

Unicode是一个编码方案(字符集),Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,至于这个二进制代码如何存储则没有任何规定。它的想法很简单,就是为每个字符规定一个用来表示该字符的数字。

根据一定规则去给这些字符集分类,Unicode数字类的type就是DECIMAL_DIGIT_NUMBER,9

2 org.apache.commons.collections4.CollectionUtils

2.1 isEmpty

集合判空

    public static boolean isEmpty(final Collection<?> coll) {
        return coll == null || coll.isEmpty();
    }

coll.isEmpty()是接口Collection的方法,根据不同实现类对象调用对应实现类的isEmpty()

3 org.apache.commons.collections4.MapUtils

2.1 isEmpty

类同2 CollectionUtils

    public static boolean isEmpty(final Map<?,?> map) {
        return map == null || map.isEmpty();
    }

4 org.springframework.beans.BeanUtils

4.1 copyProperties

将给定源bean的属性值复制到目标bean中。
注意:只要属性匹配,源类和目标类就不必相互匹配,甚至不必彼此派生。 源Bean公开但目标Bean没有公开的任何Bean属性都将被忽略。

public static void copyProperties(Object source, Object target) throws BeansException {
    copyProperties(source, target, null, (String[]) null);
}

看源码

private static void copyProperties(Object source, Object target, @Nullable Class<?> editable,
                                   @Nullable String... ignoreProperties) throws BeansException {

    Assert.notNull(source, "Source must not be null");
    Assert.notNull(target, "Target must not be null");

    Class<?> actualEditable = target.getClass();
    // null
    if (editable != null) {
        if (!editable.isInstance(target)) {
            throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
                    "] not assignable to Editable class [" + editable.getName() + "]");
        }
        actualEditable = editable;
    }

    // 核心方法:检索给定类的JavaBeans:获取目标bean的所有属性
    PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
    // null
    List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

    // 循环目标bean的所有属性
    for (PropertyDescriptor targetPd : targetPds) {
        Method writeMethod = targetPd.getWriteMethod();
        if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
            // 核心方法:获取targetPd对应源bean的属性
            PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
            if (sourcePd != null) {
                Method readMethod = sourcePd.getReadMethod();
                if (readMethod != null &&
                        ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                    try {
                        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                            readMethod.setAccessible(true);
                        }
                        // 读取源bean的sourcePd属性的值(调用源bean的getter方法)
                        Object value = readMethod.invoke(source);
                        if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                            writeMethod.setAccessible(true);
                        }
                        // 写入目标bean的targetPd属性(调用目标bean的setter方法)
                        writeMethod.invoke(target, value);
                    }
                    catch (Throwable ex) {
                        throw new FatalBeanException(
                                "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
                    }
                }
            }
        }
    }
}

Java内省机制:getPropertyDescriptors(Class<?> clazz) 

内省获取javaBean中的字段,通过获取强引用或者软引用或者新建立一个安全的缓存内省,最后返回的就是javaBean中的有get或set方法的字段,如下图,获取的第一个字段为class,因为Object有getClass方法,所以只有readMethod方法

所以实体类若没有用set或get方法是获取不到属性的,如下图,source实体类没有set或get方法,获取的PropertyDescriptor为null

遇到的问题:类的内部类不会被copy?

原因:对于两个实体类来说,两个内部类类型并不一样,如下图,所以不会被copy

ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())

Java内省机制了解下

内省机制:是对于java Bean的缺省处理,既比如在一个实体类中,有nama、address属性,那么系统会默认在此类中会有get/set方法进行获得和设置这两个值的方法。通过类 Introspector 的 getBeanInfo方法 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。

内省机制类介绍:

Introspector:将JavaBean中的属性封装起来进行操作。在程序把一个类当做JavaBean来看,就是调用Introspector.getBeanInfo()方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息,即属性的信息

BeanInfo:将类中的信息封装到BeanInfo中,获得了BeanInfo对象就相当于获得了类中的所有属性信息。调用getPropertyDescriptors()方法获得属性描述器,即获得了所有的属性信息。调用

PropertyDescriptorPropertyDescriptor实例封装了每个属性特有的一些性质,比如调用getReadMethod()方法就能获得这个属性的get方法Method,调用getWriteMethod()方法就能获得这个属性的set方法Method。

与反射的区别?(反射相关内容可见:反射

       反射是在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。

       内省(IntroSpector)是是对于java Bean的缺省处理,系统会默认在类中会有get/set方法进行获得和设置私有属性值的方法。BeanInfo用来暴露一个bean的属性、方法和事件,再去通过反射来操作。

5 com.google.common.collect.Maps

5.1 newHashMap

之前使用的Map map = new HashMap();Map.newHashMap只是将new HashMap<>()包了一层,比较简洁一点,没啥太大区别

public static <K, V> HashMap<K, V> newHashMap() {
    return new HashMap<>();
}

public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    map.put("name", "123");


    Map<String, String> guavaMap = Maps.newHashMap();
    guavaMap.put("sex", "111");


    log.info(map.get("name"));
    log.info(guavaMap.get("sex"));
}

6 com.google.common.collect.Lists

6.1 newArrayList

与Maps不同的是,Lists提供了Lists.newArrayList(T... elements);

@SafeVarargs
public static <T> ArrayList<T> newArrayList(T... elements) {
    if (elements == null) {
      return null;
    }
    ArrayList<T> list = newArrayList();
    java.util.Collections.addAll(list, elements);
    return list;
}


public static <T> ArrayList<T> newArrayList() {
    return new ArrayList<>();
}


public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    
    
    List<Integer> guavaList = Lists.newArrayList(1,2);
    

    log.info(list.toString());
    log.info(guavaList.toString());
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值