典型回答
这道题比较开放,主要考察面试者的基础和知识面,首先可以尽量列举自己用过的API,并给出应用场景和注意事项(展现自己的知识面),然后再挑一个比较经典的案例详细说明(展现自己的基础)。
- split:字符串分割,例如将一个字符串adbccc,dddd,7778,999按照”,“分隔,就可以使用这个方法;
- replace:字符串替换,将字符串的指定子串全部替换为新的子串
- replaceAll:字符串替换,将符合给定正则表达式的子串全部替换为新的子串
- subString:字符串截取,给定字符串中字符的下标索引,截取[start,end)这个子字符串,这里如果给定的不合适,就可能造成索引溢出错误;
- trim:将字符串两边的空格去掉,为了确保将要处理的字符串两边没有空格,可以用这个API操作;
- conact:字符串连接,前面一篇文分钟详细讲过了
- contains:查看字符串的包含关系,在进行模糊匹配的时候,可以用这个方法判断A字符串中是否包含B字符串;
- indexOf:获取某个字符的下标,给定一个字符,查看该字符在字符串中的位置,如果没有的话返回-1;
- isEmpty:看某个字符串对象是否为空字符串
- startsWith:看某个字符串是否以给定的字符串开头
- endsWith:看某个字符串是否以给定的字符串结尾
- valueOf:将其他类型的数据转换为字符串对象
- toLowerCase:将一个字符串中的字母全部转变成小写
- toUpperCase:将一个字符串中的字母全部转变成大写
我之前遇到一个经典的案例是replace和replaceAll的误用而导致的BUG,当时的案例我记录了下,大概如下面的代码所示:
public class StringSEAPIExample {
public static void main(String[] args) {
String sourceStr = "http://mp.weixin.com/test/xxxxx/123.jpg?xxx=yyy";
String targetReplaceUrl = "TARGET_REPLACE_URL";
String res1 = sourceStr.replaceAll(targetReplaceUrl, targetReplaceUrl);
System.out.println("启用正则的结果:" + res1);
sourceStr = "http://mp.weixin.com/test/xxxxx/123.jpg?xxx=yyy";
targetReplaceUrl = "REPLACE_URL";
String res2 = sourceStr.replace(sourceStr, targetReplaceUrl);
System.out.println("字面匹配的结果:" + res2);
}
}
上面的代码运行的结果如下图所示:
我们期望出现的是第二种效果,也就是正确替换,但是由于对这两个方法的误用,导致了第一行的结果,引发了程序的BUG(非常深刻的教训,所以记忆犹新)。
- replace(String target, String replace)方法中,第一个参数不是正则表达式;
-
replaceAll(String regex, String replace)方法和replaceFirst(String regex, String replace)方法中,第一个参数是正则表达式
知识点梳理
API名称 | 参数 | 应用 |
---|---|---|
构造方法 | 重载版本:默认版本,String,StringBuilder,StringBuffer,char数组,byte数组 | 创建String对象 |
length() | String中字符的个数 | |
charAt() | int索引 | 取得String中该索引位置上的字符 |
getChars() | 要复制部分的起点和终点的索引,复制的目标数组,目标数组的起始索引 | 将当前字符串的指定区间的字符拷贝到目标数组中,在目标数组中的起始位置由dstBegin参数确定 |
toCharArray() | 生成一个char数组,包含该String的所有字符 | |
equals(),equalsIgnoreCase() | 与之比较的String | 比较两个字符串的内容是否相同,如果要忽略大小写则使用第二个 |
compareTo() | 与之比较的String | 按照字典序比较String的内容,比较结果为负数、零或正数。注意,大小写不等价 |
contains() | 要搜索的字符序列 | 如果该字符串包含参数对应的字符内容,则返回true,否则返回false |
contentEquals() | 与之比较的CharSequence或StringBuffer | 如果该String与参数的字符内完全一致则返回true |
startsWith() | 可能的起始String。重载版本在参数中增加了偏移量 | 返回boolean结果,以表明该String是否以此参数开头 |
endsWith() | 可能的后缀String | 表明该String是否以此参数结尾 |
indexOf(),lastIndexOf() | 重载版本包括:char,char与起始索引,String,String与起始索引 | 如果该String并不包含该参数,则返回-1,否则返回参数在String中的起始索引。lastIndexOf()则是返回该参数在该String中的最后一个索引 |
substring() | 重载版本:起始所以,起始索引+终点索引 | 返回参数指定范围内的字符序列,是一个新的String |
conact() | 要连接的String | 返回一个新的String对象 |
replace() | 要替换的字符,用来进行替换的字符 | 会将能匹配的全部都替换掉;如果替换发生,则返回一个新的字符串,否则返回原来的字符串 |
replaceAll() | 正则表达式,用来进行替换的字符 | 替换该字符串中所有满足正则表达式匹配的字符,返回新的对象 |
replaceFirst() | 正则表达式,用来进行替换的字符 | 替换该字符串中第一个满足正则表达式匹配的字符,返回新的对象 |
valueOf() | 重载版本:Object;char[];char[],偏移量,字符个数;boolean;char;int;long;float;double | 返回一个表示参数内容的字符串 |
trim() | 将该String两端的空格删除后,返回一个新的String | |
toLowerCase(),toUpperCase() | 将字符的大小写改变后,返回一个新的String | |
intern() | 将该String对应的字符序列移入字符串常量池,这样改字符序列在JVM里就是唯一一份了 |
参考资料
- https://www.baeldung.com/java-string
- https://stackoverflow.com/questions/10827872/difference-between-string-replace-and-replaceall
- 《Java编程思想》
本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。
020:举几个String的API以及案例