常用Java API之String,StringBuffer,StringBuilder类
文章目录
一, String类
1.1, 创建String对象的方法
//创建一个内容为xiaoming 的字符串
String s1 = "xiaoming";
//创建一个空的字符串
Stinrg s2 = new String();
//创建一个内容为xiaogou的字符串
String s3 = new String("xiaogou");
//创建一个内容为char数组的字符串
Sting s4 = new(char[]{a,b,c})
个别方法的示例代码:
public class StringTest {
static String str = "JAVA 编程 基础";
// lastindexof, indexof
//charAt, length, subString
// toUpperCase, toLowerCase
//equals
public static void main(String[] args) {
///last and indexof(ch x) / indexof(string xxxx)
System.out.println("字符A第一次出现位置"+str.indexOf('A'));
System.out.println("字符A的最后所在位置"+str.lastIndexOf('A'));
//charAt(int index)
System.out.println("给定索引的字符为为"+str.charAt(3));
//length()
System.out.println("字符串长度为: "+str.length());
//substring(int beginIndex)
System.out.println("输出从第一个A字符索引开始到结束的子字符串: "+ str.substring(1));
//substring(beginIndex, endindex)
/// '基'索引为 index=9, 对于substring()要输入到目标索引的下一位
System.out.println("输出从第一个A字符索引位置到基础的础对应索引位置: "+str.substring(1,10));
//toUpperCase() , toLowerCase()
System.out.println("输出小写字符串"+str.toLowerCase());
//equals
}
输出结果:

subString(startindex,endindex), endindex比实际取到的字符所在的索引多了1位!!!
1.2, String类的常用方法
- 注意: length在数组中是arr.length, 而在String类中使用的是 stringA.length() !!!

1.3, ==和.equals() 的比较
'=='用在引用数据类型(比如字符串)中是比较两个字符串在内存中的地址是否相同, 而用在基本数据类型中是比较值是否相等;
equals 用在字符串中是用于比较字符串字面量是否一致;
- Object类中定义的equals方法初始行为是比较对象的内存地址,但是在String,Integer,Date这些类中被重写,用来比较字符串的内容.
示例代码:
public class StrCompare {
public static void main(String[] args) {
// == && .equals()
// ==是字符串比较地址, 而equals是字符串比较内容是否一致
String str1 = "sb";
String str2 = "sb";
String str3 = new String("sb");
String str4 = new String("sb");
System.out.println("str1与str2 地址相同吗 ? --" + (str1 == str2));
System.out.println("str1与str2 内容相同吗? --" + (str1.equals(str2)));
System.out.println("str1与str3 内容相同吗? --" + (str1.equals(str2)));
System.out.println("str1 与str3 地址相同吗? --" + (str1 == str3));
System.out.println("str3 与 str4 地址相同吗? -- " + (str3 == str4));
}
}
执行结果:

- 上面示例在内存中的体现:

插个嘴: compareTo()方法, 用于
比较同一数据类型的数! 返回值为 1(大于), -1(小于) ,0(等于)
compareTo()详细说明
1.4, String类型变量及对象在内存中的体现总结:(待理清思路)
在Java的实现中,new出来的String对象一般是放在堆中的。
如果是 String s =“xxx”; 这种,那就是放在常量池中.JDK6将常量池放在方法区中。方法区此时也是持久代。
但是从JDK7开始,常量池的实现 已经从方法区中移出来放到堆内存里面了。
- 示例图如下:

- 总结如下:
- 来个牛客网的题目:

String类的不可变性:
java规定不能修改字符串中的字符,所以Java里将String类对象称为不可变字符串,例“Hello”永远包含字符H、e、l、l、和o的代码单元序列,不能修改其中的任何一个字符;但是字符串变量是可以修改的,java通过修改String变量的引用位置来修改字符字面量.
- 答案: true, false
- 解答: 为什么 a==MESSAGE为ture, 因为a变量拼接后的值跟MESSAGE的值一致,所以编译器会把
a的引用指向与MESSAGE引用指向一致的地址; 而对于 (b+c)==MESSAGE为false是因为编译器在编译期间无法确定b和c的值,只有在运行时才会确定是什么字符串.
二, String, StringBuilder 和 StringBuffer(着重记忆)
2.1 引子
由于字符串是常量,其内容和长度都是不变的,如果需要对一个字符串进行修改,则只能创建新的字符串. 为了便于对字符串进行修改,JDK中提供了一个StringBuffer类.
- 举个栗子:

2.2 总结 (两个sb的具体使用)(▷)
- String和StringBuffer(或StringBuilder)
- String类表示的字符串是常量,一旦创建后,内容和长度是无法修改的,任何对String的改变都会使得新的String引用地址的改变; Stringbuffer表示子符容器,内容和长度可以随时修改; 在操作字符串时,如果该字符串仅用于表示数据类型,用String类即可. 但是如果需要对字符串中的字符进行增删改操作,则使用StringBuffer类;
- String类重写了Object 的equals方法, 而StringBuffer类没有;
- String类对象可以使用操作符’+'进行拼接,StringBuffer类对象之间不能;
- StringBuffer和StringBuilder的辨析:
StringBuffer和StringBuilder的原理和操作基本相同,
区别在于:
StringBufferd支持并发操作,线性安全的,适合多线程中使用。StringBuilder不支持并发操作,线性不安全不适合多线程中使用。- 新引入的
StringBuilder类虽然很多不如StringBuffer,但其在单线程中的性能比StringBuffer高。
2.3 代码示例
public class StringTest {
public static String BASEINFO = "Mr.Y";
public static final int COUNT = 2000000;
/**
* 执行一项String赋值测试
*/
public static void doStringTest() {
String str = new String(BASEINFO);
long starttime = System.currentTimeMillis();
for (int i = 0; i < COUNT / 100; i++) {
str = str + "miss";
}
long endtime = System.currentTimeMillis();
System.out.println((endtime - starttime)
+ " millis has costed when used String.");
}
/**
* 执行一项StringBuilder赋值测试
*/
public static void doStringBuilderTest() {
StringBuilder sb = new StringBuilder(BASEINFO);
long starttime = System.currentTimeMillis();
for (int i = 0; i < COUNT; i++) {
sb = sb.append("miss");
}
long endtime = System.currentTimeMillis();
System.out.println((endtime - starttime)
+ " millis has costed when used StringBuilder.");
}
/**
* 测试StringBuilder迭代赋值结果
*
* @param mlist
*/
public static void doStringBuilderListTest(List<String> mlist) {
StringBuilder sb = new StringBuilder();
long starttime = System.currentTimeMillis();
for (Iterator<String> iterator = mlist.iterator(); iterator.hasNext();) {
sb.append(iterator.next());
}
long endtime = System.currentTimeMillis();
System.out.println(sb.toString() + "builder cost:"
+ (endtime - starttime) + " millis");
}
public static void main(String[] args) {
doStringTest();
doStringBufferTest();
doStringBuilderTest();
List<String> list = new ArrayList<String>();
list.add(" I ");
list.add(" like ");
list.add(" BeiJing ");
list.add(" tian ");
list.add(" an ");
list.add(" men ");
list.add(" . ");
doStringBufferListTest(list);
doStringBuilderListTest(list);
}
}
执行结果:
2711 millis has costed when used String.
211 millis has costed when used StringBuffer.
141 millis has costed when used StringBuilder.
I like BeiJing tian an men . buffer cost:1 millis
I like BeiJing tian an men . builder cost:0 millis
从上面的结果可以看出,不考虑多线程,采用String对象时(我把Count/100),执行时间比其他两个都要高,而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显。
从后面List的测试结果可以看出,除了对多线程的支持不一样外,这两个类的使用方式和结果几乎没有任何差别,
上面的结果可以看出,不考虑多线程,采用String对象时(我把Count/100),执行时间比其他两个都要高,而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显。由此可见,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;如果要保证线程安全,自然是StringBuffer。
从后面List的测试结果可以看出,除了对多线程的支持不一样外,这两个类的使用方式和结果几乎没有任何差别,
代码摘自: https://blog.csdn.net/mad1989/article/details/26389541




浙公网安备 33010602011771号