String类
概述
- String类由final修饰,没有子类
- 字符串字面值“abc”可以看成是一个字符串对象
- 字符串是常量,一旦被赋值就不能被改变
String str = "aaa"; str ="bbb"; //此时aaa变成了垃圾 //没有问题,str是字符串类型变量,“aaa”和“bbb”是字符串对象。
- String类重写了toString方法,返回的是此对象本身
- nextInt和nextLine连用的小问题
Scanner sc = new Scanner(System.in); int i = sc.nextInt(); String s = sc.nextLine(); System.out.println(i); System.out.println(S);
分析:当输入一个数字和其他内容后,nextInt()方法取得整数值 10,而nextLine()取得的值却一直输出为空。这是因为输入10后Enter键结尾,实际输入内容为“10/r/n”,nextInt()获取值后得剩余输入值为“/r/n”,NextLine()获取之,而不获取其之后的内容。
构造方法
简述
编号 | 方法 | 说明 |
---|---|---|
a | public String() | 空构造 |
b | public String(byte[] bytes) | 把字节数组转成字符串 |
c | public String(byte[] bytes,int index,int length) | 把字节数组自index起的length个字符部分转成字符串 |
d | public String(char[] value) | 把字符数组转成字符串 |
e | public String(char[] value,int index,int count) | 把字符数组自index起的count个字符部分转成字符串 |
f | public String(String) | 把字符串常量转成字符串 |
使用范例
上述构造方法使用的例子(编号对应)如下:
// a
String s1 = new String();
//得到 :s1=""(空字符)
//b
byte[] arr1 = {97,98,99};
String s2 = new String(arr1);
//得到 :s2="abc"
//gbk解码,将计算机读得懂的转换成我们读得懂的
//c
byte[] arr2 = {97,98,99,100,101,102};
String s3 = new String(arr2,2,3);
//得到 :s3="def"
//根据平台默认字符集(gbk)解码,将计算机读得懂的转换成我们读得懂的
//d
char[] arr3= {'a','b','c','d'};
String s4 = new String(arr3);
//得到 :s4="abcd"
//e
char[] arr3= {'a','b','c','d'};
String s5 = new String(arr3,1,2);
//得到 :s5="bc"
//f
String s6 = new String("monaup");
//得到 :s6="monaup"
常见面试题
1.判断定义为String类型的s1和s2是否相等
String s1 = "abc";
String s2 = "abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
答案:true true
分析: 方法区中含常量池,没此创建常量时,现在常量池查找待创建常量,若未找到在其中创建,若找到引用指向该常量。
2.下面这句代码在内存中创建了几个对象
String s1 = new String("abc");
答案:2个,常量池和堆中各一个。
分析:
1.先到常量池看有没有"abc",没有就创建;
2.new方法在堆中创建对象,从常量池中拷贝一份“abc”的副本,再将该对象地址值赋给s1。
3.判断定义为String类型的s1和s2是否相等
String s1 = "a"+"b"+"c";
String s2 = "abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
答案:true true
分析:java中有常量优化机制,在编译时就处理好
4.判断定义为String类型的s1和s2是否相等
String s1 = "ab"+"c";
String s2 = "abc";
s3 = s1+"c";
System.out.println(s3==s2);
System.out.println(s3.equals(s2));
答案:false true
分析:s1和s2在常量池中创建,s3由变量和字符串拼接而成。拼接底层实现包括两步骤:1.StringBuffer对象取到s1变量值“ab”,将之和“c”拼接得到StringBuffer类“abc”;2.用toString方法把StringBuffer对象转为String类,并把地址赋给s3引用。
因此,s3和32不是同一个对象,地址值不同。
5.判断定义为String类型的s1和s2是否相等
String s1 = new String("abc");
String s2 = "abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
答案:false true
分析:s1记录的是堆中的对象,见T2;s2记录的是常量池中的对象。
判断功能
简述
编号 | 方法 | 说明 |
---|---|---|
a | boolean equals(Object obj) | 比较字符串的内容是否相同,区分大小写 |
b | boolean equalsIgnoreCase(String str) | 比较字符串的内容是否相同,不区分大小写 |
c | boolean contains(String str) | 判断大字符串中是否包含小字符串 |
d | boolean startsWith(String str) | 判断字符串是否以某个指定的字符串开头 |
e | boolean endsWith(String str) | 判断字符串是否以某个指定的字符串结尾 |
f | boolean isEmpty() | 判断字符串是否为空public String() |
相关知识补充
null和""(空字符串)
String s1 = "";
String s2 = null;
System.out.println(s1.isEmpty()); //true
System.out.println(s2.isEmpty()); //java.lang.NullPointerException
- ""是字符常量,同时是String类型对象,可以调用String类中的方法。
- null是空常量,不能调用任何方法,否则会出现空指针异常;但null可以任意引用数据类型赋值
小习惯:字符串常量和字符串变量比较时,通常是字符串常量调用方法,将变量作为参数传递,防止空指针异常
获取功能方法
简述
编号 | 方法 | 说明 |
---|---|---|
a | int length() | 获取字符串的长度 |
b | char charAt(int index) | 获取指定索引位置的字符 |
c | int indexOf(int ch) | 返回指定字符在此字符串中第一次出现处的索引,未找到则返回-1 |
d | int indexOf(int ch,int fromIndex) | 返回在指定字符在此字符串中从指定位置后第一次出现处的索引 |
e | int indexOf(String str) | 返回指定字符串在此字符串中第一次出现处的索引 |
f | int indexOf(String str,int fromIndex) | 返回指定字符串在此字符串中从指定位置后第一次出现处的索引 |
g | int lastIndexOf(Type variate,……) | 类似indexOf,从后向前 |
h | String substring(int start) | 从指定位置开始截取字符串,默认到末尾 |
i | String substring(int start,int end) | 从指定位置开始到指定位置结束截取字符串 |
知识细节补充
数组和字符串中的length的区别
数组:int length 是属性,
字符串:int length()是方法,获取字符串中字符的个数
charAt()易出现越界异常
int s2 = s1.charAt(a);
应注意到判断 a>0&&a<s1.length(),否则出现StringIndexOutOfBoundsException。
indexof()接收int类型参数
s1.index('a');
参数接收的是int类型的 ,传递char类型的会自动提升为int类型
原理:gbk码表编码。
- 编码:把我们看得懂的转换成计算机看得懂的
- gbk码表特点:1)2个字节表示一个中文;2)中文的第一个字节肯定是负数
substring()得到新字符串需接收
String s = "mona";
s.substring(2);
System.out.println(s);
结果: mona (原值)
分析:调用substring()方法后,s本身不变,产生一个需要变量记录的新值,如:String newS = s.substring(2)。
字符串的遍历
for (int i = 0; i <= s.length; i++) { //for循环获取到每个字符的索引
System.out.println(s.charAt(i)); //利用索引获取每一个字符
}
转换功能方法
简述
编号 | 方法 | 说明 |
---|---|---|
a | byte[] getBytes() | 把字符串转换为字节数组 |
b | char[] toCharArray() | 把字符串转换为字符数组 |
c | static String valueOf(char[] chs) | 把字符数组转成字符串 |
d | static String valueOf(int i) | 把int类型的数据转成字符串 |
注意 :String类的valueOf方法可以把任意类型的数据转成字符串
仅需了解
String toLowerCase() ---------- 把字符串转成小写
String toUpperCase() ---------- 把字符串转成大写
String concat(String str) ------- 把字符串拼接
使用范例
上述方法使用范例如下:
//a
String s1 = "abc";
byte[] arr = s1.getBytes();
for(int i = 0;i<arr.length;i++){
System.out.println(arr[i]+" ");
} //得到 97 98 99 ,即gbk编码结果
//b
String s2 = "abc";
char[] arr = s2.toCharArray();
for(int i = 0;i<arr.length;i++){
System.out.println(arr[i]+" ");
} //得到 a b c ,即逐个字符
//c
char[] arr={'a','b','c'};
String s2 = String.valueOf(arr); //静态方法,底层是String的构造方法实现的
System.out.println(s2);
其他功能方法
替换
- String replace(char old, char new)
将所有old字符换成new字符,若不存在old字符则不改变
String s1 = "nozuonodie";
String s2 = s1.replace('n', 'f'); //得到结果:fozuofodie
- String replace(String old, String new)
将所有old字符串换成new字符串,若不存在old字符串则不改变
String s1 = "nozuonodie";
String s2 = s1.replace('die', 'high'); //得到结果:nozuonohigh
去空格
- String trim()
将所有空格字符去除
String s1 = "no zuo no die";
String s2 = s1.trim(); //得到结果:nozuonodie
比较
- int compareTo(String str)
返回值大于为正,相同为0,小于为负
根据Unicode编码比较
String s1 = "a";
String s2 = "aaaa";
int num = s1.compareTo(s2);
int compareToIgnoreCase(String str)不区分大小写,其他类似
综合应用小范例
//把第一个字母转成大写,其余为小写
String s1 = "shduwhaBDDBJSDssds";
String s2 = s1.substring(0,1).toUpperCase().
concat(s.substring(1).toLowerCase()) //链式编程
//字符串反转
Scanner sc= new Scanner(System.in);
System.out.println("输入一个字符串:");
String s1 = sc.nextLine(); //1.得到一个字符串
String s2="";
char[] arr = s1.toCharArray(); //2.转化为字符数组
for(int i = arr.length-1; i>=0;i--){ //3.倒叙遍历输出数组
s2 +=arr[i]; //4.拼接为新字符串
}
System.out.println(s2);
//在大串中统计小串出现的次数
String s1="monadededmonadedjimonaireirmona"; //定义大串
String s2 ="mona"; //定义小串
int len = s2.length(); //获得小串的长度
int count = 0; //计数器
while(s1.indexOf(s2)>=0){ //判断大串中是否存在小串
count++; //计数器自增
s1 = s1.substring(s1.indexOf(s2)+len);
//根据获取的索引值加上小串的长度,截取大串,将截取后的结果赋值给大串
//进入新的循环
}
System.out.println(count);
心得:一直跟着一般的java学习大纲结构学下来,直到遇到String。当时感觉String以及StringBuffer这几个类算是工具,缺少思想,心想用到了再查API就行,便跳过学习。越完后看,越发现由于对这几个工具型类不熟悉,大大降低了我的学习进度,时常需要去翻阅长长的方法列表。于是,我回头学习,将常用的方法整理为本文。方便自己在忘记时翻阅温习,也希望朋友们看到也了解一波。
潜心学习,不断接近期盼的生活状态!