字符串(String)
一、是什么?
百度百科:
字符串主要用于编程,概念说明、函数解释、用法详述见正文,这里补充一点:字符串在存储上类似字符数组,所以它每一位的单个元素都是可以提取的,如s=“abcdefghij”,则s[1]=“b”,s[9]=“j”,而字符串的零位正是它的长度,如s[0]=10,这可以给我们提供很多方便,如高精度运算时每一位都可以转化为数字存入数组。
常用场景:
通常以串的整体作为操作对象,如:在串中查找某个子串、求取一个子串、在串的某个位置上插入一个子串以及删除一个子串等。两个字符串相等的充要条件是:长度相等,并且各个对应位置上的字符都相等。设p、q是两个串,求q在p中首次出现的位置的运算叫做模式匹配。串的两种最基本的存储方式是顺序存储方式和链接存储方式。
二、怎么用?
1、创建字符串
来看看他的构造方法:
char[] byt = {'1','2','3','4'};
String str1 = new String("123");
String str2 = "sdfdsf";
String str3 = new String(byt);
jdk底层实现:
注意:final修饰
2、字符串使用
1.字符串长度
length()方法
public static void main(String[] args) {
char[] byt = {'1','2','3','4'};
String str1 = new String(byt);
// System.out.println( str1 instanceof String);
System.out.println(length(str1));
}
public static int length(String str){
return str.length();
}
底层实现:
结果:
2.连接字符串
语法:
string1.concat(string2);
方法一:
public static void concat(){
String str1 = "abc";
String str2 = "def";
System.out.println(str1.concat(str2));
}
方法二:
public static void concat(){
String str1 = "abc";
String str2 = "def";
System.out.println(str+str2);
}
结果:
jdk实现:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oboqUbiv-1605945249804)(…/…/…/…/…/AppData/Roaming/Typora/typora-user-images/image-20201121134520124.png)]
3.比较字符串
语法:
str1.equals(str2);
public static void equals(){
String str1="Twinkle Twinkle little star, ";//创建字符串1
String str2="How I wonder what you are";//创建字符串2
boolean b=str1.equals(str2);//比较两个字符串,相同输出true,否则输出false
System.out.println(b);//输出字符串
}
结果
jdk实现:
字符串比较说明:equalls()和“==”的区别
由代码可知,string类里对比较字符串进行了重写,equals()的底层实现其实也是应用“==“的,只是将字符串中的每个字符拿出来进行比较罢了。
而如果其它对象比较,或自己创建的对象要进行比较,则也需要重写equals()方法,不然就是比较双方的地址,而非其中的属性值比较了。
3.查找是否包含某个字符串
str1.contains(str2);
public static void contain()
{
String str1 = "afdasfsadfaaa";
String str2 = "afdf";
String str3 = "aa";
System.out.println(str1.contains(str2));
System.out.println(str1.contains(str3));
}
结果:
jdk实现:
最终实现的代码:
/* @param source the characters being searched.
* @param sourceOffset offset of the source string.
* @param sourceCount count of the source string.
* @param target the characters being searched for.
* @param targetOffset offset of the target string.
* @param targetCount count of the target string.
* @param fromIndex the index to begin searching from.
*/
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
//如果查询下表大于等于字符串长度
//如果查询条件长度==0就是""返回字符串长度等同于length()
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
//没有查询坐标就是0
if (fromIndex < 0) {
fromIndex = 0;
}
//如果没有查询条件返回下标
if (targetCount == 0) {
return fromIndex;
}
//字符数组 总是返回第一个
char first = target[targetOffset];
//int max = 0 +(总长度-查询条件的长度)查询的最大位偏移量
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
//判断查询条件条件在不在source中以便循环,找到第一个相等字符的位置,不相等就一直加,注意边界
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
//再次判断下边界,如果大于边界就可以直接返回-1了
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) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}
思路:
##这个方法首先会查找子字符串的头字符在此字符串中第一次出现的位置,再以此位置的下一个位置开始,然后将子字符串的字符依次和此字符串中字符进行比较,如果全部相等,则返回这个头字符在此字符串中的位置;如果有不相等的,则继续在剩下的字符串中查找,继续进行上面的过程,直到查找到子字符串或没有找到返回-1为止。
#感兴趣的同学可以自己实现以下这个功能,顺便说下String里的一个思想,比如replace方法我们知道是将当前字符串中的某个字符替换成另一个字符,String里都会先遍历以下当前字符串,看看是否有需要改变的,如果没有就直接返回,如果需要改变,就把需要改变的第一个字符前的数据完全拷贝到新字符中(因为前面的都不需要替换),接下来的数据拷贝的时候进行判断是否替换,再拷贝。也是一个比较好的思想。
补充:如果主串中包含子串,且包含多次,返回包含次数
/**
s1:source
s2:target
*/
static int count(String s1,String s2)
{
int c=0;
int index=-1;
while((index=s1.indexOf(s2,index))>-1)//indexOf查找一个字符或字符串的第一次出现
{
index+=s2.length;
c++;
}
return c;
}
3.替换字符串
语法:
str.replace("xx","yy");//将str中所有xx替换为yy
public String replace(char searchChar, char newChar);//字符替换
public String replaceAll(String regex, String replacement);//正则替换
public static void replace(){
String str = new String("Runoob");
System.out.print("返回值 :" );
System.out.println(str.replace('o', 'T'));
System.out.print("返回值 :" );
System.out.println(str.replace('u', 'D'));
String str1 = new String("www.google.com");
System.out.print("匹配成功返回值 :" );
System.out.println(str1.replaceAll("(.*)google(.*)", "runoob" ));
System.out.print("匹配失败返回值 :" );
System.out.println(str1.replaceAll("(.*)taobao(.*)", "runoob" ));
}
结果:
4.返回特定索引的字符
语法:
str.charAt(index);//index为int类型的数字指定字符串类指定索引的字符
public static void charAt(){
String str1 = "大家好是渣渣辉";
char c = str1.charAt(3);
System.out.println(c);
}
结果:
jdk源码:
5.截取字符串
语法:
public String substring(int beginIndex);
public String substring(int beginIndex, int endIndex);
public static void subString(){
String Str = new String("www.runoob.com");
System.out.print("返回值 :" );
System.out.println(Str.substring(4) );
System.out.print("返回值 :" );
System.out.println(Str.substring(4, 10) );
}
结果:
6.切割字符串(常用)
语法:
public String[] split(String regex, int limit);//regex分隔字符,limit分割几次
public String[] split(String regex);
public static void splip(){
String str = new String("Welcome-to-Runoob");
System.out.println("- 分隔符返回值 :" );
for (String retval: str.split("-")){
System.out.println(retval);
}
System.out.println("-------------------");
System.out.println("- 分隔符设置分割份数返回值 :" );
for (String retval: str.split("-", 2)){
System.out.println(retval);
}
System.out.println("---------------");
String str2 = new String("www.runoob.com");
System.out.println("转义字符返回值 :" );
for (String retval: str2.split("\\.", 3)){
System.out.println(retval);
}
System.out.println("-------------------");
String str3 = new String("acount=? and uu =? or n=?");
System.out.println("多个分隔符返回值 :" );
for (String retval: str3.split("and|or")){
System.out.println(retval);
}
}
结果:
7.判断字符串是否为空
语法:
public boolean isEmpty();
public static void isEmpty(){
String myStr1 = "Runoob";
String myStr2 = ""; // 空字符串
String myStr3 = " "; // 多个空格,length() 不为 0
System.out.println("myStr1 是否为空:" + myStr1.isEmpty());
System.out.println("myStr2 是否为空:" + myStr2.isEmpty());
System.out.println("myStr3 长度:" + myStr3.length());
System.out.println("myStr3 是否为空:" + myStr3.isEmpty());
}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1IbrqA4X-1605945249846)(…/…/…/…/…/AppData/Roaming/Typora/typora-user-images/image-20201121150708857.png)]
-------------------------------无情分割线---------------------
就写这些方法了,其它读者可去查阅API或者去看String的源码,也可参看一些文档如菜鸟营地
三、总结
以上只是粗略的讲解了字符串的使用,字符串的操作在项目中经常面到,小川后面还会再度进阶,去深究一些字符串的操作。
注:参考资料: