[Java][华为云Java编程创造营][学习笔记][第三阶段][07_Java常用类][01_字符串类分析和使用]
【摘要】 1,字符串类的分析和使用 1.1,String分析String类的底层使用char的数组保存数据。String类是一个final类,不允许被继承。String类是一个不可变类,该类的对象生成后,内容不会发生改变。String类中的所有返回String类型对象的成员方法都是返回一个新的String对象。 1.2,String比较String类重写了equals方法,用来比较两个字符串的内容是...
1,字符串类的分析和使用
1.1,String分析
- String类的底层使用char的数组保存数据。
- String类是一个final类,不允许被继承。
- String类是一个不可变类,该类的对象生成后,内容不会发生改变。
- String类中的所有返回String类型对象的成员方法都是返回一个新的String对象。
1.2,String比较
- String类重写了equals方法,用来比较两个字符串的内容是否相同。
- String类的equals方法和==做区分,==比较的是两个字符串对象的地址。
public class Test
{
public static void main(String[] args)
{
String s1 = new String("123");
String s2 = new String("123");
System.out.println(s1 == s2);//false
System.out.println(s1.equals(s2));//true
}
}
- String类重写了equals方法,从底层代码分析:
public class Test
{
public boolean equals(Object anObject)
{
if (this == anObject)
{
return true;
}
if (anObject instanceof String)
{
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length)
{
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0)
{
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
}
- 首先调用==判断两个对象的地址是否相同,如果相同即是同一个对象,内容必定相同则返回true。
- 如果地址不相同则先判断传入的对象是否是String类的实例,如果不是直接返回false,如果是String类的实例则判断两个字符串的长度是否相等,不相等返回false,如果长度相等的话就挨个比较两个字符串的字符数组,如果有一个不相同的话就返回false,都相同的话返回true。
1.3,字符串类实例化机制
- Java中String类型的创建有以下两种方式:
-
创建的时候,JVM会现在字符串常量池中去查找是否存在该字符串,如果存在直接返回该字符串对象的地址,否则会在常量池中创建该字符串对象并返回地址。
-
创建的时候,也会先查找常量池中是否存在该字符串,如果存在就会在堆里面复制一份这个字符串对象,然后把堆里面的对象地址返回给变量;不存在的话就会在堆中和常量池中各创建一个对象,并返回堆中对象的地址。
-
//第一种方式
String s1 = "hello world";
//第二种方式
String s2 = new String("hello world");
//只在常量池中创建了一个对象,创建了1个对象
String s1 = "123";
//在常量池和堆中各创建了一个对象,创建了2个对象
String s2 = new String("456");
1.4,字符串的维护和参数传递
- String类的+和concat都可以将2个字符串拼接到一块,形成新的字符串。
- String的+还可以将字符串和非字符串连接在一起,成为新的字符串,concat不可以与非字符串拼接在一起。
public class Test
{
public static void main(String[] args)
{
String s1 = "123";
System.out.println(s1 + 123);
//System.out.println(s1.concat(123));//错误
}
}
- String的参数传递
public class Test
{
public static void test(String str)
{
str = "world";
}
public static void main(String[] args)
{
String str1 = new String("hello");
test(str1);
System.out.println(str1);//hello
}
}
- 引用str1指向新对象new String(“hello”)。
- test()刚刚开始调用时,形参str复制了实参str1的值,这个值也就是对象new String(“hello”)的地址,所以这时候引用str和引用str1指向同一个对象"hello"。
- 进入到test()方法内部,world这个对象被分配给形参str,而这个操作对象实参str1并没有影响,所以这个时候引用str指向"world",而引用str1仍然指向原来的对象"hello"。
- test()方法结束后,形参str从栈内存中消失,它指向的对象"world"由于没有其他引用指向它,也可以被gc回收了。打印引用str1指向的对象,即"hello"。
1.5,字符串的常用API方法
-
String类的常用方法:
- equals方法,用来比较两个字符串内容是否相同。
- charAt方法,返回指定索引处的字符。
- contains方法,判断字符串中是否包含另一个字符串。
- indexOf方法,返回第一次出现某个字符串的位置。
- isEmpty方法,判断字符串是否是空字符串。
- split方法,将字符串分割,返回一个字符串数组。
- trim方法,返回去掉字符串开头和结尾的空格后的字符串。
- toCharArray方法,将字符串转换为字符数组。
- replace方法,替换原字符串中的某个字符或子字符串,全部替换。
- length方法,返回字符串长度。
-
String类的常用方法案例:
public class Test
{
public static void main(String[] args)
{
String string = " hello world!!";
System.out.println(string.charAt(1));//h
System.out.println(string.contains("he"));//true
System.out.println(string.indexOf("e"));//2
System.out.println(string.isEmpty());//false
System.out.println(string.split(" ")[0]);//去空格
System.out.println(string.trim());//hello world!!
System.out.println(string.toCharArray()[1]);//返回字符数组 h
System.out.println(string.replace("!", "?"));// hello world??
System.out.println(string.length());//14
System.out.println(string.lastIndexOf("!"));//13
}
}
1.6,StringBuffer类
- StringBuffer又称为可变字符序列,它是一个类似于String的字符串缓冲区,可以改变该序列的长度和内容。
- StringBuffer是同步安全的。
public class Test
{
public static void main(String[] args)
{
//public StringBuffer():无参构造方法
StringBuffer sb = new StringBuffer();
System.out.println("sb:" + sb);//sb:
System.out.println("sb.capacity:" + sb.capacity());//sb.capacity:16
System.out.println("sb.length:" + sb.length());//sb.length:0
//public StringBuffer(int capacity):指定容量的字符串缓冲区对象
StringBuffer sb2 = new StringBuffer(50);
System.out.println("sb:" + sb2);//sb:
System.out.println("sb.capacity:" + sb2.capacity());//sb.capacity:50
System.out.println("sb.length:" + sb2.length());//sb.length:0
//public StringBuffer(String str):指定字符串内容的字符串缓冲区对象
StringBuffer sb3 = new StringBuffer("hello");
System.out.println("sb:" + sb3);//sb:hello
System.out.println("sb.capacity:" + sb3.capacity());//sb.capacity:21
System.out.println("sb.length:" + sb3.length());//sb.length:5
}
}
1.7,StringBuilder类
- StringBuilder类也是字符串缓冲区,非同步安全。
public class Test
{
public static void main(String[] args)
{
String str = new String("abc");
StringBuilder stringBuilder = new StringBuilder(str);
System.out.println("使用带参的构造方法生成的字符串缓冲区:" + stringBuilder);
//输出结果:使用带参的构造方法生成的字符串缓冲区:abc
//空参构造方法
StringBuilder builder = new StringBuilder();
System.out.println("空参构造的字符串缓冲区:" + builder);
String s1 = builder.toString();
StringBuilder builder2 = new StringBuilder();
System.out.println("空参构造的字符串缓冲区:" + builder2);
String s2 = builder2.toString();
//equals()
boolean result1 = builder.equals(builder2);
System.out.println(result1);//false
boolean result2 = s1.equals(s2);
System.out.println(result2);//true
}
}
- String、StringBuffer、StringBuilder的区别:
- String是内容不可变的。
- StringBuffer、StringBuilder都是内容可变的。
- StringBuffer是同步的,数据安全,效率低。
- StringBuilder是不同步的,数据不安全,效率高。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)