String:最终类,不能被继承
“helloworld”–注意:所有的字符串,都是string的对象
字符串底层是由字符数组创建的。private final共同修饰,创建后不能改变(地址值和元素都不能改变)。
所有的常量都存储在方法区运行的常量池
Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。
1)所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。
2)而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。
StringBuiler是线程不安全,效率高
StringBuffer是线程安全,效率低
public class StringDemo {
public static void main(String[] args) {
//s1对象指向常量池
String s1="ab";
//s2的对象指向堆内存
,所以两个对象的地址值不同
String s2=new String("ab");
//s3指向常量池,后续创建的字符串和之前的一致,常量池就不创建新的
String s3="ab";
//如果参与的是常量,Java会在编译时期 进行优化然后先计算结果然后赋值
String s4="a"+"b";
String s5="a";
s5=s5+"b";
//String 底层是由StringBuilder来完成拼接,toString()创建新的字符串对象进行返回
s5=new StringBuilder("a").append("b").toString();
// s1指向常量池,s5指向堆内存
/*
* + 和StringBuilder拼接对比
* 空间::
* 1.+拼接
* String[] str={...};//100个字符串
* Strig s="";
* for(int i=0;i<str.length;i++{
* s+=str[i];//new StringBuilder(s).append(str[i]).toString();
*一次创建了3个对象
* }
* 一共创建了301个对象
//2.StringBuilder
* StringBuilder sb=new StringBuilder();
* for(int i=0;i<str.length;i++){
* sb.append(str[i]);//一次创建一个对象
* }
* String s1=sb.toString();//一个对象
* 一共创建102个对象
* 结论StringBuilder 在空间上由于+号添加
*/
// s5=s5+"b";
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s1==s4);
System.out.println(s1==s5);
System.out.println(s2==s5);
System.out.println(s5);
// System.out.println(s6==s1);
}
}
-----------------------------------------------------
````java
public class StringDemo2 {
public static void main(String[] args) {
//从1970年1月1日0点0分0秒到现在的毫秒值
long start= System.currentTimeMillis();
//1.+
/* String str="";
for (int i=1;i<100000;i++){
str+="a";
}*/
//2.stringbulider
StringBuilder sb=new StringBuilder();
for(int i=1;i<10000000;i++){
sb.append("a");
}
String s=sb.toString();
long end =System.currentTimeMillis();
System.out.println(end-start);
}//结论 时间上StringBulider优于+添加
}
重要方法:charAt(int index)返回指定索引对应数组元素的值
length()返回字符数组的长度
toCharArray字符串转成字符数组 例如:char[]cs=s.toCharArray()
Arrays.sort(cs);//排序
Arrays.toAtring(cs)//输出
//字符数组变成字符串
String str=new String(cs)
System.out.println(str)
//有开始下标的
String str=new String(cs,起始位置,
个数)
Arrays.copyOf(c,index//缩小到第几个是数字);
s.compareTo©两个字符数组比差值,如果差值一直为0,直到其中一个字符数组长度比较完成,然后 把长度相减
s.concat(string s)在字符串后面进行拼接,不改变s的值
s.contains(CharSequence s)原串包不包含子串,包含返回true,不包含返回false
s.endwith(String suffix)判断以什么为结尾
s.startsWith(String suffix)判断以什么为开始
应用:求一个字符串各个元素出现的次数
//判断 各元素出现的次数
public static void CounterLetter(String s){
//转成字符数组
char []cs=s.toCharArray();
//用boolean数组表示每个元素的计数状态
boolean[] b=new boolean[cs.length];
//初始化true 表示未计数,false表示已经计数
for (int i = 0; i < b.length; i++) {
b[i]=true;
}
//遍历字符数组
for (int i = 0; i < cs.length; i++) {
//判断是否计数
if(b[i]){
//没有计数
int count=1;
//转字符
char c=s.charAt(i);
//
for(int j=i+1;j<cs.length;j++){
//判断后面的元素是否相等
if(c==cs[j]){
count ++;
b[j]=false;
}
}
//输出
System.out.println(c+":"+count);
}
}
String–字符对象的创建(+用于字符串的拼接,通过StringBuilder底层可变数组操作
数组复制,最后再把新字符数组转成字符串
Instanceof–左边区域代表的是要去比对的对象,右边可以是对象的父类,本类,子类用于判断这个对象是由右边的类创建的
equals()–先比较地址值,不相等再比较字符串对应位置是否相等
equalsIgnoreCase() 忽略大小写
**getBytes()**使用字符串转成一个字节数组 如果指定了码表就按指定码表把字符串转成字符数组 ,如果没有指定就按系统平台码来进行转换
new String(byte[]bs,int offset,int count,Charset charset))–如果有指定码表就按码表把字节数组转成字符串,没有没有就按系统平台默认
编码–把文字转换成数字的过程。文字转换成数字的规则–码表
ISO8889-1(西欧码表 1个字节)—>GB2312、Big5–>GBK(国标码 2个字节)–>
Unicode编码体系(utf-8(3个字节 Java文件存储是按utf-8来编码)、utf-16(2个字节)(Java文件加载到内存是utf-16))
所有的完整码表默认兼容西欧码表
Char c=‘a’ 用GBK,占用1个内存,占用3个磁盘内存,加载到2个字节内存
public class StringDemo2 {
public static void main(String[] args) throws UnsupportedEncodingException {
String s="为所欲为";
//字符串转成字节数组
//没有指定系统平台码---GBK
//byte[] bs=s.getBytes();
//指定编码
byte[] bs=s.getBytes("utf-8");
//System.out.println(bs.length);
//按照指定编码把字节数组转成字符串
//String str=new String(bs,"utf-8");
String str=new String(bs,0,5,"utf-8");
System.out.println(str);
}
}
hashCode()返回字符串码表 和字符串的内容有关,和地址无关
indexOf()输入一个字符串返回开始下标的索引(默认第一次找到的索引)或者入字符串和从哪开始的下标
isEmpty()判断是否为空
substring()截取子串,但不改变原串的内容,截取的子串,左包又不包
trim()把前后空格删除
valueOf()把参数变成字符串输出