String、StringBuffer和StringBuilder的区别:
首先String内部的字符数组是使用final修饰,无法修改,每次修改其实是创建一个新的String对象,为了高效字符串操作,引入了StringBuffer和StringBuilder。但StringBuffer的线程是安全的,适合多线程环境下使用,而StringBuilder速度快,但不安全,适合单线程环境下使用。
封装、继承、多态具体含义:
封装:将对象实现细节隐藏,只允许通过公共的接口与外部交互 (数据的安全性,代码可维护性)
继承:子类继承父类后,可获得父类公有的属性和方法(代码的复用性,扩展性)
多态:子类重写父类的方法,将子类对象赋给父类变量,但运行表现子类行为(代码可维护性,解耦合)
String
最多可以放多少个字符?
使用 char[]来维护字符序列的,而char[]的长度是 int类型,所以理论上 String的长度最大为2^31-1,不过根据实际JVM的堆内存限制,编译时,String长度最多可以是2的16次方减2。
源码分析:
substring(int beginIndex, int endIndex)int length = length();//获取当前字符串的长度
checkBoundsBeginEnd(beginIndex, endIndex, length);//判断传入的参数是否合法
/*if (begin < 0 || begin > end || end > length) {throw new StringIndexOutOfBoundsException("begin " + begin + ", end " + end + ", length " + length);
}*/
int subLen = endIndex - beginIndex;//获取截取字符长度
if (beginIndex == 0 && endIndex == length) {//如果起始点为0并且未位置等于当前字符串长度return this;//返回本字符串
}
//否则根据编码方式新建子字符串
return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen): StringUTF16.newString(value, beginIndex, subLen);
public int indexOf(String str)//查找子串,返回第一个找到的索引位置,没找到返回-1
//首先根据编码方式进行判断if (str.length == 0) {//如果查找子串为空返回0return 0;}
if (length(value) < str.length) {//如果子串长度大于当前字符长度肯定找不到返回-1return -1;}
/*src:要搜索的源字节数组。
srcCount:源字节数组中的有效字节数。
tgt:要查找的目标字节数组。
tgtCount:目标字节数组中的有效字节数。
fromIndex:开始搜索的索引位置(包含)*/public static int indexOfLatin1Unsafe(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) {//确保数据合法assert fromIndex >= 0;assert tgtCount > 0;assert tgtCount <= tgt.length;assert srcCount >= tgtCount;//转换字符char first = (char)(tgt[0] & 0xff);int max = (srcCount - tgtCount);//获取遍历次数,因为次数大于该值后src子字符串长度小于查找字符串所有肯定不成立for (int i = fromIndex; i <= max; i++) {// 找第一个匹配的字符if (getChar(src, i) != first) {while (++i <= max && getChar(src, i) != first);}// 还在范围内进入ifif (i <= max) {int j = i + 1;int end = j + tgtCount - 1;//尾位置//遍历比对字符是否相同for (int k = 1;j < end && getChar(src, j) == (tgt[k] & 0xff);j++, k++);if (j == end) {// 到达末尾说明找到,直接返回return i;}}}return -1;}
public boolean equals(Object anObject) //与其他字符串比较,看内容是否相同
public boolean equals(Object anObject) {//判断是否是同一个对象,是则内容肯定相同if (this == anObject) {return true;}//判断该对象是否是String类if (anObject instanceof String) {//根据字符串判断是否一样String aString = (String)anObject;//根据编码方式进行判断if (coder() == aString.coder()) {return isLatin1() ? StringLatin1.equals(value, aString.value): StringUTF16.equals(value, aString.value);}//上述equals方法内代码//如果长度不一样返回falseif (value.length == other.length) {//一个个比较是否相同for (int i = 0; i < value.length; i++) {//不同返回falseif (value[i] != other[i]) {return false;}}return true;}return false;}//不是字符串返回falsereturn false;}
public int compareTo(String anotherString) //比较字符串大小
//获取两个字符串长度int len1 = value.length;int len2 = other.length;return compareTo(value, other, len1, len2);public static int compareTo(byte[] value, byte[] other, int len1, int len2) {//获取最短数组长度int lim = Math.min(len1, len2);//遍历for (int k = 0; k < lim; k++) {//不相等即可退出if (value[k] != other[k]) {return getChar(value, k) - getChar(other, k);}}//返回长度差 0——相等 负数——本字符串小于比较的字符串 正数——本字符串大于比较的字符串return len1 - len2;}
public String concat(String str) //字符串连接,返回当前字符串和参数字符串合并结果
//如果拼接的字符为空,直接退出if (str.isEmpty()) {return this;}//编码格式一样if (coder() == str.coder()) {//将两个字符串转数组byte[] val = this.value;byte[] oval = str.value;//求拼接后长度和int len = val.length + oval.length;//将第一数组copy进去byte[] buf = Arrays.copyOf(val, len);//将第二个数组copy进去System.arraycopy(oval, 0, buf, val.length, oval.length);//通过数组返回新的字符串return new String(buf, coder);}
谢谢观看!