一.字符串类
1.1 Java字符串简介
在java中,字符串被作为String类型的对象来处理。Strin类位于java.lang包中,默认情况下,该包被自动导入所有的程序中。
创建String对象有三种方法:
第一种:创建一个字符串对象imooc,名为s1
String s1 = "imooc";
第二种:创建一个空字符串对象,名为s2
String s2 = new String();
第三种:创建一个字符串对象imooc,名为s3
String s3 = new String("imooc");
1.2 Java中字符串的不变性
String对象创建后则不能被修改,是不可变的,这里楼主要说明的是,所谓的不能的修改实质上指的是对象本身不可被修改,而不是引用不可被修改。如:
String s="hello",这个意思是声明一个String类型的引用变量叫做s.在内存中创建一个String对象(值为"hello"),然后再把这个String对象的引用赋值给变量s;
然后再s="world";
这句话的执行效果就是在内存中另外创建了一个String对象(值为"world"),然后把这个新的对象的引用赋值给变量s,而不是把原来的内存中的那个"hello"的String对象的值变为了hello(这点特别注意),如果之后内存中的那个"hello"的String对象没有任何引用,那么就会被下一次垃圾回收器运行时回收。
所以这里的String对象不可修改指的是创建的String对象本身不能被修改,而可以被"修改"实质上是创建了新的对象,但所指向的内存空间不同。
下面再以一个例子来说明下:
//例1:
<span style="font-size:24px;">public class HelloWorld {
public static void main(String[] args) {
String s1 = "疯狂java";
String s2 = "疯狂java";
String s3 = new String("疯狂java");
String s4 = new String("疯狂java");
//多次出现的字符常量,Java中编译程序只创建一个,所以返回true
System.out.println(s1==s2);
//s1和s3是不同的对象,所以返回false
System.out.println(s1==s3);
//s3和s4是不同的对象,所以返回false
System.out.println(s3==s4);
s1 = "人森苦短," + s1;
//字符串s1被修改,指向新的内存空间
System.out.println(s1);
}
}</span>
注意:
1.通过String s1="疯狂java";声明了一个字符串对象,s1存放到了字符串对象的引用,在内存中的存放引用关系是:
s1指向处于堆内存中的"疯狂java"这个字符串对象;
然后通过s1="人森苦短,"+s1;改变了字符串s1,其实质是创建了新的字符串对象,变量s1指向了新创建的字符串对象;
2.一旦一个字符串在内存中创建,则这个字符串将不可改变。如果需要一个可以改变的字符串,我们可以使用StringBuffer或者StringBuilder;
3.每次使用new来创建字符串对象时,就是产生一个新的对象,即便两个字符串的内容相同,使用"=="比较时也为false,如果只需要比较内容是否相同,应该使用"equals()"方法来判断字符串是否相同;
下面再举一个例子来加强对字符串应用的理解:
//例2
<span style="font-size:24px;">public class HelloWorld {
public static void main(String[] args) {
String s1 = "imooc";
String s2 = "imooc";
//定义字符串s3,保存“I love”和s1拼接后的内容
String s3 = "I love" + s1;
// 比较字符串s1和s2
// imooc为常量字符串,多次出现时会被编译器优化,只创建一个对象
System.out.println("s1和s2内存地址相同吗?" + (s1 == s2));
//比较字符串s1和s3
System.out.println("s1和s3内存地址相同吗?"+(s1==s3));
String s4 = "I love" + s1;
//比较字符串s4和s3
// s1是变量,s4在运行时才知道具体值,所以s3和s4是不同的对象
System.out.println("s3和s4内存地址相同吗?" + (s4 == s3));
}
}</span>
在这里,可能兄弟们也发现了一个问题,例子1中的s1,s2和例子2中的s3,s4同样都是字符串直接赋值创建的,为什么结果不一样?(例1中s1==s2为true;例2中s3==s4为false)
这里主要是因为:
例2中
String s3 = "I love" + s1;
这两个之所以不同,是因为s1在上面是以变量方式创建的,java在编译时会创建多个,所以指向不同,两个不一样,会返回false;
string s1 = "peng"
string s2 = "peng"
这里面是用字符常量做的,多次出现的字符常量,java编译只创建一个,所以返回true
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
//定义一个字符串"人森苦短疯狂java"
String str = "人森 苦短 疯狂 java";
//打印出字符串长度
System.out.println("字符串长度:" + str.length());
//查找字符'短'的位置
char c = '短';
System.out.println("字符'短'的位置:" + str.indexOf(c));
//查询子字符串'imooc'的位置,如果找不到就返回-1
System.out.println("子字符串'疯狂'的位置:" + str.indexOf("疯狂"));
//按空格把字符串拆分成一个数组,并输出数组元素
String[] arr = str.split(" ");
System.out.println("按空格拆分成数组:"+Arrays.toString(arr));
System.out.println();
//获取索引位置[3,7)之间的子串
System.out.println("获取位置[3,7)之间的子串:"+str.substring(3,7));
}
}
字符'短'的位置:4
子字符串'疯狂'的位置:6
按空格拆分成数组:[人森, 苦短, 疯狂, java]
获取位置[3,7)之间的子串:苦短 疯
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
String fileName = "HelloWorld.java"; //java文件名
String email = "laurenyang@imooc.com"; //邮箱
//判断.java文件名是否正确:合法的文件名应该以.java结尾
int index = fileName.lastIndexOf("."); //获取文件名中"."的位置
//获取文件的后缀
String prefix = fileName.substring(index+1,fileName.length());
//判断必须包含"."号,且不能出现在首位,同时后缀名为"java"
if(index!=-1 && index!=0 && prefix.equals("java")){
System.out.println("java文件名正确");
} else{
System.out.println("java文件名无效");
}
//判断邮箱格式是否正确:合法的邮箱名中至少要包含"@",并检查"@"是否在"."之前
int index2 = email.indexOf('@'); //获得邮箱中'@'符号的位置
int index3 = email.indexOf('.'); //获得邮箱中'.'的位置
//判断必须包含'@'符号,"@"是否在"."之前
if(index2!=-1 &&index3>index2){
System.out.println("邮箱格式正确");
}else{
System.out.println("邮箱格式无效");
}
}
}
运行结果为:
邮箱格式正确
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
//定义一个字符串"疯狂java"
String str = "疯狂java";
//将字符串转换为小写
System.out.println("转换为小写:"+str.toLowerCase());
//获取索引位置为1的字符
System.out.println("获取索引为1位置的字符:"+str.charAt(1));
//将字符串转换为byte[],并打印输出
byte[] b = str.getBytes();
System.out.println("转换为字节数组: ");
for(int i=0;i<b.length;i++){
System.out.print(b[i]+" ");
}
System.out.println();
//和另外一个字符串"疯狂java"进行比较
String str2 = new String("疯狂java");
System.out.println("str和str2的内存地址相同?"+(str==str2));
System.out.println("str和str2的内容相同?"+str.equals(str2));
}
}
获取索引为1位置的字符:狂
转换为字节数组:
-73 -24 -65 -15 106 97 118 97
str和str2的内存地址相同?false
str和str2的内容相同?true
功能:统计指定字符串中字符'w'出现的次数
例六:
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
//定义一个字符串
String s="qwhehdukhaisehoiwhiehsafuihwqefgadsbfasahkh";
int num = 0; //出现次数
for(int i=0;i<s.length();i++) //循环遍历每个字符
{
if(s.charAt(i)=='w'){//依次获取每个字符,判断是否是字符2
num++; //累计统计次数
}
}
System.out.println("w出现的次数为:"+num);
}
}
运行结果为: