字符串是一个特殊的对象
字符串一旦初始化就可以不改变,但可以共享
字符串常量是不可修改的,改变的只是String类对象的引用,并且这种改变将有可能带来大量的垃圾空间
实例化字符串对象
//直接赋值
String a1="abc";
//使用构造函数创建对象
String a2=new String("abc");
String类两种实例化对象的区别:
- 直接赋值:只会产生一个实例化对象,
- 构造函数:会产生两个实例化对象,并且不会自动入池(常量池),无法实现对象的重用,但是可以利用intern()方法手工入池处理
字符串的比较
//"abc"会存储在字符床常量池中,如果没有则创建,如果有则引用
String s="abc";
String s1="abc"; //在常量池中创建对象(可共享)
s==s1; //true
String s2=new String("abc");//在堆内存中创建对象,开辟新的内存空间(不可共享)
s==s2;//false
s.equales(s2); //true
String中使用“==”与“equales”比较的区别?
- “==”:进行的是数值的比较,如果用于对象比较的是两个内存的地址值是否相等
- “equales()”:类所提供的比较方法,可以直接进行字符串内容的判断
String内存分析
String对象(常量)池:
常量池的目的是实现数据的共享处理。以String对象池为例,里面的内容主要是为了重用,而重用实际就是属于共享设计,在Java中对象池可以分为两种:
- 静态常量池:程序在加载的时候会自动将此程序中保存的字符串,普通的常量,类和方法的信息等等全部进行分配
- 运行时常量池:当一个程序加载之后,里面可能有一些变量,这个时候提供的常量池就是运行时常量池
String a1="www.baidu.com";
String a2="www."+"baidu"+".com"; //运行加载之后 a2="www.baidu.com"
a1==a2; //true
/**
在这个程序中给出的内容全部都是静态常量数据(字符串的常量都是匿名对象),
所以最终在程序加载的时候会自动帮助开发者处理好相应的连接
**/
Sting a1="baidu";
String a2="www.baidu.com"; //静态常量池
String a3="www."+a1+".com"; //存放在了运行时常量池
a2==a3; //false
/**
程序在加载是并不确定a1是什么内容,因为在连接字符串时a1是一个变量,
变量的内容会被修改,所以最终结果是不确定的
**/
对字符串进行功能分类
- 获取
package java8;
public class StringDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
String a="abcadefgabcddefag";
//获取字符串长度
int length=a.length();
System.out.println("length="+length);
//根据位置获取字符
char ch=a.charAt(3);
System.out.println("ch="+ch);
//根据字符获取在字符串中第一次出现的位置
int index1=a.indexOf(97);
int index2=a.indexOf("a");
//指定位置由前向后查找字符串出现的位置
int index3=a.indexOf(100,3);
int index4=a.indexOf("d",3);
System.out.println("indexOf="+index1+","+index2+","+index3+","+index4);
//根据字符获取在字符串中最后一次出现的位置
int last1=a.lastIndexOf(97);
int last2=a.lastIndexOf("a");
//指定位置由后向前查找字符串出现的位置
int last3=a.lastIndexOf(97, 7);
int last4=a.lastIndexOf("a", 7);
System.out.println("last="+last1+","+last2+","+last3+","+last4);
//获取字符串中的一部分字符串,又叫做字串
String sub1=a.substring(4);
String sub2=a.substring(4, 10);
System.out.println("sub1="+sub1+",sub2="+sub2);
CharSequence sub3=a.subSequence(4, 10);
System.out.println("sub3="+sub3);
}
}
/**
length=17
ch=a
indexOf=0,0,4,4
last=15,15,3,3
sub1=defgabcddefag,sub2=defgab
sub3=defgab
**/
- 转换
//将字符串变成字符串数组
String str="张三,李四,王二";
String arr[]=str.split(",");
System.out.println("arr:"+Arrays.toString(arr));
String str1="absSfWmndG";
//将字符串变成字符数组
char arr1[]=str1.toCharArray();
System.out.println("arr1:"+Arrays.toString(arr1));
//将字符串变成字节数组
byte[] arr2=str1.getBytes();
System.out.println("arr2:"+Arrays.toString(arr2));
//将字符串中的字母转成大小写
String s1=str1.toUpperCase();
String s2=str1.toLowerCase();
System.out.println("s1="+s1);
System.out.println("s2="+s2);
//将字符串中的内容进行替换
String newS=str.replace(",", "-");
System.out.println("news="+newS);
//将字符串两端空格去除
String str2=" www.baidu.com ";
System.out.println("str2="+str2);
System.out.println("str2.trim="+str2.trim());
//将字符串进行连接
System.out.println(str.concat(str2));
// 将基本数据类型转为字符串
System.out.println(String.valueOf(100));
/**
arr:[张三, 李四, 王二]
arr1:[a, b, s, S, f, W, m, n, d, G]
arr2:[97, 98, 115, 83, 102, 87, 109, 110, 100, 71]
s1=ABSSFWMNDG
s2=abssfwmndg
news=张三-李四-王二
str2= www.baidu.com
str2.trim=www.baidu.com
张三,李四,王二 www.baidu.com
100
**/
- 判断
String s1="Abc";
String s2="abc";
//比较字符串是否相同
boolean bool1= "abc".equals(s1);
//忽略大写比较字符串内容
boolean bool2=s1.equalsIgnoreCase(s2);
System.out.println("bool1="+bool1);
System.out.println("bool2="+bool2);
//判断字符串是否包含指定字符串
String s3="adnkabcdijid";
boolean bool3=s3.contains(s2);
System.out.println("bool3="+bool3);
//字符串是否以指定字符串开头
System.out.println("startsWith:"+s3.startsWith("ad"));
//字符串是否以指定字符串结尾
System.out.println("endsWith:"+s3.endsWith("sd"));
/**
bool1=false
bool2=true
bool3=true
startsWith:true
endsWith:false
**/
- 比较
String s1="asd";
String s2="rty";
//比较两个字符串大小(按ASCII码表)
int com= s1.compareTo(s2);
System.out.println("com:"+com); //com:-17
/**
* 比较结果有三种:
* 相等==>返回0
* 大于==>返回正数
* 小于==>返回负数
*/
String a1="abc";
String a2=new String("abc");
a2.intern(); //引用a1中字符串常量池中的内容
System.out.println(a1==a2); //true