• org.apache.commons.lang3.StringUtils 源码解读(1)


    一、背景

      不管是公司的项目,还是个人的日常练习,都会使用 org.apache.commons.lang3.StringUtils 这个String工具类,究其原因,是太好用了,而且太全了。比如判断是否为空,截取,拼接之类的。一直没有仔细的看过它的源码,今天我就研究一番,同时作为我“阅读源码”路上的第一步。

    二、常用API

      注:本次是基于commons-lang3-3.8.1 进行阅读分析总结的,其他版本与此相差不多。

    2.0、概念释义

    2.0.1、null,empty,space的区别

        null:代表无效数据,调用其他Api会有NPE异常;

        empty:是有效数据,表示一个长度为0的字符串——"";

        space:是有效数据,表示一个长度不为0,但是没有任何内容的字符串——“          ”,其trim后和empty是等价的;

    2.0.2、什么是CharSequence

        查看StringUtils的源码,你会发现它的方法参数里面经常会出现一个类型:CharSequence。所以有必要在这里解释一下。

        CharSequence是一个描述字符串结构的接口,它的常用方法有length(),charAt(),toString 。很熟悉对吧。它的常见实现类有String,StringBuffer,StringBuilder。只要有字符串就可以为CharSequence实例化。

    public interface CharSequence {
    
       int length(); 
    
       char charAt(int index);
        
       public String toString();
       
    //
    字符串截取 CharSequence subSequence(int start,int end);
    public
    default IntStream chars() {   
        //默认逻辑
      }

      public default IntStream codePoints() {   
        //默认逻辑
      }
    }
    //String
    public final class String implements java.io.Serializable, Comparable<String>, CharSequence
    
    //StringBuffer
    public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence
    
    //StringBuilder
    public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence

    2.1、Empty

    2.1.1、isEmpty:检查字符串是 "" 或 null

    //源码
    public static boolean isEmpty(final CharSequence cs) {
        return cs == null || cs.length() == 0;
    }
    @Test
    public void isEmpty_Test() {
       //true
       StringUtils.isEmpty(null);
       //true
       StringUtils.isEmpty("");
       //false
       StringUtils.isEmpty("  ");
       //false
       StringUtils.isEmpty("bob");
       //false
       StringUtils.isEmpty(" bob ");
    }

    2.1.2、isNotEmpty:与isEmpty正好相反,判断不为""且不为null   

    //源码
    public static boolean isNotEmpty(final CharSequence cs) {
         return !isEmpty(cs);
    }  
    @Test
    public void isNotEmpty_Test() {
        //false
        StringUtils.isNotEmpty(null);
        //false
        StringUtils.isNotEmpty("");
        //true
        StringUtils.isNotEmpty(" ");
        //true
        StringUtils.isNotEmpty("bob");
        //true
        StringUtils.isNotEmpty("  bob  ");
    }

    2.1.3、isAnyEmpty

    2.1.4、isNoneEmpty

    2.1.5、isAllEmpty

    2.2、Blank

    2.2.1、isBlank:检查一个字符串是 "",或null,或只有空格

    与isEmpty相比,对于“    ”,isEmpty("  ") =false,isBlank("  ") =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++) {
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    } 
    @Test
    public void isBlank_Test() {
        //true
        StringUtils.isBlank(null);
        //true
        StringUtils.isBlank("");
        //true
        StringUtils.isBlank(" ");
        //false
        StringUtils.isBlank("bob");
        //false
        StringUtils.isBlank("  bob  ");
    }

    2.2.2、isNotBlank:检查一个字符串不是 "",且不是null,且不只有空格   

    @Test
    public void isNotBlank_Test() {
        //false
        StringUtils.isNotBlank(null);
        //false
        StringUtils.isNotBlank("");
        //false
        StringUtils.isNotBlank(" ");
        //true
        StringUtils.isNotBlank("bob");
        //true
        StringUtils.isNotBlank("  bob  ");
    }

    2.2.3、isAnyBlank

    2.2.4、isNoneBlank

    2.2.5、isAllBlank

    2.3、Trim

    2.3.1、trim:移除字符串两端的空字符串 

    //源码
    public static String trim(final String str) {
         return str == null ? null : str.trim();
    } 
    @Test
    public void trim_Test() {
        //null    
        StringUtils.trim(null);
        //""             
        StringUtils.trim("");
        //""             
        StringUtils.trim("     ");
        //"abc"           
        StringUtils.trim("abc");
        //"abc"             
        StringUtils.trim("    abc    ");
    }

    2.3.2、trimToNull:trim之后,用isEmpty进行了判断,如果true返回null,否则返回trim后的值  

    //源码
    public static String trimToNull(final String str) {
        final String ts = trim(str);
        return isEmpty(ts) ? null : ts;
    }
    StringUtils.trimToNull(null)          = null
    StringUtils.trimToNull("")            = null
    StringUtils.trimToNull("     ")       = null
    StringUtils.trimToNull("abc")         = "abc"
    StringUtils.trimToNull("    abc    ") = "abc"

    2.3.3、trimToEmpty:如果为null,返回“”,否则返回trim后的值

    //源码
    public static String trimToEmpty(final String str) {
        return str == null ? EMPTY : str.trim();
    }
    StringUtils.trimToEmpty(null)          = ""
    StringUtils.trimToEmpty("")            = ""
    StringUtils.trimToEmpty("     ")       = ""
    StringUtils.trimToEmpty("abc")         = "abc"
    StringUtils.trimToEmpty("    abc    ") = "abc"

    2.4、Truncate

    2.4.1、truncate:字符串截取,从索引为0处截取,截取固定的长度

    //源码
    public static String truncate(final String str, final int maxWidth) {
        return truncate(str, 0, maxWidth);
    }
    StringUtils.truncate(null, 0)       = null
    StringUtils.truncate(null, 2)       = null
    StringUtils.truncate("", 4)         = ""
    StringUtils.truncate("abcdefg", 4)  = "abcd"
    StringUtils.truncate("abcdefg", 6)  = "abcdef"
    StringUtils.truncate("abcdefg", 7)  = "abcdefg"
    StringUtils.truncate("abcdefg", 8)  = "abcdefg"
    StringUtils.truncate("abcdefg", -1) = throws an IllegalArgumentException

          

        可以看到,对于起始截取索引,截取长度为负数时,直接报异常;然后被截取字符串为null时,返回null;截取索引大于字符串长度时,返回“”。

    //源码
    public static String truncate(final String str, final int offset, final int maxWidth) {
        if (offset < 0) {
            throw new IllegalArgumentException("offset cannot be negative");
        }
        if (maxWidth < 0) {
            throw new IllegalArgumentException("maxWith cannot be negative");
        }
        if (str == null) {
            return null;
        }
        if (offset > str.length()) {
            return EMPTY;
        }
        if (str.length() > maxWidth) {
            final int ix = offset + maxWidth > str.length() ? str.length() : offset + maxWidth;
            return str.substring(offset, ix);
        }
        return str.substring(offset);
    }
    StringUtils.truncate(null, 0, 0) = null
    StringUtils.truncate(null, 2, 4) = null
    StringUtils.truncate("", 0, 10) = ""
    StringUtils.truncate("", 2, 10) = ""
    StringUtils.truncate("abcdefghij", 0, 3) = "abc"
    StringUtils.truncate("abcdefghij", 5, 6) = "fghij"
    StringUtils.truncate("raspberry peach", 10, 15) = "peach"
    StringUtils.truncate("abcdefghijklmno", 0, 10) = "abcdefghij"
    StringUtils.truncate("abcdefghijklmno", -1, 10) = throws an IllegalArgumentException
    StringUtils.truncate("abcdefghijklmno", Integer.MIN_VALUE, 10) = "abcdefghij"
    StringUtils.truncate("abcdefghijklmno", Integer.MIN_VALUE, Integer.MAX_VALUE) = "abcdefghijklmno"
    StringUtils.truncate("abcdefghijklmno", 0, Integer.MAX_VALUE) = "abcdefghijklmno"
    StringUtils.truncate("abcdefghijklmno", 1, 10) = "bcdefghijk"
    StringUtils.truncate("abcdefghijklmno", 2, 10) = "cdefghijkl"
    StringUtils.truncate("abcdefghijklmno", 3, 10) = "defghijklm"
    StringUtils.truncate("abcdefghijklmno", 4, 10) = "efghijklmn"
    StringUtils.truncate("abcdefghijklmno", 5, 10) = "fghijklmno"
    StringUtils.truncate("abcdefghijklmno", 5, 5) = "fghij"
    StringUtils.truncate("abcdefghijklmno", 5, 3) = "fgh"
    StringUtils.truncate("abcdefghijklmno", 10, 3) = "klm"
    StringUtils.truncate("abcdefghijklmno", 10, Integer.MAX_VALUE) = "klmno"
    StringUtils.truncate("abcdefghijklmno", 13, 1) = "n"
    StringUtils.truncate("abcdefghijklmno", 13, Integer.MAX_VALUE) = "no"
    StringUtils.truncate("abcdefghijklmno", 14, 1) = "o"
    StringUtils.truncate("abcdefghijklmno", 14, Integer.MAX_VALUE) = "o"
    StringUtils.truncate("abcdefghijklmno", 15, 1) = ""
    StringUtils.truncate("abcdefghijklmno", 15, Integer.MAX_VALUE) = ""
    StringUtils.truncate("abcdefghijklmno", Integer.MAX_VALUE, Integer.MAX_VALUE) = ""
    StringUtils.truncate("abcdefghij", 3, -1) = throws an IllegalArgumentException
    StringUtils.truncate("abcdefghij", -2, 4) = throws an IllegalArgumentException

    2.5、Strip

    2.5.1、strip

    2.5.2、stripToNull

    2.5.3、StripToEmpty

    2.5.4、stripStart 

    //null
    System.out.println(StringUtils.stripStart(null,"xyzbca"));
    //""
    System.out.println(StringUtils.stripStart("","xyzbca"));
    
    //"abc  "
    String s1 = StringUtils.stripStart("abc  ",null);
    System.out.println(s1+","+s1.length());
    //**abc   **
    String s2 = StringUtils.stripStart( "   abc   ",null);
    System.out.println("**"+s2+"**");
    //** abc **
    String s3 = StringUtils.stripStart(" abc ","");
    System.out.println("**"+s3+"**");
    
    //bc
    String s4 = StringUtils.stripStart("abc", "a");
    System.out.println(s4);
    //bcysz
    String s5 = StringUtils.stripStart("xyabcysz","yax");
    System.out.println(s5)   
    //源码
    public static String stripStart(final String str, final String stripChars) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
              return str;
        }
        int start = 0;
        if (stripChars == null) {
            while (start != strLen && Character.isWhitespace(str.charAt(start))) {
                start++;
            }
        } else if (stripChars.isEmpty()) {
            return str;
        } else {
            while (start != strLen && stripChars.indexOf(str.charAt(start)) != -1) {
                start++;
            }
        }
        return str.substring(start);
    }

    2.5.5、stripEnd

    //源码
    public static String stripEnd(final String str, final String stripChars) {
        int end;
        if (str == null || (end = str.length()) == 0) {
            return str;
        }
    
        if (stripChars == null) {
            while (end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
                end--;
            }
        } else if (stripChars.isEmpty()) {
            return str;
        } else {
            while (end != 0 && stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND) {
                end--;
            }
        }
        return str.substring(0, end);
    }

    2.5.6、stripAll

    2.5.7、stripAccents

    2.6、Equals、toString

    2.6.1、equals

    2.6.2、equalsIgnoreCase

    2.6.3、equalsAny

    2.6.4、equalsAnyIgnoreCase

    2.6.5、toString

    2.6.6、toEncodedString

    2.7、Compare

    2.7.1、compare

    2.7.2、compareIgnoreCase

    2.8、IndexOf

    2.8.1、indexOf

    2.8.2、ordinalIndexOf

    2.8.3、indexOfIgnoreCase

    2.8.4、lastIndexOf

    2.8.5、lastOrdinalIndexOf

    2.8.6、lastIndexOfIgnoreCase

    2.8.7、indexOfAny

    2.8.8、indexOfAnyBut

    2.8.9、lastIndexOfAny

     

    2.9、Contains

    2.9.1、contains

    2.9.2、containsIgnoreCase

    2.9.3、containsWhitespace

    2.9.4、containsAny

    2.9.5、containsOnly

    2.9.6、containsNone

    2.10、Substring

    2.10.1、substring

    2.10.2、left

    2.10.3、right

    2.10.4、mid

    2.10.5、substringBefore

    2.10.6、substringAfter

    2.10.7、substringBeforeLast

    2.10.8、substringAfterLast

    2.10.9、substringsBetween

    2.11、Split

    2.11.1、split

    2.11.2、splitByWholeSeparator

    2.11.3、splitByWholeSeparatorPreserveAllTokens

    2.11.4、splitByWholeSeparatorWorker

    2.11.5、splitPreserveAllTokens

    2.11.6、splitWorker

    2.11.7、splitByCharacterType

    2.11.8、splitByCharacterTypeCamelCase

     

    2.12、Join

    2.12.1、join

    2.12.1、joinWith

    2.13、Delete

    2.13.1、deleteWhitespace

    2.14、Remove

    2.14.1、remove

    2.14.2、removeIgnoreCase

    2.14.3、removeStart

    2.14.4、removeStartIgnoreCase

    2.14.5、removeEnd

    2.14.6、removeEndIgnoreCase

    2.14.7、removeAll

    2.14.8、removeFirst

    2.14.9、removePattern

    2.15、Replace

    2.15.1、replace

    2.15.2、replaceIgnoreCase

    2.15.3、replaceOnce

    2.15.4、replaceOnceIgnoreCase

    2.15.5、replacePattern

    2.15.6、replaceAll

    2.15.7、replaceFirst

    2.15.8、replaceEach

    2.15.9、replaceEachRepeatedly

    2.15.10、replaceChars

    2.16、Overlay

    2.16.1、overlay

    2.17、Chomping

    2.17.1、chomp

    2.18、Chop

    2.18.1、chop

    2.19、Repeat

    2.19.1、repeat

    2.20、Pad

    2.20.1、rightPad

    2.20.2、leftPad

    2.21、Length

    2.21.1、length

    2.22、Center

    2.22.1、center

    2.23、Case

    2.23.1、upperCase

    2.23.2、lowerCase

    2.23.3、swapCase

    2.24、Capitalize

    2.24.1、capitalize

    2.24.2、uncapitalize

    2.25、CountMatches

    2.25.1、countMatches

    2.26、判断/检查

    2.26.1、isAlpha

    2.26.2、isAlphaSpace

    2.26.3、isAlphanumeric

    2.26.4、isAlphanumericSpace

    2.26.5、isAsciiPrintable

    2.26.6、isNumeric

    2.26.7、isNumericSpace

    2.26.8、isWhitespace

    2.26.9、isAllLowerCase

    2.26.10、isAllUpperCase

    2.26.11、isMixedCase



    2.27、Default

    2.27.1、defaultString

    2.27.2、defaultIfBlank

    2.27.3、defaultIfEmpty

    2.28、Rotate

    2.28.1、rotate

    2.29、Reverse

    2.29.1、reverse

    2.29.1、reverseDelimited



    2.30、Abbreviate

    2.30.1、abbreviate

    2.30.2、abbreviateMiddle



    2.31、Difference

    2.31.1、difference

    2.31.2、indexOfDeffererce



    2.32、开头/结尾

    2.32.1、startsWith

    2.32.2、startsWithIgnoreCase

    2.32.3、startsWithAny

    2.32.4、endsWith

    2.32.5、endsWithIgnoreCase

    2.32.6、endsWithAny

    
    

    2.33、追加

    2.33.1、appendIfMissing

    2.33.2、appendIfMissingIgnoreCase

    2.33.3、prependIfMissing

    2.33.4、prependIfMissingIgnoreCase

    2.34、Wrap

    2.34.1、wrap

    2.34.2、wrapIfMissing

    2.34.3、unwrap



    2.35、其他

    2.35.1、getCommonPrefix

    2.35.2、getLevenshteinDistance

    2.35.3、getJaroWinklerDistance

    2.35.4、getFuzzyDistance

    2.35.5、getDigits

    2.35.6、firstNonBlank

    2.35.7、firstNonEmpty

    2.35.8、normalizeSpace

    2.35.9、toCodePoints



    在全栈的道路上,积极向上、成熟稳重、谦虚好学、怀着炽热的心向前方的走得更远。
  • 相关阅读:
    UIProgressView的详细使用
    Android拍照上传代码样例
    UILabel的详细使用及特殊效果
    TextView属性android:ellipsize实现跑马灯效果
    Android中WebView实现Javascript调用Java类方法
    有效获取状态栏(StatusBar)高度
    详解iPhone Tableview分批显示数据
    TextView显示插入的图片
    ObjectiveC语法快速参考
    UISegmentedControl的详细使用
  • 原文地址:https://www.cnblogs.com/DDgougou/p/13250684.html
Copyright © 2020-2023  润新知