StringUtils在commons-lang3和commons-lang中的区别

(1)入参类型不同
commons.lang中入参为 Sring str
commons.lang3中入参为 CharSequence cs(适用范围更广)
(2)入参数量不同
commons.lang3中支持多入参

最近经常需要对String做一些判断和处理,于是就用到了Apache提供的StringUtils这个工具类,用的时候发现有两个不同的版本,一个版本位于org.apache.commons.lang下面,另一个则位于org.apache.commons.lang3下面。

查了一下资料,lang3是Apache Commons 团队发布的工具包,要求jdk版本在1.5以上,相对于lang来说完全支持java5的特性,废除了一些旧的API。该版本无法兼容旧有版本,于是为了避免冲突改名为lang3。这些东西就不再细说了,我们来看看StringUtils中常用的一些方法有什么改变吧。

PS.本文的java版本为1.8。

1.isEmpty、isNotEmpty、isBlank、isNotBlank先贴源码

//lang
 public static boolean isEmpty(String str) {
     return str == null || str.length() == 0;
 }

 public static boolean isNotEmpty(String str) {
     return !isEmpty(str);
 }

 public static boolean isBlank(String str) {
     int strLen;
     if(str != null && (strLen = str.length()) != 0) {
         for(int i = 0; i < strLen; ++i) {
             if(!Character.isWhitespace(str.charAt(i))) {
                 return false;
             }
         }
         return true;
      } else {
         return true;
      }
 }

 public static boolean isNotBlank(String str) {
     return !isBlank(str);
 }
//lang3
public static boolean isEmpty(CharSequence cs) {
   return cs == null || cs.length() == 0;
}

public static boolean isNotEmpty(CharSequence cs) {
   return !isEmpty(cs);
}

public static boolean isBlank(CharSequence cs) {
   int strLen;
   if(cs != null && (strLen = cs.length()) != 0) {
       for(int i = 0; i < strLen; ++i) {
           if(!Character.isWhitespace(cs.charAt(i))) {
               return false;
           }
       }
       return true;
   } else {
       return true;
   }
}

public static boolean isNotBlank(CharSequence cs) {
    return !isBlank(cs);
}

可以看到这几个方法逻辑毫无变化,只是参数类型变了,由String变为CharSequence。那么这个CharSequence是什么呢?我们看看它的源码:

/**
* A <tt>CharSequence</tt> is a readable sequence of <code>char</code> values. This
* interface provides uniform, read-only access to many different kinds of
* <code>char</code> sequences.
* A <code>char</code> value represents a character in the <i>Basic
* Multilingual Plane (BMP)</i> or a surrogate. Refer to <a
* href="Character.html#unicode">Unicode Character Representation</a> for details.
*
* <p> This interface does not refine the general contracts of the {@link
* java.lang.Object#equals(java.lang.Object) equals} and {@link
* java.lang.Object#hashCode() hashCode} methods.  The result of comparing two
* objects that implement <tt>CharSequence</tt> is therefore, in general,
* undefined.  Each object may be implemented by a different class, and there
* is no guarantee that each class will be capable of testing its instances
* for equality with those of the other.  It is therefore inappropriate to use
* arbitrary <tt>CharSequence</tt> instances as elements in a set or as keys in
* a map. </p>
*
* @author Mike McCloskey
* @since 1.4
* @spec JSR-51
*/

public interface CharSequence {
    int length();
    char charAt(int index);
    CharSequence subSequence(int start, int end);
    public String toString();
}

CharSequence是一个字符序列的接口,其中定义了一些常用的如length()、subSequence()等方法,String也实现了这个接口。当然大家可能在String里用到的都是subString(),实际上String也实现了subSequence()这个方法,只是直接指向了subString()。

//String中的subSequence方法
public CharSequence subSequence(int beginIndex, int endIndex) {
    return this.substring(beginIndex, endIndex);
}

lang3中使用CharSequence最大的好处就是令这些方法用处更加广泛,不止局限于String,其他一些实现了该接口的类也可以使用StringUtils中的这些方法去进行一些操作。另外我发现很多nio中的类都实现了这个接口,个人猜测可能也有为nio服务的目的。

2.equals

//lang
public static boolean equals(String str1, String str2) {
   return str1 == null?str2 == null:str1.equals(str2);
}
//lang3
public static boolean equals(CharSequence cs1, CharSequence cs2) {
    return cs1 == cs2?true:(cs1 != null && cs2 != null?(cs1.length() != cs2.length()?false:(cs1 instanceof String && cs2 instanceof String?cs1.equals(cs2):CharSequenceUtils.regionMatches(cs1, false, 0, cs2, 0, cs1.length()))):false);
}

在lang中,第一步是先判断str1是否为空,而在lang3中,第一步则是先判断两个对象是否相同。这个不难理解,如果两个对象的地址相同,那么它们指向的就是同一个对象,内容肯定相同。

3.isAnyEmpty、isNoneEmpty、isAllEmpty

//lang3
public static boolean isAnyEmpty(CharSequence... css) {
    if(ArrayUtils.isEmpty(css)) {
        return false;
    } else {
        CharSequence[] var1 = css;
        int var2 = css.length;
        for(int var3 = 0; var3 < var2; ++var3) {
            CharSequence cs = var1[var3];
            if(isEmpty(cs)) {
                return true;
            }
         }
         return false;
     }
 }

public static boolean isNoneEmpty(CharSequence... css) {
    return !isAnyEmpty(css);
}

public static boolean isAllEmpty(CharSequence... css) {
    if(ArrayUtils.isEmpty(css)) {
        return true;
    } else {
        CharSequence[] var1 = css;
        int var2 = css.length;
        for(int var3 = 0; var3 < var2; ++var3) {
            CharSequence cs = var1[var3];
            if(isNotEmpty(cs)) {
                return false;
            }
        }
        return true;
    }
}

在lang3中,还加入了一些同时判断多个参数的方法,可以看到实际上是将参数列表放入一个CharSequence数组中,然后遍历调用之前的isEmpty等方法。判断blank也有类似的方法。

可能有人会觉得,很多方法String本身就有啊,为什么还要用StringUtils提供的呢?抛开参数类型不谈,我们可以看到,StringUtils中的方法大多都做了空校验,如果为空时会返回Null或者空串,而String本身的方法在很多传入参数或对象本身为空的时候都会报空指针错误。

参考地址:StringUtils在commons-lang3和commons-lang中的区别

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容