JAVA類String

  • 2019 年 12 月 15 日
  • 筆記

今天要講的是JDK中的String類了,相信大家對這個類特別的熟悉,那今天話不多說,直接講一些常用的方法。

首先有個內部類:

    private static class CaseInsensitiveComparator    implements Comparator<String>, java.io.Serializable {    // use serialVersionUID from JDK 1.2.2 for interoperability    private static final long serialVersionUID = 8575799808933029326L;      public int compare(String s1, String s2) {      int n1 = s1.length();      int n2 = s2.length();      int min = Math.min(n1, n2);      for (int i = 0; i < min; i++) {          char c1 = s1.charAt(i);          char c2 = s2.charAt(i);          if (c1 != c2) {              c1 = Character.toUpperCase(c1);              c2 = Character.toUpperCase(c2);              if (c1 != c2) {                  c1 = Character.toLowerCase(c1);                  c2 = Character.toLowerCase(c2);                  if (c1 != c2) { // 某些字母大寫是無法比較的,所以這裡還是得判斷一下                      // No overflow because of numeric promotion                      return c1 - c2;                  }              }          }      }      return n1 - n2;  }        /** Replaces the de-serialized object. */      private Object readResolve() { return CASE_INSENSITIVE_ORDER; }  }    //再看下這個內部類在String類中的使用  public static final Comparator<String> CASE_INSENSITIVE_ORDER                                           = new CaseInsensitiveComparator();    public int compareToIgnoreCase(String str) {      return CASE_INSENSITIVE_ORDER.compare(this, str);  }  String str1 = "abba";  String str2 = "Abba";  str1.compareToIgnoreCase(str2) ---  0 完全匹配    String str1 = "abba";  String str2 = "Abba";  str1.compareToIgnoreCase(str2) ---  1 包含      String str1 = "abba";  String str2 = "Abbac";  str1.compareToIgnoreCase(str2) ---  -1 不匹配                                                     

屬性:

private final char value[]; // 很明白了 用value存  private int hash;    // constructor  public String(String original) {      this.value = original.value;      this.hash = original.hash;  }  //  // 順便看下這個hash  public int hashCode() {      int h = hash;      if (h == 0 && value.length > 0) {          char val[] = value;            for (int i = 0; i < value.length; i++) {              h = 31 * h + val[i]; // val[0]*31^(n-1) + val[1]*31^(n-2) + ... + val[n-1]          }          hash = h;      }      return h;  }  // val[0]*31^(n-1) + val[1]*31^(n-2) + ... + val[n-1]  // n是字元串的長度 很明顯n比較大的時候就會溢出 這樣也證明hashCode相同的String串,其內容不一定相同

METHOD

// 方法  public int length() {      return value.length; // 返回char數組的length 很簡單 包裝成方法了  }  public boolean isEmpty() {      return value.length == 0;  }  // 返回指定下標的字元  public char charAt(int index) {      if ((index < 0) || (index >= value.length)) {          throw new StringIndexOutOfBoundsException(index);      }      return value[index]; // 還是數組操作  }  // 把字元串放入char數字  void getChars(char dst[], int dstBegin) {      System.arraycopy(value, 0, dst, dstBegin, value.length);  }  // 把字元串中srcBegin到srcEnd - 1放到從char數組dstBegin開始往後的空間  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {      if (srcBegin < 0) {          throw new StringIndexOutOfBoundsException(srcBegin);      }      if (srcEnd > value.length) {          throw new StringIndexOutOfBoundsException(srcEnd);      }      if (srcBegin > srcEnd) {          throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);      }      System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);  }  // 比較這個是重寫的Object方法  public boolean equals(Object anObject) {  // 地址一樣返回true      if (this == anObject) {          return true;      }  // 地址不一樣如果是String那麼會繼續比較內容      if (anObject instanceof String) {          String anotherString = (String)anObject;          int n = value.length;          if (n == anotherString.value.length) {              char v1[] = value;              char v2[] = anotherString.value;              int i = 0;  //循環比較              while (n-- != 0) {                  if (v1[i] != v2[i])                      return false;                  i++;              }              return true;          }      }      return false;  }  // 以什麼開始 從字元串的toffset開始比較  public boolean startsWith(String prefix, int toffset) {      char ta[] = value;      int to = toffset;// 從to開始      char pa[] = prefix.value;      int po = 0;      int pc = prefix.value.length;      // Note: toffset might be near -1>>>1.      if ((toffset < 0) || (toffset > value.length - pc)) {          return false;      }  // 一個一個char字元匹配      while (--pc >= 0) {          if (ta[to++] != pa[po++]) {              return false;          }      }      return true;  }  // 返回ch字元(ACII碼 )第一次出現的下標 不匹配返回-1  public int indexOf(int ch) {      return indexOf(ch, 0);  }  // 返回字元串在當前字元串中出現的位置 不匹配返回-1  public int indexOf(String str) {      return indexOf(str, 0);  }  public int indexOf(String str) {      return indexOf(str, 0);  }  public int indexOf(String str, int fromIndex) {      return indexOf(value, 0, value.length,              str.value, 0, str.value.length, fromIndex);  }  static int indexOf(char[] source, int sourceOffset, int sourceCount,          char[] target, int targetOffset, int targetCount,          int fromIndex) {      if (fromIndex >= sourceCount) {          return (targetCount == 0 ? sourceCount : -1);      }      if (fromIndex < 0) {          fromIndex = 0;      }      if (targetCount == 0) {          return fromIndex;      }        char first = target[targetOffset];      int max = sourceOffset + (sourceCount - targetCount);  // fromIndex從第幾個開始      for (int i = sourceOffset + fromIndex; i <= max; i++) {          /* Look for first character. */          if (source[i] != first) {  // 先找到第一個匹配的字元              while (++i <= max && source[i] != first);          }            /* Found first character, now look at the rest of v2 */          if (i <= max) {              int j = i + 1;              int end = j + targetCount - 1;  // 開始比較              for (int k = targetOffset + 1; j < end && source[j]                      == target[k]; j++, k++);  //最後一個也相等才會到這              if (j == end) {                  // 返回下標                  return i - sourceOffset;              }          }      }      return -1;  }  // 以什麼結尾其實就是用的startsWith取最後  public boolean endsWith(String suffix) {      return startsWith(suffix, value.length - suffix.value.length);  }  // 這個方法是從字元常量池裡拿String  public native String intern();    String str1 = new String("abba");  String str2 = "abba";  System.out.println(str1 == str2); // false  String str3 = str1.intern();  System.out.println(str2 == str3); // true    // trim() 去除字元串兩邊空格  String str = "  ssad";  str.trim() = "ssad"  // substring 切分字元串從beginIndex開始到endIndex - 1  public String substring(int beginIndex, int endIndex) {      if (beginIndex < 0) {          throw new StringIndexOutOfBoundsException(beginIndex);      }      if (endIndex > value.length) {          throw new StringIndexOutOfBoundsException(endIndex);      }      int subLen = endIndex - beginIndex;      if (subLen < 0) {          throw new StringIndexOutOfBoundsException(subLen);      }      return ((beginIndex == 0) && (endIndex == value.length)) ? this              : new String(value, beginIndex, subLen);  }  // join() 拼接  List<String> list = new ArrayList();  list.add("aa");  list.add("aa");  list.add("aa");  list.add("aa");  list.add("aa");  String.join(",",list);  System.out.println(list); // [aa, aa, aa, aa, aa]    // substring 切分字元串從beginIndex開始到endIndex - 1  public String substring(int beginIndex, int endIndex) {      if (beginIndex < 0) {          throw new StringIndexOutOfBoundsException(beginIndex);      }      if (endIndex > value.length) {          throw new StringIndexOutOfBoundsException(endIndex);      }      int subLen = endIndex - beginIndex;      if (subLen < 0) {          throw new StringIndexOutOfBoundsException(subLen);      }      return ((beginIndex == 0) && (endIndex == value.length)) ? this              : new String(value, beginIndex, subLen);  }  // split() 切分  String str1 = "qw-sdad-dsa";  String[] bs = str1.split("-");  // bs[0] = qw bs[0] = wdad bs[2] = dsa    //replace() 替換  String str1 = "qw-sdad-dsa";  System.out.println(str1.replace("d", "D")); // qw-sDaD-Dsa