javaAPI02——String和StringBuilder

目录

1.String
String是不可变的对象
String常量池
String内存编码和长度
方法:indexof、substring、trim、chatAt、startswith和endswith

String是不可变对象

java.lang.String使用final修饰,不能被继承。
字符串底层封装字符数组及针对字符数组的操作算法。
字符串一旦创建,对象永远无法改变,但是字符串引用可以重新赋值。
java字符串在内存采用Unicode编码方式,任何一个字符对应两个字节的定长编码。

String常量池

字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能。
JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。

  1. 为字符串开辟一个字符串常量池,类似于缓存区。
  2. 创建字符串常量时,首先坚持字符串常量池是否存在该字符串。
  3. 存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中。

实现的基础:

  1. 实现该优化的基础是因为字符串是不可变的,可以不用担心数据冲突进行共享。
  2. 运行时实例创建的全局字符串常量池中有一个表,总是为池中每个唯一的字符串对象维护一个引用,这就意味着它们一直引用着字符串常量池中的对象,所以,在常量池中的这些字符串不会被垃圾收集器回收java为了提高性能,静态字符串(字面量、常量、常量连接的结果)在常量池中创建,并尽量使用同一个对象,重用静态字符串。

**字符串常量池则存在于方法区。**静态区,跟堆一样,被所有的线程共享。方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
在这里插入图片描述字符串对象内部用字符数组进行存储的。

String m = "hello,world";
String n = "hello,world";
String u = new String(m);
String v = new String("hello,world");

操作过程:
会分配一个11长度的char数组,并在常量池分配一个由这个char数组组成的字符串,然后由m去引用这个字符串;用n去引用常量池里边的字符串,所以和n引用的是同一个对象;生成一个新的字符串,但内部的字符数组引用着m内部的字符数组;同样会生成一个新的字符串,但内部的字符数组引用常量池里边的字符串内部的字符数组,意思是和u是同样的字符数组。
结果:
m和n是同一个对象
m,u,v都是不同的对象
m,u,v,n但都使用了同样的字符数组,并且用equal判断的话也会返回true

内存编码及长度

String在内存中采用的是Unicode编码,每个字符占用两个字节;任何一个字符(无论中英文)都算1个字符长度,占用两个字节。

public void testlength(){
	String s ="hello";
	System.out.println(s.length());
}

indexOf

实现在字符串里检索另一个字符串
在这里插入图片描述

public void testindexOf(){
	String s ="I can because I think I can ";
	int i = s.indexOf("bec");
	System.out.println(i);
	int i2= s.indexOf("can");
	System.out.println(i2);
}

substring获得子串

在这里插入图片描述

public void test1(){
	String s ="I can because I think I can ";
	String ss = str.substring(11,14);	
	System.out.println(ss);
}

trim

trim方法去掉字符串前后的空字符

public void test2(){
	String s ="I can because I think I can ";
	String ss = str.trim();	
	System.out.println(ss);
}

chatAt

chatAt方法用来返回字符串制定位置的字符,参数index用来制定位置。

public void test1(){
	String s ="I can because I think I can ";
	for(int i =0;i<s.length();i++){
		char c = s.charAt(i);
		System.out.println(c);
	}
}

startsWith和endsWith

//检测一个字符串是不是以制定字符串为开头或结尾
public void test1(){
	String s ="I can because I think I can ";
	System.out.println(s.endsWith("cn"));
	System.out.println(s.statsWith("I"));
}

StringBuilder

SBtringuilder封装可变得字符串,对象创建后可以通过调用改变其封装的字符序列。返回值都是StringBuilder类型(方法的返回语句都是return this)。
在这里插入图片描述
append和insert方法

//测试StringBuilder的append方法
public void test4(){
	StringBuilder buf =new StringBulider("programming language");
	buf.append("java").append("php").append("R")
	System.out.println(buf.toString());
	buf.insert(4,"python");
	System.out.println(buf);
}

StringBuilder是可变字符串。在需要进行字符串的内容时候用StringBuilder进行实现会有更好的性能。
对比:
StringBuffer是线程安全的,同步处理的,性能稍慢;StringBuilder是非线程安全的,并发处理的,性能稍快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值