内部存储结构

 以主流的 JDK 版本 1.8 来说,String 内部实际存储结构为 char 数组。

private final char value[];

常用的几个构造方法

1.String 为参数

public String(String original) {
   this.value = original.value;
   this.hash = original.hash;
}

2.char[]、byte[] 为参数

public String(char value[]) {
   this.value = Arrays.copyOf(value, value.length);
}
public String(byte bytes[]) {
   this(bytes, 0, bytes.length);
}

3.StringBuffer 为参数

public String(StringBuffer buffer) {
   synchronized(buffer) {
      this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
   }
}

4.StringBuilder 为参数

public String(StringBuilder builder) {
   this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

String类用于比较的方法

1.equals()方法
源码:

public boolean equals(Object anObject) {
   if (this == anObject) {
      return true;
   }
   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;
}

比较过程:
A.先通过 instanceof 判断是否为 String 类型;
B.当判断参数为 String 类型之后,会循环对比两个字符串中的每一个字符,当所有字符都相等时返回 true,否则则返回 false。

2.compareTo()方法
源码:

    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }  

比较过程:
A.循环比较所有的字符,如果存在不相同的字符,则返回两个字符的差值。

3.equals()和compareTo()的区别
A.参数不同;equals()的参数是Object 类型的,而compareTo()的参数只能是String类型的。
B.返回值不同:equals()的返回值是boolean类型的,compareTo()的返回值是int类型的;也就是说,如果两个String相等,那么equals返回true,compareTo()返回0。

其他常用的方法

A.转大小写:toUpperCase() 、 toLowerCase()
B.判断是否包含:contains()
C.查询长度:length()
D.替换字符:replace()
E.去字符串首尾空格:trim()

一些经典的面试问题

1.== 和 equals 的区别
先谈“==”:
== 对于基本数据类型来说,是用于比较 “值”是否相等的;而对于引用类型来说,是用于比较引用地址是否相同的。
再看equals()方法:

public boolean equals(Object obj) {
        return (this == obj);
    }

如果不重写equals方法的话,默认使用Object类的方法,可以从源码中看出,此时,equals相等于==。

2.String 和 StringBuilder、StringBuffer 的区别
A.String是不可变类,在进行字符串拼接的时候,回影响性能;
B.StringBuffer类提供了append、insert等字符串拼接相关的方法,但是它是线程安全的,性能也不高;
C.StringBuilder同样提供了append、insert等字符串拼接相关的方法,但是线程不安全,性能高。

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

一个喜欢拔刀的萌新Coder