String类的作用、用法、各种语法、注意事项、应用
11.4 String类
11.4.1 String
- 字符串是常量。创建之后不可改变;
- 字符串字面值存储在字符串池中,可以共享;
- String s = “Hello”; //产生一个对象,字符串池中存储;
- String s = new String(“Hello”); //产生两个对象,堆、池各存储一个;(Hello首次出现)
public class TestBasicString {
public static void main(String[] args) {
//System.out.println("abc");//常量
String s1 = "abc";//变量s1 = 常量“abc”
String s2 = "abc";//以上两行代码创建了一个“abc”对象,保存在常量池中
String s3 = new String("abc");//此行代码创建了以恶“abc”对象,保存在堆中
System.out.println(s1 == s2);
System.out.println(s1 == s3);
String s4 = new String("def");//先在常量池中创建一个“def”对象,再在堆中创建String对象
String s5 = "def";//变量s1 = 常量池中的常量“def”
String s6 = "def";//以上两行代码直接使用s4在常量池中创建的一个“def”
}
}
运行结果:
true
false
11.4.2 常用方法
- public char charAt(int index); //根据下标获取字符;
- public boolean contains(String str); //判断当前字符串是否包含str;
- public char[] toCharArray(); //将字符串转换成数组;
- public int indexOf(String str); //查找str首次出现的下标,存在则返回下标,不存在,则返回-1;
- public int lastIndexOf(String str); //查找字符串在当前字符串中最后一次出现的下标索引;
- public int length(); //返回字符串的长度;
- public String trim(); //去掉字符串前后的空格;
- public String toUpperCase(); //将小写转成大写;
- public boolean endWith(String str); //判断字符串是否以str结尾;
- public String replace(char oldChar , char newChar); //将旧字符串替换成新的字符串;
- public String[] split(String str); //根据str做拆分;
import java.util.Scanner;//快速导包:Ctrl + 1
public class TestStringMethods {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s = "HelloWorld";
System.out.println( s.charAt(5) );//获取对应下标的字符
System.out.println(s.contains("llo"));//判断是否包含该字符序列
char[] chs = s.toCharArray();//将字符串转换成数组
System.out.println(s.indexOf("o"));//返回s首次出现字符序列的下标
//简单的邮箱验证
String email = "[email protected]";
int elementA = email.indexOf("@");//@的下标
int elementB = email.indexOf(".");//.的下标
if(elementA != -1 && elementB != -1) {
if(elementA < elementB) {
System.out.println("邮箱名正确");
}
}
System.out.println(s.lastIndexOf("o"));//返回s最后一次出现字符序列的下标
System.out.println(s.length());//返回字符串长度
//HelloWorld GoodBye
String hi = "HelloWorld GoodBye";
int firstindex = hi.indexOf("o",hi.indexOf("0")+1);//查第二个o出现的位置
System.out.println(firstindex);
String str = "aa";
System.err.println(str.isEmpty());//判断字符串是否为空串:""
String str2 = " Hello ";
System.out.println(str2.trim());//去掉字符串前后的空格
String upperHi = hi.toUpperCase();
System.out.println(s.toUpperCase());//将小写转换为大写
String lowerHi = hi.toLowerCase();
System.out.println(s.toLowerCase());//小写转大写
System.out.println(upperHi.equals(lowerHi));//内容必须完全相同,包括大小写
System.out.println(upperHi.equalsIgnoreCase(lowerHi));//忽略大小写
String fileName = "TestString.java";
System.out.println(fileName.endsWith(".java"));//判断是否以该字符序列结尾
System.out.println(fileName.startsWith("Test"));//判断是否以该字符序列开头
String str3 = "HelloHelloHelloWorld";
String str4 = str3.replace("o", "0");//将str3中的前者替换为后者
System.out.println(str3.replace("Hello", "Bye"));
String text = "宝剑锋从磨砺出,梅花香自苦寒来";
String[] texts = text.split(",");//以该字符序列为分割依据进行分割
for(int i = 0 ; i < texts.length ; i++) {
System.out.println(texts[i]);
}
String subStr = text.substring(8,10);//将前下标前的舍弃,从后下标开始舍弃
System.out.println(subStr);//截一段
}
}
输出结果:
W
true
false
4
邮箱名正确
6
10
4
Hello
HELLOWORLD
helloworld
false
true
true
true
ByeByeByeWorld
宝剑锋从磨砺出,梅花香自苦寒来
梅花
11.4.3 可变字符串
- StringBuffer:可变长字符串,JDK1.0提供,运行效率慢、线程安全;
- StringBuilder:可变长字符串,JDK5.0提供,运行效率快,线程不安全;
public class TestStringBuilder {
public static void main(String[] args) {
String str = "Hello";//不变的、不能扩容、加长
StringBuilder sBuilder = new StringBuilder();//内存中创建了一个对象(Hello),可变的可扩容的,可加的
for(int i = 0 ; i <= 100 ; i++) {
sBuilder.append(i);//在原有空间中进行追加,容量不够,则扩容
}
str = sBuilder.toString();
System.out.println(str);
}
}
public class TestStringBuilder2 {
public static void main(String[] args) {
String str = "World";
for(int i = 0 ; i <= 100;i++) {
str += i;//JDk的实现方式是什么?会产生中间变量?
//编译之后,自动创建StringBuilder对象、初始化、调用append方法进行追加、调用toString方法转换成字符串,并赋值给str
//JDK内部进行了优化,没有产生中间变量
}
}
}
public class TestString4 {
public static void main(String[] args) {
String s1 = "abc";//直接声明,保存在池中
String s2 = s1 + "def";//自动优化,abcdef,StringBuilder.toString()得到一个new String(xxx,xxx,xxx)堆
//s2.intern();//只要首次出现即可,手工的在程序运行时,将s2加入到池中
String s3 = "abcdef";//直接声明,保存在池中
System.out.println(s2 == s3);
System.out.println(s2);
System.out.println(s3);
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
}
}
输出结果:
false
abcdef
abcdef
-1424385949
-1424385949
public class TestString5 {
public static void main(String[] args) {
String s1 = "abc";//直接声明,保存在池中,首次出现
String s2 = s1 + "def";
//s2.intern();
String s3 = "abcdef";//直接声明,首次出现,保存在池中
s2.intern();//手工向池中保存s2指向的字符串失败了
System.out.println(s2 == s3);//比较s2指向堆中的“abcdef” s3所指向的池中的“abcdef”
System.out.println(s2);
System.out.println(s3);
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
String s4 = s2.intern();//如果池中有s2所指向的“abcdef”的话,则返回池中的内容一样的常量的地址
String s5 = s2;//赋值的是堆中的地址,没有形成复用
System.out.println(s3 == s4);
System.out.println(s3 == s5);
}
}
输出结果:
false
abcdef
abcdef
-1424385949
-1424385949
true
false