String不是8种基本数据类型,是一个对象,默认值为null。
一、创建方式
ps:前天一个面试官问我,new一个String的话创建了几个对象,我说一个,所以面试挂了。
String str1 = new String("hello");
String str2 = "hello";
首先来画一个图来看一下:
在堆内存中存放的是具体的值,在栈中存放的是引用。如上图所示,String str1 = new String("hello");,首先会在堆内存中申请一块内存存储hello字符串,str1引用指向这个字符串,然后若在常量池中没有hello这个字符串,则将hello加入到常量池中,若在常量池中有这个字符串,则不再加入,所以这时str1创建了可能创建了一个对象,也可能创建了两个对象。String str2 = "hello";,若在常量池中有hello字符串,则不再创建对象,若没有,则将字符串加入到常量池中,str2引用指向常量池,所以这时str2可能创建了一个对象,可能没有创建。
实例练习:
ps:以下这个实例是转载网上,感谢
1.创建了几个对象:
String temp="apple";
for(int i=0;i<1000;i++)
{
temp=temp+i;
}
答案:1001个
2.创建了几个对象:
String temp=new String("orange")
for(int i=0;i<1000;i++)
{
temp=temp+i;
}for(int i=0;i<1000;i++)
{
temp=temp+i;
}
答案:1002个
※创建字符串的两种方式:
字符串直接量:如“welcome to hello world”,将字符串直接量看成是String对象
String str = new String("welcome to hello world");或者String str = "welcome to hello world";
字符数组:
char[] ch = {'H','e','l','l','o'};String str = new String(ch);
上面的str称作是String变量,String变量里面存的是String对象的引用。上面的“welcome to hello world”称作是String对象,String对象里面存的才是真正的字符串的值。String类是不可变的,是指:String对象是不能改变的,即它的内容是不能改变的。而String变量的值是可以改变的,即变量的值(地址)是可以改变的,地址改变了之后,就访问不到原先指向的String对象了,例:
String string = "haha";这时string变量里面存的是String对象“haha”的引用(即指向String对象的地址),string = "world";这时string变量里面存的是String对象“world”的引用,原先的String对象“haha”仍然存在于堆内存中,只是现在访问不到了。
二、==和equals的区别
1、==:既可以用于基本数据类型,也可以用于类对象类型。==用于比较值(地址)
变量(栈)内存中存放的对象(堆)内存的首地址。
对于两种情况来说,都是比较值,只是基本类型的变量中存的是常量值,而引用类型的变量(栈)内存中存放的是它所对应的对象(堆)内存中的首地址。
1.1、基本数据类型中:用于比较两个变量的值是否相等。
例:int i = 10;
int j = 10;
if(i == j)
return true;
else
return false;
答案:true
1.2、用于类对象类型中:用于比较两个对象变量的引用是否相同,即是否指向同一块栈内存块。
前面讲过:像String这样的对象,在创建时会申请栈内存和堆内存,在栈内存中存储的是变量引用,==就是用于判断两个对象变量是否指向同一块栈内存,若是,则说明它们的对象变量是相等的。
“==就是用于比较两个变量所对应的内存中的值是否相同”,“变量所对应的内存”,对于引用变量来说,它所对应的内存应该就是栈内存,它所对应的内存的值就是对象(堆)内存中的首地址。
例:String str1 = new String("hello");
String str2 = new String("hello");
if(str1 == str2)
return true;
else
return false;
答案:false //str1和str2分别指向不同的堆内存地址
例1:String str1 = "hello";
String str2 = "hello";
if(str1 == str2)
return true;
else
return false;
答案:true
例2:String str1 = "hello";
String str2 = "world";
if(str1 == str2)
return true;
else
return false;
if(str1 == str2)
return true;
else
return false;
if(str1 == str2)
return true;
else
return false;
if(str1 == str2)
return true;
else
return false;
答案:false
2、equals:不能用于基本数据类型,只能用于类对象类型,用于基本类型的话要用它们的包装类。比较对象内容是否相等,不是变量值(地址)。
我曾经犯过的一个错误:
char ch = 'A';
if(ch.equals('A'))
//其他代码
搞不搞笑,我当时还纳闷咋没有equals这个方法,⊙﹏⊙b汗
例1:String str1 = new String("hello");
String str2 = new String("hello");
if(str1.equals(str2))
return true;
else
return false;
答案:true
例2:String str = new String("hello");
if("hello".equals(str))
return true;
else
return false;
答案:true
噔噔噔,请看下面这种情况:
a: String str1 = "hello1";
int i = 1;
String str2 = "hello"+i;
if(str1 == str2)
return true;
else
return false;
答案:false //因为常量池是在编译器就能确定的,而i 变量导致str2不确定,所以返回false
b:String str1 = "hello1";
final int i = 1;
String str2 = "hello"+i;
if(str1 == str2)
return true;
else
return false;
答案:true
c:String str1 = "hellow";
String i = "w";
String str2 = "hello"+i;
if(str1.equals(str2))
return true;
else
return false;
答案:true
d:String str1 = "hellow";
String i = "w";
String str2 = "hello"+i;
if(str1.equals(str2))
return true;
else
return false;
答案:false
e:String str1 = "hello1";
String str2 = new String("hello1");
if(str1==str2)
return true;
else
return false;
答案:falsef:String str1 = "hello1";
String str2 = new String();
str2 = "hello1";
if(str1==str2)
return true;
else
return false;
答案:true
三、String常用方法
1、length()
String str = "hello";
str.length();//5
2.chatAt(int i):截取一个字符
String str = "hello";
char c = str.charAt(1);//c = e
3.indexOf(char c)/indexOf(String str):字符或者子串第一次出现的下标
String str = "hello";
str.indexOf('l');//2
str.indexOf("ll");//2
4.lastIndexOf(char c)/lastIndexOf(String str):最后一次
String str = "hello";
str.lastIndexOf('l');//3
str.lastIndexOf("ll");//2
5.subString(int startIndex)/subString(int startIndex,int endStart):截取子字符串
String str = "hello";
str.subString(2);//llo
str.subString(2,4);//ll
//说明:subString(int startIndex,int endIndex)是个左闭右开区间
6.concat():连接两个字符串
String str = "hello";
String str2 = "world";
str.concat(str2);//helloworld
连接更多字符串用+
7.replace(char oldCh,char newCh)/replace(CharSequence oldChSe,CharSequence newChSe):字符替换或者字符序列替换
String str = "hello";
str.replace('h','w');//wello
String str1 = "world";
str1.replace("wo","tt");//ttold
8.replaceAll(String oldStr,String newStr):用一个新字串替换这个字符串中所有和它匹配的子串
replaceFirst(String oldStr,String newStr):用一个新字符串替换这个字符串中第一个和它匹配的子串
String str = "hello";
str.replaceAll(str,"haha");//haha
str.replaceAll("l","haha");//hehahao
str.replaceFirst("l","haha");//hehalo
9.trim():去掉字符串开头和末尾的空格
String str = " hello ";
str,trim();//hello
10.valueOf():基本类型转换为字符串,该方法是一个静态方法
只列举一种:char转换为String
char[] ch = {'a','b'};
String.valueOf(ch);//ab
※使用上面这种方式可以讲基本数据类型转化为字符串
※字符串转换为基本类型:
String str = "hello";
Double.parseDouble(str)//这是错误的
应该是:
String str = "4.1";
Double.parseDouble(str);
//结果为:4.1
还有:Integer.parseInt(str);
字符的话就是转换成字符数组:toCharArray();
11.toLowerCase():转换为小写
String str = "HELLO";
str.toLowerCase();//hello
toUpperCase():转换为大写
String str = "hello";
str.toUpperCase();//HELLO
12.startsWith():是否以指定字符或子字符串开头
endsWith():是否以特定字符或子字符串结尾
String str = "hello";
str.startWith("he");//true
str.endWith('p');//false
13.split():将字符串以特定分隔符分割后返回数组
String str = "hello,world,haha";
String[] strings = str.split(",");//注意这里是双引号,即字符串
for(int i = 0;i<strings.length;i++){
System.out.print(strings[i] + " ");
}
//hello world haha
14.toCharArray():将字符串转换为字符数组
String str = "hello";
char[] ch = str.toCharArray();
15.compareTo():比较两字符串(比较的是对象内容),若相等则返回0,若不相等,则返回它们的差值
String str1 = "hello";
String str2 = new String("hello");
str1.compareTo(str2);//返回0
String str1 = "hello";
String str2 = "world";
str1.compareTo(str2);//返回-15,它们的差值
str2.cpmpareTo(str1);//返回15
16.matches():类似于equals,但是比equals功能更强大,可以遵从某种规则,如正则表达式:
String str = "welcome to hello world";
str.matches("welcome.*") //.*表示匹配任意多个字符
上面讲到的replaceAll也可以使用正则表达式:
String str = "hello##$"
str.replaceAll("[#$]","www");//[]代表模式替换,[#$]表示能匹配#和$的模式
//结果为:hellowwwwww
记得牛客网上刷到一个编程题:将字符串中空格用%20代替,当时费了九牛二虎之力写了一个很复杂的实现算法,在网上查到一个人写的比我的还复杂,这个问题完全可以用上面这个方法来解决嘛:
String str = "welcome to hello world ";
str.replaceAll("[ ]","%20");
//结果为:welcome%20to%20hello%20world
//在IDE中已测
17.regionMatches():精确匹配,返回值为boolean