String

一、字符串常量池
字符串常量池的存放位置
jdk6.0 字符串常量池是在方法区中
jdk7.0 从方法区中移除,字符串常量池存放到堆空间中
jdk8.0及之后 虚拟机规范中声明了元空间,字符串常量池存放到元空间中备注:元空间是指本地内存除了为jvm开辟空间之外的额外本地内存
字符串常量池的概念
字符串常量池是java一项技术,从字面意思理解就是把经常用的数据存放到某一个内存当中,本质意义是避免频繁的数据创建于销毁,实现数据共享,提供系统性能。
public class Test{
public static void main(String[] args){
String a = “123”;
String b = “123”;
System.out.println(a==b);
}
}
//输出结果 true
上面代码,在内存中是干了什么?

因为a和b指向同一个对象,所以ab是true,那么看下述代码执行结果:
public class Test{
public static void main(String[] args){
String a = new String(“123”);
String b = “123”;
System.out.println(a
b);
}
}
//输出结果 false
执行结果是false,内存中又干了啥?

当我们用new 关键字创建字符串对象时,会先在堆中开辟内存空间,然后,在该内存中存放我们在字符串常量池中的数据地址
二、字符串拼接
public class Test{
public static void main(String[] args){
String a = “123”;
String b = “456”;
String c = “123456”;
String d = a+b;
System.out.println(c==d);
}
}

字符串+字符串(拼接)底层是靠StringBuilder的append和toString方法实现。
toString方法源码如下:

可以看到new ,所以输出false,但是如下代码又是什么结果呢?
public class Test{
public static void main(String[] args){
String a = “123”+“456”;
String c = “123456”;
System.out.println(ac);
}
}
//输出true
之所以为true,是因为jvm编译阶段编译器优化后把字符串常量直接合并成“123456”
三、子串
String类的substring()从一个字符串中提取一个子串:
public class Test{
public static void main(String[] args){
String a = “Hello World!”;
String b = a.substring(0,7);
System.out.println(b);
}
}
//输出 Hello W
备注:substring方法第二参数不写,截取到结尾
四、空串和Null串
空串是一个对象,有自己串长度(0)和内容(空),可以用以下代码来检测:
public class Test{
public static void main(String[] args){
String a = “”;
if(a.length()0 || a.equals(“”))
System.out.println(“是空串”);
}
}
String变量还可以存放一个特殊值,名为null,即Null串
五、
和equals的区别
基本数据类型,也原始数据类型: 他们之间比较,应用双等号(
),比较是他们的值
引用数据类型 当他们用()进行比较时,比较的是他们的内存中的存放地址,所以,除非是同一个new出来的对象,他们比较的结果是true,否则就是false。Object类中定义一个equals方法,该方法是比较的内存地址,但是有些子类覆盖了该方法,目的是提高字符串等值比较的场景,提高实际使用价值,比如String等equals方法:
首先比较地址,如果地址相同,就返回true
如果字符串地址不相同,name首先会判断要比较的参数类型是否是String,如果是,再比较两者的长度,如果长度相同,再对位比较每一个字符值是否相同,如果相同,则返回true
六、String常见的一些方法(api)
获取String的长度length()String a = “12345577”;int len = a.length();System.out.println(len);
用charAt()获取String中的指定索引位置的代码单元(值|字符)String a = “12345577”;char res = a.charAt(2);System.out.println(res);
用codePointAt()获取指定索引位置的代码点(编号)String a = “abcsd”;
int rescode= a.codePointAt(0);
System.out.println(rescode);
equals()判断字符串是否相等
substring()截取子串
contains()判断是否包含目标串String a = “abcsd”;
boolean isCont = a.contains(“sdqcy”);
System.out.println(isCont);
indexOf()获取目标串第一次出现位置的索引值String a = “abcsd”;
int index= a.indexOf(“sd”);
System.out.println(index);
endsWith()判断是否是指定字符串结尾String a = “abcsd”;
boolean index = a.endsWith(“a”);
System.out.println(index);
startsWith()判断是否是指定字符串开头String a = “abcsd”;
boolean index = a.startsWith(“a”);
System.out.println(index);
使用concat()做字符串连接String a = “abcsd”;
String b = “sdfds”;
String index = a.concat(b);
System.out.println(index);
toLowerCase()返回一个新的字符串,新字符串是把所有大写字母变成小写String a = “SFSsdfdsFDd”;
String index = a.toLowerCase();
System.out.println(index);
toUpperCase()返回一个新的字符串,新字符串是把所有小写字母变成大写String a = “SFSsdfdsFDd”;
String index = a.toUpperCase();
System.out.println(index);
split()按照指定分隔符,拆分字符串成字符串数组String a = “SFSsdfdsdFDd”;
String[] index = a.split(“sd”);
System.out.print(“[”);
for(int i=0;i<index.length;i++) {
if(i
index.length-1) {
System.out.print(index[i]);
}else {
System.out.print(index[i]+“,”);
}
}
System.out.print(“]”);
trim()返回一个新字符串,该字符串是删除原始字符串开头和结尾的空格String a = " SFSsdfdsdFDd ";
String res = a.trim();
System.out.print(res);
七、可变字符串
使用场景StringBuffer 线程安全 适合多线程 慢StringBuilder 线程不安全 适合单线程 快
StringBuffer与StringBuilder 的方法一致,以StringBuilder 为例,列出一些常用方法(api)package com.qcby.test1;

public class StringDemo {
public static void main(String[] args) {
StringBuilder a = new StringBuilder(“12345678”);
//添加
//追加
//a.append(“qcby”);
//System.out.println(a);

	//指定位置插入
	//a.insert(1,"qcby");
	//System.out.println(a);
	
	//删除
	//指定范围删除
	//a.delete(1, 4);
	//System.out.println(a);
	
	//指定位置删除
	//a.deleteCharAt(0);
	//System.out.println(a);
	
	
	//修改
	//指定位置修改
	//a.setCharAt(0, 'r');
	//System.out.println(a);
	
	
	//反转
	//a.reverse();
	//System.out.println(a);
	
	//查
	//System.out.println(a.charAt(0))	
	
}

}

测试下StringBuilder与String,在字符串拼接方面的性能,代码如下:package com.qcby.test1;

public class StringDemo {
public static void main(String[] args) {
String str =“”;
long start = System.currentTimeMillis();
for(int i=0;i<100000;i++) {
str+=“第”+i+“元素”;
}
long end = System.currentTimeMillis();
System.out.println(“String需要的时间是”+(end-start)+“ms”);

	StringBuilder str1 = new StringBuilder("");
	long start1  = System.currentTimeMillis();
	for(int i=0;i<100000;i++) {
		str1.append("第"+i+"元素");
	}
	long end1 = System.currentTimeMillis();
	System.out.println("StringBuilder需要的时间是"+(end1-start1)+"ms");
}

}
执行结果如下:
总结: 如果不频繁修改字符串时,建议使用String
如果在单线程下,需要频繁修改字符串时,建议使用StringBuilder
如果在多线程下,需要频繁修改字符串时,建议使用StringBuffer

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值