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