- 堆、栈、方法区(静态区、常量池)
String s =“abc”;
s是类类型变量,abc是一个对象,也是一个常量;
一旦初始化就不能改变:String s1=“abc”;s1=“kk”;s1原本指向“abc”对象,后来指向了“kk”对象,但是“abc”对象依然存在;
1.关于字符串对象是否相同的结果-有待深究
package zifuchuan;
/*
- String s = new String(“abc”);【该命令会将"abc"视为一个字符串常量。首先,在常量池中查找是否有该常量:如果没有,就创建;有,就直接引用。假设将常量池中"abc"的内存地址记为0x001。然后,在堆中创建一个对象,对常量池中"abc"的地址进行引用,并有了自己的内存地址假设记为0x0003。那么此时,s的就是对这个堆中0x0003这个地址的引用。
- String s1 = “abc”;【该命令会将"abc"视为一个字符串常量。首先,在常量池中查找是否有该常量:如果没有,就创建;有,就直接引用。由第1步知,已有,所以s1就是对常量池中0x001这个地址的引用。
-
String s1 = “abc”;
String s2 = “ab” + “c”;
String s3 = “ab”;
String s4 = “c”;
String s5 = s3 + s4;
System.out.println(s1 == s2);//结果:true
【s2只不过是对"abc"进行拼接,和s1都是对常量池中"abc"的引用,所以引用的地址相同,s1s2。故结果为true】
System.out.println(s1.equals(s2));//结果:true
【比较内容。故结果为true】
System.out.println(s1 == s5);//结果:false
【两个变量相加相当于在堆中new了一个新对象。故结果为false】
System.out.println(s1.equals(s5));//结果:true
【比较内容。故结果为true】
*/
public class Demo01 {
public static void main(String[] args) {
//1.new新对象
String s1=new String(“abc”);
String s2=new String(“abc”);
System.out.println(s1s2);//2.s3和s4都是指向常量池中的一个abc String s3="abc"; String s4="abc"; System.out.println(s3==s4); //3.s5是堆中对象的引用,s6是常量池中对象的引用 String s5=new String("abc"); String s6="abc"; System.out.println(s5==s6); //System.out.println(s1==s2); //System.out.println(s1.equals(s2)); }
}
2.基本操作
s1.equals(s2);
s1.equalsIgnoreCase(s2);//忽略大小写。是否相等
s1.compareTo(s2);//s1比s2大,则为正数,相等为0,否则为负数;
s1.startsWith(“aa”);
s1.endsWith(‘b’);
s1.subString(1,4);//输从1到3位置上的子串,含头不含尾
s1.subString(2);//从下标为2的位置截取某子串
s1.charAt(2);//输出某一位置上的字符
s1.indexOf(“ab”);//输出字符串的位置
s1.indexOf(‘c’);//输出字符的位置
s1.indexOf(‘z’,2);//从第二个位置开始,找到z第一次出现的位置;
s1.indexOf(“ac”,2);//从第二个位置开始,找到ac第一次出现的位置;
s1.toUpperCase();//转换成大写
s1.toLowerCase();//转换成小写
s1.contains(“aa”);//是否包含
s1.empty();//字符串是否为空
s1.trim();//去掉字符串两端的多个空格;
将字符数组转换成字符串
char[] arr={‘a’,‘b’,‘c’,‘d’,‘e’};
(1)构造函数法
String s=new String(arr);//将字符数组转换成字符串
String s=new String(arr,2,4); //从2位置开始,数4个字符,将字符数组转换成字符串,2是位序,4是个数!!
(2)静态方法
String.copyValueOf(arr));
String.copyValueOf(arr,1,3));//3是个数
//将字符串转换成字符数组
String s1=“lypabc”;
char[] chs=s1.toCharArray();
for(int i=0;i<chs.length;i++)
{
sop(“chs=”+chs[i]);
}
// 将字节数组转换成字符串
byte[] by={‘B’,‘b’,‘c’};
String s4=new String(by);
//将字符串转换成字节数组
byte[] bytes=s1.getBytes();
for(int y=0;y<bytes.length;y++)
{
sop(“bytes=”+bytes[y]);
}
//基本数据类型转换成字符串
String.valueOf(基本数据类型);3+"";Integer.toString(33)
//将字符串转化成整型
Integer.valueOf(str);Integer.parseInt();
//替换
s.replace(“a”,“b”);//用b替换a
//切割
String s=“abc,efg,hij”;
String[] s1=s.split(",");
for循环打印出s1//用“,”切割字符串
3.StringBuffer
(1).概念:是一个容器,字符串缓冲区,可以对其中的数据进行增删改查;长度可变,可装任意类型的数据(除了字节型和短整形),与String的区别是,它初始化后内容可以改变;
StringBuffer sb=new StringBuffer();
StringBuffer sb1=sb.append(“abc”).append(true);//append指的是在尾部添加
System.out.println(sb==sb1);
//结果是:true
sb1.insert(1,3.3);
System.out.println(sb.toString());//toString方法表示转换成字符串
//结果是:a3.3bctrue
(2).删除:delete(1,3)//含头不含尾,删除1、2位置上的字符
deleteCharAt(2);//删除指定位置的字符
替换:sb.replace(start,end,String);//含头不含尾,
setCharAt(2,’ ')//用指定字符替换掉2位置上的数据;
修改:getChars(start,end,目标字符数组,数组的开始位置);
char[] chs=new char[5];
sb.getChars(1, 3, chs, 2);
for(int i=0;i<chs.length;i++)
{
System.out.println(“chs[”+i+"]"+chs[i]);
}
4.StringBuilder类-字符串序列
jdk1.5版本后出现的,与StringBuffer的api兼容,是他的简易替换
区别:StringBuffer是线程同步的(进来后加锁,不允许同时写)
StringBuilder是线程不同步的(效率更高),建议用StrignBuilder;
升级的三个要素:代码简化;效率更高;安全性。